Willow and the Storm

Jun 4, 2010 at 6:07 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
I don't know what an xls file does and I probably wont find out in time since I am going to sleep but uh, 32 bits is the size of a standard register, a DWORD, which takes you to 2.14 billion I think?
while 8 bits is a byte and 255 and of course you could turn a DWORD variable into four byte variables if you needed more variables and less space.
Uh but you probably know all that stuff already though and since I dont' even know what you're doing I'll just stop talking now.

32? >.>
 
Jun 4, 2010 at 7:27 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6210
Age: 38
I think that you should use V to identify a variable in all cases.

For instance <VAR0000:0120<YNJV000 could be the same as <YNJ0120, which would allow the system to be very flexable.

Though you would still need a command to store the variable to the flag data (when saving data), and another to retrieve the flag data and store it to a variable (when loading data).

BINXXXX:YYYY:VZZZ - Store var z into range x:y.
BVRXXXX:YYYY:ZZZZ - Load data from range x:y and store in z.
 
Jun 5, 2010 at 1:32 AM
Cold Agony of Resolute Vacuum
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jan 1, 2008
Location: Elsewhere
Posts: 1973
andwhyisit said:
I think that you should use V to identify a variable in all cases.

For instance <VAR0000:0120<YNJV000 could be the same as <YNJ0120, which would allow the system to be very flexable.

Though you would still need a command to store the variable to the flag data (when saving data), and another to retrieve the flag data and store it to a variable (when loading data).

BINXXXX:YYYY:VZZZ - Store var z into range x:y.
BVRXXXX:YYYY:ZZZZ - Load data from range x:y and store in z.

Indeed.
'Course this is all theory at the moment, anyways.

On a much more related topic: I think sometime within the next week or two I *might* have a non-plot demo to demonstrate the various systems being implimented.

Won't have the Mimiga Mask character thing, but the alchemy, item tracking and 4 of the Wizards spells should be working.

:D

(This demo might not happen, but if it does it will be implimenting a standard version of the CS engine, not the epic-hacked one that Lace is funkin' out.)

* Funkin' out is a technical term, really.
 
Jun 5, 2010 at 8:17 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6210
Age: 38
Actually, thinking about all this it may be beneficial to add these tsc commands to vanilla Cave Story as well. Forgive me, I am somewhat excited about the idea.

Anyway since 9999 is the largest amount you could possibly accept for a variable using <VAR, and the largest "possible" value input for TSC commands in general is the same (I stress possible because each command has its own limit), then you will need 2 bytes of space per variable. How much space in ram do you have to burn?

@Noxid: An xls file is an Excel Spreadsheet file.
 
Jun 5, 2010 at 10:08 AM
Cold Agony of Resolute Vacuum
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jan 1, 2008
Location: Elsewhere
Posts: 1973
andwhyisit said:
Actually, thinking about all this it may be beneficial to add these tsc commands to vanilla Cave Story as well. Forgive me, I am somewhat excited about the idea.

Anyway since 9999 is the largest amount you could possibly accept for a variable using <VAR, and the largest "possible" value input for TSC commands in general is the same (I stress possible because each command has its own limit), then you will need 2 bytes of space per variable. How much space in ram do you have to burn?

@Noxid: An xls file is an Excel Spreadsheet file.

Indeed it would.
In fact, it's been my plan all along. :3

And hmmm...
I say impose a reasonable limit on variables, say 256 in total (V000:V255)?

That gives 2 bytes x 256 = 512 bytes needed.
Though I'm sure an array of some description could store such data more effeciently.

Also, a couple samples of what this makes possible in simpler terms:

#0099
<VAR0001:0100<END // Set variable to 100
#0100
<FLJ0120:0103<FL-V001<VA+0001:0001<FL+V001<END // Check Flag 120. If clear, clear VFlag, Increment V001 by 1, Store as VFlag.
#0101
<FLJ0100:0104<FL-V001<VA-0001:0001<FL+V001<END // Check Flag 100. If clear, clear VFlag, Decrement V001 by 1, Store as VFlag.
#0103
<MSGYou can't carry any more.<NOD<CLO<END // Limit reached
#0104
<MSGYou can't give what you don't have...<NOD<CLO<END // You have none

A basic counter for 20 items. Only worries if you have none of have full. Some form of variable-based return could be handy here, to allow it to return if it succeeds (Eg. Flag 120 or 100 AREN'T set) to a previous event (or variable subsequent one), allowing to mimic a stack-like arrangement. THIS IS WHAT I DREAM OF.

Or:
#0099
<VAR0001:0100<END // Set V001 to 100
#0100
<VA+0001:0001<EVEV001 // Increment V001 by 1, run VEvent
#0101
[Some event]
#0102
[Other event]
[...]
#0200
<VAR0001:0100<MSFin...?<NOD<CLO<END // Reset

Sorta like a table selector. Could possibly be used to generate some psuedo-random events for, say, a slot machine. Or maybe for NPC dialogue so they don't always say the same thing. More of a goofy example, but it doesn't use flags (though it could).

In both examples event #0099 is assumed to be called somewhere else and is here for clarity.

Also, on a final note: Perhaps allow each variable to have a command form.

<FLJV001:0001 - as an argument
<001 - as a command
And, for epicness, <001 should print its current value.

<MSGHello world, I am <001 years old!<NOD<CLR<VA+0001:0001<END

Would initially display "Hello world, I am 0 years old!" and each subsequent time until it/the game is reset would display the number as 1 greater.
 
Jun 5, 2010 at 11:50 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6210
Age: 38
DragonBoots said:
Could possibly be used to generate some psuedo-random events for, say, a slot machine.
Actually that's another thing, random number generation.
<RNDXXXX:YYYY:ZZZZ - Generate a random number between x and y and store in z.
Could be useful.


Actually scratch that, pseudo-random number generation in assembly sounds complicated.

DragonBoots said:
Also, on a final note: Perhaps allow each variable to have a command form.

<FLJV001:0001 - as an argument
<001 - as a command
And, for epicness, <001 should print its current value.

<MSGHello world, I am <001 years old!<NOD<CLR<VA+0001:0001<END

Would initially display "Hello world, I am 0 years old!" and each subsequent time until it/the game is reset would display the number as 1 greater.
No. It is better to have a single command (<PRNXXXX, where x is the variable number) to print the variable instead rather than make 256 new commands. :D

<MSGHello world, I am <PRN0001 years old!<NOD<CLR<VA+0001:0001<END
 
Jun 5, 2010 at 12:19 PM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
andwhyisit said:
Actually scratch that, pseudo-random number generation in assembly sounds complicated.

PUSH max
PUSH min
Call 40F350
Add ESP, 8

Returns a number between min and max to EAX

<001 as a command would be unreasonable based on how the parser works by comparing each character in sequence to a hardcoded value you'd need to extend the parser for EVERY possiblity.
Oh but I see Andwhy picked up on that.

9999 isn't the largest possible value you can input, ~~~~ is (87769)
 
Jun 5, 2010 at 3:01 PM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6210
Age: 38
Noxid said:
9999 isn't the largest possible value you can input, ~~~~ is (87769)
Correction: 9999 is the largest possible literally interpreted zero-padded decimal integer value that can be inputted into a tsc command.

To be honest I doubt there is any real situation where you would need to use ~~~~ in a variable.
 
Jun 6, 2010 at 1:48 AM
Cold Agony of Resolute Vacuum
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jan 1, 2008
Location: Elsewhere
Posts: 1973
andwhyisit said:
Actually that's another thing, random number generation.
<RNDXXXX:YYYY:ZZZZ - Generate a random number between x and y and store in z.
Could be useful.


Actually scratch that, pseudo-random number generation in assembly sounds complicated.


No. It is better to have a single command (<PRNXXXX, where x is the variable number) to print the variable instead rather than make 256 new commands. :confused:

<MSGHello world, I am <PRN0001 years old!<NOD<CLR<VA+0001:0001<END

Quiet. -_-''
It was 4 AM when I made that post.
It's a wonder it didn't devolve into Power Rangers lyrics.

Noxid said:
PUSH max
PUSH min
Call 40F350
Add ESP, 8

Returns a number between min and max to EAX

<001 as a command would be unreasonable based on how the parser works by comparing each character in sequence to a hardcoded value you'd need to extend the parser for EVERY possiblity.
Oh but I see Andwhy picked up on that.

9999 isn't the largest possible value you can input, ~~~~ is (87769)

Eh. For all intents and purposes 9999 would be suffecient.
Though if it would generate less work somehow, I suppose allowing up to ~~~~ would be fine. :/
 
Jun 6, 2010 at 1:49 AM
Senior Member
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Nov 3, 2009
Location: United States, East Coast
Posts: 150
What is this I don't even??

Yeah, assembly flies straight above my head...

OT: DragonBoots a demo would be amazing! (just to see how alchemy works)
Do you think it's going to happen?
 
Jun 6, 2010 at 1:58 AM
Cold Agony of Resolute Vacuum
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jan 1, 2008
Location: Elsewhere
Posts: 1973
igotsthepower9000 said:
What is this I don't even??

Yeah, assembly flies straight above my head...

OT: DragonBoots a demo would be amazing! (just to see how alchemy works)
Do you think it's going to happen?

Yeah, ditto.
Which is why I get someone else to do it. ^^;
I can sorta grasp the concepts behind it, but in terms of actually making a change I'm clueless.
Largely because I'm used to working with commented code. ^^;

On topic: Yeah, I'm pretty sure it's gonna happen.
As I've said many times with regards to this mod: I'm going to lay down the framework before I weave the story.

If I *really* wanted to I could release something now, but in its current incarnation it's a little buggy to say the least (and some of the alchemy items just plain don't work). -_-;;
 
Jun 6, 2010 at 4:10 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6210
Age: 38
We may need a zero padding version of <PRNXXXX. Say instead of outputting 2 you want to output 002.

<PNZXXXX:YYYY - Output var x zero-padded to y digits if the number of digits in x is less than y.

Also if you plan to do any maths operations beyond addition and subtraction you may need 4 bytes (signed with 3 digits after the decimal point) for math operations.

<MASXXXX - Store var x into 4-byte math variable for math operations.
<MADXXXX - Divide math variable by x, store in math variable.
<MDRXXXX - Divide x by math variable, store in math variable.
<MAMXXXX - Multiply math variable by x, store in math variable.
<MAAXXXX - Add math variable to x, store in math variable.
<MSUXXXX - Subtract math variable by x, store in math variable.
<MSRXXXX - Subtract x by math variable, store in math variable.
<MPOXXXX - Math variable to the power of x, store in math variable.
<MPRXXXX - X to the power of math variable, store in math variable.
<MMOXXXX - Modulus of math variable and x, store in math variable.
<MMRXXXX - Modulus of x and math variable, store in math variable.
<MAEXXXX:YYYY - Store math variable into var x, using rounding method y

Rounding methods:
0 = normal rounding with negative values becoming 0 (-1 is now 0).
1 = round down with negative values becoming 0.
2 = round up with negative values becoming 0.
3 = normal rounding with negative values becoming positive (-1 is now 1).
4 = round down with negative values becoming positive.
5 = round up with negative values becoming positive.
6 = save digits after the decimal point as int (0000000.XXX).
7 = save as 1 for a positive number and 0 for a negative one.
8 = save the first four digits to the left of the decimal point (000XXXX.000).
9 = save the last three digits to the left of the decimal point (XXX0000.000).

The math variable is different from the current variables because you cannot reference it in an argument.

But that is all irrelevant if there is no need for multiplication, division or exponentiation.

DragonBoots said:
Quiet. -_-''
It was 4 AM when I made that post.
It's a wonder it didn't devolve into Power Rangers lyrics.
Well if you do then I will resort to using the Captain Planet theme song. :p

DragonBoots said:
Eh. For all intents and purposes 9999 would be suffecient.
Though if it would generate less work somehow, I suppose allowing up to ~~~~ would be fine. :/
87769 cannot be represented in two bytes, so you could have that value be stored in a variable as either 9999 or 65535.
 
Jun 6, 2010 at 6:48 AM
Senior Member
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Nov 3, 2009
Location: United States, East Coast
Posts: 150
DB I'm sorry for the unrelated topic but is there a way to contact Lace like through yahoo, or something other than PMing him? (I was told that his inbox was maxed out....)
I have some unfinished business with him.

Anyway a little bit more on topic I have a little question: will wizard spells be modded weapons or do you have to go through a menu of sorts to access them (like some RPGs I know...)?
 
Jun 6, 2010 at 11:01 PM
Cold Agony of Resolute Vacuum
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jan 1, 2008
Location: Elsewhere
Posts: 1973
andwhyisit said:
We may need a zero padding version of <PRNXXXX. Say instead of outputting 2 you want to output 002.

<PNZXXXX:YYYY - Output var x zero-padded to y digits if the number of digits in x is less than y.

Also if you plan to do any maths operations beyond addition and subtraction you may need 4 bytes (signed with 3 digits after the decimal point) for math operations.

<MASXXXX - Store var x into 4-byte math variable for math operations.
<MADXXXX - Divide math variable by x, store in math variable.
<MDRXXXX - Divide x by math variable, store in math variable.
<MAMXXXX - Multiply math variable by x, store in math variable.
<MAAXXXX - Add math variable to x, store in math variable.
<MSUXXXX - Subtract math variable by x, store in math variable.
<MSRXXXX - Subtract x by math variable, store in math variable.
<MPOXXXX - Math variable to the power of x, store in math variable.
<MPRXXXX - X to the power of math variable, store in math variable.
<MMOXXXX - Modulus of math variable and x, store in math variable.
<MMRXXXX - Modulus of x and math variable, store in math variable.
<MAEXXXX:YYYY - Store math variable into var x, using rounding method y

Rounding methods:
0 = normal rounding with negative values becoming 0 (-1 is now 0).
1 = round down with negative values becoming 0.
2 = round up with negative values becoming 0.
3 = normal rounding with negative values becoming positive (-1 is now 1).
4 = round down with negative values becoming positive.
5 = round up with negative values becoming positive.
6 = save digits after the decimal point as int (0000000.XXX).
7 = save as 1 for a positive number and 0 for a negative one.
8 = save the first four digits to the left of the decimal point (000XXXX.000).
9 = save the last three digits to the left of the decimal point (XXX0000.000).

The math variable is different from the current variables because you cannot reference it in an argument.

But that is all irrelevant if there is no need for multiplication, division or exponentiation.


Well if you do then I will resort to using the Captain Planet theme song. :D


87769 cannot be represented in two bytes, so you could have that value be stored in a variable as either 9999 or 65535.
Augh!
Too much maths! X_X
And yeah...
That all's cool in theory, but useless in practice...
I think.
Well, not useful for WatS at least.

igotsthepower9000 said:
DB I'm sorry for the unrelated topic but is there a way to contact Lace like through yahoo, or something other than PMing him? (I was told that his inbox was maxed out....)
I have some unfinished business with him.

Anyway a little bit more on topic I have a little question: will wizard spells be modded weapons or do you have to go through a menu of sorts to access them (like some RPGs I know...)?
Yeah, he does.
I'll PM you his email addy.

And it'll work by pressing the W key, then selecting the spell you want from a pool of 6.
Though with this variable deal I could theorhetically expand the number of spells learnable (or at the least make them level-able through successive castings or sidequests).
 
Jun 8, 2010 at 5:42 AM
In front of a computer
"Man, if only I had an apple..."
Join Date: Mar 1, 2008
Location: Grasstown
Posts: 1435
DragonBoots said:
Look again.
1.) Bit-wise TSC processors are good for things that will remain static or for very large lists (more than ~16 items) as it consumes fewer flags. However, making it able to increment and decrement can be tricky, as you have to check (for either) what your current value is before incrementing or decrementing, which expands the script tremendously.
Um, what? Why would you need to know the current value of the flagset before incrementing? In pseudo-TSC, assuming the number occupies flags 0001, 0002, 0003, and 0004 (in order, so that the value 1 is when flag 4 is set and the other three are unset):

Code:
#0001
<[color=#7F7F7F]FLJ[/COLOR][color=#7F7F7F]0004[/COLOR]:[color=#7F7F7F]0002[/COLOR]<[color=#7F7F7F]FL+[/COLOR][color=#7F7F7F]0004[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0002
<[color=#7F7F7F]FL-[/COLOR][color=#7F7F7F]0004[/COLOR]<[color=#7F7F7F]FLJ[/COLOR][color=#7F7F7F]0003[/COLOR]:[color=#7F7F7F]0003[/COLOR]<[color=#7F7F7F]FL+[/COLOR][color=#7F7F7F]0003[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0003
<[color=#7F7F7F]FL-[/COLOR][color=#7F7F7F]0003[/COLOR]<[color=#7F7F7F]FLJ[/COLOR][color=#7F7F7F]0002[/COLOR]:[color=#7F7F7F]0004[/COLOR]<[color=#7F7F7F]FL+[/COLOR][color=#7F7F7F]0002[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0004
<[color=#7F7F7F]FL-[/COLOR][color=#7F7F7F]0002[/COLOR]<[color=#7F7F7F]FLJ[/COLOR][color=#7F7F7F]0001[/COLOR]:[color=#7F7F7F]0005[/COLOR]<[color=#7F7F7F]FL+[/COLOR][color=#7F7F7F]0001[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0005
<[color=#7F7F7F]END[/COLOR] [color=#7F7F7F]// The execution of this event signals that the integer has
     // overflowed from max (15 in this example) to 0.[/COLOR]

Note: The assumption in this code is that FLJ/FNJ takes the flag as the first argument. It also assumes unsigned integers, because signed integers complicate things a bit. I think.

And for decrement:
Code:
#0001
<[color=#7F7F7F]FNJ[/COLOR][color=#7F7F7F]0004[/COLOR]:[color=#7F7F7F]0002[/COLOR]<[color=#7F7F7F]FL-[/COLOR][color=#7F7F7F]0004[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0002
<[color=#7F7F7F]FL+[/COLOR][color=#7F7F7F]0004[/COLOR]<[color=#7F7F7F]FNJ[/COLOR][color=#7F7F7F]0003[/COLOR]:[color=#7F7F7F]0003[/COLOR]<[color=#7F7F7F]FL-[/COLOR][color=#7F7F7F]0003[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0003
<[color=#7F7F7F]FL+[/COLOR][color=#7F7F7F]0003[/COLOR]<[color=#7F7F7F]FNJ[/COLOR][color=#7F7F7F]0002[/COLOR]:[color=#7F7F7F]0004[/COLOR]<[color=#7F7F7F]FL-[/COLOR][color=#7F7F7F]0002[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0004
<[color=#7F7F7F]FL+[/COLOR][color=#7F7F7F]0002[/COLOR]<[color=#7F7F7F]FNJ[/COLOR][color=#7F7F7F]0001[/COLOR]:[color=#7F7F7F]0005[/COLOR]<[color=#7F7F7F]FL-[/COLOR][color=#7F7F7F]0001[/COLOR]<[color=#7F7F7F]END[/COLOR]
#0005
<[color=#7F7F7F]END[/COLOR] [color=#7F7F7F]// The execution of this event signals that you've
     // overflowed from 0 to max.[/COLOR]

DragonBoots said:
2.) Flag-Per-Item counters are best for short lists of things that will be frequently changed. Incrementing or decrementing the stored value is basically as simple as a string of flag checks that lead to different events to decrement or increment appropriately (which could appear as <FL-XXXX<FL-XXXX<FL-XXXX<FL+YYYY if it's tracking something like a quantity - Since only the flag for the "current" quantity needs to be set).
Not really sure how incrementing works here...?

andwhyisit said:
<BIJXXXX:YYYY:ZZZZ - Add the values from Z and range X:Y together and run the resulting event number.
...this command does not make sense.

DragonBoots said:
Probably work best as <BIJWWWW:XXXX:YYYY:ZZZZ
Makes more sense this way. However, it might be easier to specify a flag block (byte, or a flag that's a multiple of 8) rather than a flag, and omit the endpoint (for any math function). Working with numbers spanning across multiple bytes could get tricky (assuming it's not 2 or 4 full bytes).

DragonBoots said:
<VARXXXX - Stores variable X. 0000 should clear. Should only accept standard numerical values.
<VA+ - Increments existing variable X
<VA- - Decrements existing variable X
Variables would indeed be nice. Your second suggestion (with a Y) would be better though.

DragonBoots said:
<TRA0100:0050:0020:V001 for the first variable (the "V" informing it to check the slot).
This could work, of course; it'd be slightly easier to instead have a <VLDXXXX command that substitutes the value of the specified variable into the first 0000 parameter of the next command, but that's also a significant loss of flexibility.

Noxid said:
"There isn't really any RAM to make variables in" as far as I know.. Well, unless you kill the Old Map data. Or that smidgen at 4bba00 lace told me bout'.
Um, or you could allocate more. Just make sure to deallocate it when you're done, or you'll have major memory leaks. Assuming Cave Story is linked with the full C standard library, all you would have to do is call malloc to allocate and free to deallocate. (You'd need to find the address of these functions). Both functions take one argument; malloc takes as an argument the number of bytes to allocate and returns the address of the new memory; later, when you're done with it, you would pass that address to free as its argument.

I'm not entirely sure how to call functions in assembly, but it would be something along the lines of "push arg; call func;".

Noxid said:
If the variable had to save, then I'd endorse the use of some flag data unless you were feeling like hacking the save feature which I've not actually looked into myself so I can't vouch for the feasability.
Again, this would be done by calling a library function (most likely fwrite, but it's also possible that Pixel called the Windows file handling functions directly). Just find the code where saving is done, and duplicate the logic.

Noxid said:
Though you would still need a command to store the variable to the flag data (when saving data), and another to retrieve the flag data and store it to a variable (when loading data).

BINXXXX:YYYY:VZZZ - Store var z into range x:y.
BVRXXXX:YYYY:ZZZZ - Load data from range x:y and store in z.
I don't see what's wrong with storing variables in a new section instead.

andwhyisit said:
How much space in ram do you have to burn?
Theoretically, unlimited.

DragonBoots said:
I say impose a reasonable limit on variables, say 256 in total (V000:V255)?
This is reasonable. You could avoid having a limit altogether through judicious use of malloc, but that's probably more work than you'd want to deal with when programming in assembly.

DragonBoots said:
Though I'm sure an array of some description could store such data more effeciently.
Not especially; however, using an array makes it easy to find where in memory your variable is. To use an array, you need to allocate the entire array all at once. So, if you want an array of 256 2-byte variables, the argument to malloc would be 512.

DragonBoots said:
A basic counter for 20 items. Only worries if you have none of have full. Some form of variable-based return could be handy here, to allow it to return if it succeeds (Eg. Flag 120 or 100 AREN'T set) to a previous event (or variable subsequent one), allowing to mimic a stack-like arrangement. THIS IS WHAT I DREAM OF.
What do you mean by a "stack-like" arrangement?

With just variables and no call stack or any such conveniences, the best way to do return values would probably be to use a reserved variable. Example:

Code:
#0001
<[color=#7F7F7F]VAR[/COLOR][color=#7F7F7F]0000[/COLOR]:[color=#7F7F7F]0002[/COLOR]<[color=#7F7F7F]JMP[/COLOR][color=#7F7F7F]0003[/COLOR] [color=#7F7F7F]// This JMP calls the function[/COLOR]
#0002
<[color=#7F7F7F]MSG[/COLOR]The function returned <[color=#7F7F7F]PRN[/COLOR][color=#7F7F7F]0001[/COLOR]!<[color=#7F7F7F]END[/COLOR]
[color=#7F7F7F]// This event runs after the function call.[/COLOR]
#0003
<[color=#7F7F7F]VAR[/COLOR][color=#7F7F7F]0001[/COLOR]:[color=#7F7F7F]0120[/COLOR]<[color=#7F7F7F]JMP[/COLOR][color=#7F7F7F]V000[/COLOR] [color=#7F7F7F]// And this event is the function[/COLOR]
Note that a function could span multiple events, of course.

DragonBoots said:
Also, on a final note: Perhaps allow each variable to have a command form.
This is a nice idea.

DragonBoots said:
<MSGHello world, I am <001 years old!<NOD<CLR<VA+0001:0001<END

Would initially display "Hello world, I am 0 years old!" and each subsequent time until it/the game is reset would display the number as 1 greater.
Not so. Unless you actually set the variable to 0 at some earlier time, you cannot predict what the initial value of a variable will be.

Though, my suggestion would be to zero the entire variable area of RAM using memset. I forget how that function works though.

andwhyisit said:
Actually scratch that, pseudo-random number generation in assembly sounds complicated.
Fortunately, it has been done for you. Call the rand library function.

...actually, I'm pretty sure Noxid said that already.


andwhyisit said:
It is better to have a single command (<PRNXXXX, where x is the variable number) to print the variable instead rather than make 256 new commands. :D
Actually, you wouldn't have to make 256 new commands. You could make just one. However, instead of comparing each of the three characters in turn to a hard-coded value, you would check the return value of the isdigit function, which takes a single argument: the character to check. If it returns 1 (non-zero, technically) for all three characters, you know this is a print variable command, and you backtrack to get the number of the variable.

That said, the <PRN command would probably be less work.

Noxid said:
PUSH max
PUSH min
Call 40F350
Add ESP, 8

Returns a number between min and max to EAX
...wait, what? Which function are you calling here? That is, what would be the C name of the function? The rand() function I know does not take arguments.

Noxid said:
<001 as a command would be unreasonable based on how the parser works by comparing each character in sequence to a hardcoded value you'd need to extend the parser for EVERY possiblity.
Oh but I see Andwhy picked up on that.
It would not be unreasonable. Just because the parser works like that does not mean you can make an exception for this command.

andwhyisit said:
<MASXXXX - Store var x into 4-byte math variable for math operations.
<MADXXXX - Divide math variable by x, store in math variable.
<MDRXXXX - Divide x by math variable, store in math variable.
<MAMXXXX - Multiply math variable by x, store in math variable.
<MAAXXXX - Add math variable to x, store in math variable.
<MSUXXXX - Subtract math variable by x, store in math variable.
<MSRXXXX - Subtract x by math variable, store in math variable.
<MPOXXXX - Math variable to the power of x, store in math variable.
<MPRXXXX - X to the power of math variable, store in math variable.
<MMOXXXX - Modulus of math variable and x, store in math variable.
<MMRXXXX - Modulus of x and math variable, store in math variable.
<MAEXXXX:YYYY - Store math variable into var x, using rounding method y
...whoa. Why do it this way? It sounds like your plan is to have a special floating-point "register" for math operations. You should know that this is a bad idea if you really only care about integer math; floating-point numbers cannot represent decimal portions accurately unless they are multiples of a power of 1/2. It's much like how you can't represent 1/3 accurately in the decimal system, except that in binary there are a lot less fractions you can accurately represent.

andwhyisit said:
Rounding methods:
0 = normal rounding with negative values becoming 0 (-1 is now 0).
1 = round down with negative values becoming 0.
2 = round up with negative values becoming 0.
3 = normal rounding with negative values becoming positive (-1 is now 1).
4 = round down with negative values becoming positive.
5 = round up with negative values becoming positive.
6 = save digits after the decimal point as int (0000000.XXX).
7 = save as 1 for a positive number and 0 for a negative one.
8 = save the first four digits to the left of the decimal point (000XXXX.000).
9 = save the last three digits to the left of the decimal point (XXX0000.000).
Well, this is a pretty odd collection of rounding methods. Method 7 is not rounding at all (it's the signum or sgn function). Also, define "normal rounding", because there's no one normal method of rounding.

For reference, standard rounding methods are usually something like the following (assuming we have signed integers, though): TO_INFINITY, TO_ZERO, TO_NEG_INFINITY, TO_NEAREST, and the last one which I don't know the name of. TO_NEAREST would be the common "check the first digit after the decimal, round up if >5 else round down). The nameless one is similar, except if the digit is 5 and the next digit after the decimal point is even (or odd, I forget which) you round down instead of up. Examples:
Code:
NUMBER     ZERO     INF     NEG_INF     NEAREST     OTHER
 3.45       3        4       3           3           3
 2.43       2        3       2           2           2
 5.53       5        6       5           6           5
 5.56       5        6       5           6           6
 3.79       3        4       3           4           4
-3.45      -3       -3      -4          -3          -3
-2.43      -2       -2      -3          -2          -2
-5.53      -5       -5      -6          -6          -5
-5.56      -5       -5      -6          -6          -6
-3.79      -3       -3      -4          -4          -4

I'm thinking that if you really wanted such a command set, it would be helpful to make the rounding type a decimal "bitfield". That is, each decimal digit has a separate meaning.

So, something like this:
<MAEXXXX:ABCD

Values for D (rounding method):
0 - Towards zero (truncate)
1 - Towards infinity
2 - Towards negative infinity
3 - To nearest
4 - To nearest with statistical correction
5 - Retain fraction only (X - floor(X) if positive, X - ceil(X) if negative)

Values for C (sign behaviour):
0 - Keep sign (might not be useful)
1 - Apply abs() function (negative numbers become positive)
2 - Apply sgn() function (1 if positive else 0; though, technically, this is not how sgn() works; it returns -1 if negative and 0 only if 0)
 
Jun 8, 2010 at 6:08 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
I'm sorry but if there's ever something I'd tl;dr it's that. I mean I read some of it but I couldn't manage it all.

Anyway personally, doing ASM code I try to go for the simplest option which more often than not is the one that involves the *least* amount of modifications to the existing code. I dont *know* how to allocate memory so I just don't. I've never looked at fwrite so I probably won't do anything involving it unless I really have to.

Because this is ASM and not C (from what I can tell it was specifically Microsoft Visual C++) certain things that might seem simple are confusing and difficult and crash-y without knowing stuff.. that I dont know.
 
Jun 8, 2010 at 2:19 PM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6210
Age: 38
Celtic Minstrel said:
...this command does not make sense.
As an example I'll set x to 10, y to 4, and z to 100.
<BIJ0010:0004:0100

Lets say that the binary data in flags 10-13 (4 bits) was equal to 7. 7+100=107, therefore run event 0107. If it was equal to 0 then run event 0100. If it was equal to 29 then run event 0129.

But that is irrelevant since DB is not using it. And I don't think <BIJ will be used anyway because the flag data can be saved to a variable after the game is loaded, which is much more efficient.

Celtic Minstrel said:
...whoa. Why do it this way? It sounds like your plan is to have a special floating-point "register" for math operations. You should know that this is a bad idea if you really only care about integer - math; floating-point numbers cannot represent decimal portions accurately unless they are multiples of a power of 1/2. It's much like how you can't represent 1/3 accurately in the decimal system, except that in binary there are a lot less fractions you can accurately represent.
It sounds like you really don't understand the concept.

Lets say I divide 1 by 2 and multiply by 2, I'd get 1 right? Well what would really happen is:

1/2=0.5
round to store as an unsigned integer (either 0 or 1)
0*2=0 or 1*2=2
round to store as an unsigned integer (either 0 or 2)

We want an answer BEFORE we save it as a 2-byte unsigned integer.

1/2=0.5
0.5*2=1
round to store as an unsigned integer (1)

To do that we need to store that 0.5 value somewhere.

The idea isn't to be outrageously accurate, you cannot use a two-byte unsigned integer for division, multiplication and exponentiation and guarantee results that are even close to correct. Results of 13.333 and any loss occurred are irrelevant because once that data is saved back to a variable after the math operation it will be rounded down to 13. As long as it has little impact on the final integer result.

Celtic Minstrel said:
Well, this is a pretty odd collection of rounding methods. Method 7 is not rounding at all (it's the signum or sgn function).
I intended to rename that to "output methods", but I forgot. Sue me.

Celtic Minstrel said:
Also, define "normal rounding", because there's no one normal method of rounding.
By normal rounding I mean conditional rounding where the value is rounded to the closest integer.

Celtic Minstrel said:
I don't see what's wrong with storing variables in a new section instead.
The flag stored data and the variables are two different things. The variables only exist during runtime and are stored elsewhere in ram. The flag data is for storing information for profile.dat on save and retrieving information on load, like the current MyChar sprite for instance.
 
Jun 14, 2010 at 2:09 PM
In front of a computer
"Man, if only I had an apple..."
Join Date: Mar 1, 2008
Location: Grasstown
Posts: 1435
Noxid said:
I'm sorry but if there's ever something I'd tl;dr it's that. I mean I read some of it but I couldn't manage it all.
Hehe, sorry. I just had a whole lot to respond to, I guess.

Noxid said:
Anyway personally, doing ASM code I try to go for the simplest option which more often than not is the one that involves the *least* amount of modifications to the existing code. I dont *know* how to allocate memory so I just don't. I've never looked at fwrite so I probably won't do anything involving it unless I really have to.
I think allocating memory would be fairly easy, once you figure out how to call malloc. As for fwrite, chances are that he already uses it for saving the profile, so you can just mimick that code if you want to write to a file (and if he doesn't use fwrite there and instead uses Windows API functions, it really doesn't matter since the net effect is pretty much the same).

Noxid said:
Because this is ASM and not C (from what I can tell it was specifically Microsoft Visual C++) certain things that might seem simple are confusing and difficult and crash-y without knowing stuff.. that I dont know.
Sure. Still, if it becomes important (eg if you discover you need more RAM than is available, and there's no way around that), you can do the research! :(

andwhyisit said:
It sounds like you really don't understand the concept.
I do understand the concept of integer vs floating-point math.

andwhyisit said:
Lets say I divide 1 by 2 and multiply by 2, I'd get 1 right? Well what would really happen is:

1/2=0.5
round to store as an unsigned integer (either 0 or 1)
0*2=0 or 1*2=2
round to store as an unsigned integer (either 0 or 2)
Normally these would give you a result of 0, since integer division is truncated.

andwhyisit said:
We want an answer BEFORE we save it as a 2-byte unsigned integer.

1/2=0.5
0.5*2=1
round to store as an unsigned integer (1)

To do that we need to store that 0.5 value somewhere.
Yes, I do understand what you mean and the reason for it.

andwhyisit said:
The idea isn't to be outrageously accurate, you cannot use a two-byte unsigned integer for division, multiplication and exponentiation and guarantee results that are even close to correct. Results of 13.333 and any loss occurred are irrelevant because once that data is saved back to a variable after the math operation it will be rounded down to 13. As long as it has little impact on the final integer result.
My point is that the inaccuracy of the representation of floating-point numbers can give some unexpected results. Even integers cannot be precisely represented in floating-point format, since it's stored in scientific notation (meaning that all binary digits other than the first are after the decimal point).

Also, floating-point format can represent positive and negative infinity as well as various NaNs (error codes; stands for "not a number"). I'm not sure if such things are automatically handled when converting back to an integer.

andwhyisit said:
I intended to rename that to "output methods", but I forgot. Sue me.
Okay, sure. I think my list included some that you didn't mention, by the way.

andwhyisit said:
By normal rounding I mean conditional rounding where the value is rounded to the closest integer.
Yeah, the TO_NEAREST algorithm.

andwhyisit said:
The flag stored data and the variables are two different things. The variables only exist during runtime and are stored elsewhere in ram. The flag data is for storing information for profile.dat on save and retrieving information on load, like the current MyChar sprite for instance.
That's the current state of affairs, yes, but why not make a separate section in the profile for the variables? Wouldn't that be a bit easier?
 
Jun 14, 2010 at 2:28 PM
Creating A Legacy...
Bobomb says: "I need a hug!"
Join Date: Sep 6, 2009
Location: The Balcony
Posts: 852
Age: 29
Too much information, My heads going to EXPLODE!!!! :(


:p
 
Jun 14, 2010 at 10:13 PM
Cold Agony of Resolute Vacuum
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jan 1, 2008
Location: Elsewhere
Posts: 1973
JetHawk95 said:
Too much information, My heads going to EXPLODE!!!! :)


:p

Damnit.
And I was gonna give him the alpha test for the current alchemy system. :<
 
Top