This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Messages - squidgetx
Pages: 1 ... 3 4 [5] 6 7 ... 123
61
« on: December 26, 2012, 09:34:43 pm »
Tile editor (design blatantly stolen from calcGS because it's a good design) mostly implemented, have yet to add in fancy tools like copy and pasting and such
To do; Map and tile copy/paste Map file parsing Adding npcs, warp tiles, etc.
62
« on: December 25, 2012, 10:34:58 pm »
133794m3r,
In Axe, the ONLY data type there is is the 16 bit (and sometimes 8 bit) integer. Why? It's the hardware. The biggest register is 16 bits...so yeah. There are different ways of reading this number (signed, unsigned, char, etc.) but it is still only a number. Fixed point notation is just that- notation. It is a different way of representing a 16 bit integer. As such, all the limitations that come with dividing and multiplying integers still exist.
Let's take a look at the example 1.0/*10.0. Runer explained it up above, but I'll attempt to explain a little differently since you didn't seem to get it the first time.
First, understand that that all that the decimal point does, is convert the value from fixed point notation to an integer. Remember fixed point notation means this: high byte is the integer portion, low byte is a fraction of 256. So, 0.5 in fixed point will become 128 (because 128/256 = 0.5). Similarly, 1.0's integer representation is just 256. 10.0's is 2560.
Anyway, the fixed point division returns 1/10, which is actually the integer 25. Why? Because 1/10 of 256 is 25.6, but that's a no no because everything is still integers really, so you just get 25. Then it goes on to **10.0 which just takes your 25 and fixedpoint multiplies by 2560. Which is the same thing as regular multiplying by 10, which is why you get 250.
So basically, what you have to keep in mind when doing math in Axe are two things: one, divisions will always truncate the decimal part. That's just the way it is, you can ask around and explore the ins and outs of writing an integer division routine. Using fixed point can lessen the impact of this phenomenon, but it won't eliminate it, especially as you work with smaller and smaller numbers (like 1/10). Second, all Axe operations move left to right. The only order of operations cue there is are parentheses. That might be why you were having trouble with 2/10*65535; Axe saw 2/10, which is 0, and then multiplied 0 by 65535, which is still 0.
Depending on your numbers, you should (mostly) be able to play around with the way you write your statements to achieve a respectable degree of accuracy. Typically you want to try to get as large a number as you can before performing a division. For example, you can get 1.0/*10.0**10.0 to return 256 if you do 1.0**10.0/*10.0. Unfortunately, you have to be careful not to get a number larger than 65535, otherwise everything will break. So, 2/10*65535 becomes a little trickier. But you can still do it; while 2*65535/10 is not going to help us (because 2*65535 goes over 65535), 2*32767/5+1 gives you 13107. You can play around with the numerator and denominator a bit to try to get optimal results. This is the down and dirty truth of Axe and z80 asm in general. If you want something more accurate and/or larger range than 65535 (or -128 to 128 with x256 accuracy), get ready to write some really complicated routines.
63
« on: December 25, 2012, 01:57:08 pm »
Well theta comes right after Z in TI's ascii set, so that's not a problem. You'd need a different data set for numbers, but for lower case you can add a different number instead of 65 (I think 97 points to lowercase a). Other special characters are a bit of an issue, but if you're just wanting to input something like an appvar name it's not a big deal.
64
« on: December 25, 2012, 01:29:47 pm »
I've found a better way, instead of keeping track of letter arrangements, would be to keep track of the key values. That way you can have one uninterrupted array of key values, the first element being the getKey that matches the letter A, and so on. Then you can just simply use inData(getKey,data(...))+65 to retrieve the ascii value of the letter
65
« on: December 24, 2012, 11:14:36 pm »
Thanks guys Shmibs, yup, that's exactly what it means . Depending on how well this goes, I may even externalize nearly every bit of data out of the caclulator app so that it could even serve as an RPG maker of sorts. Anyway, time for (another) update. Added some antialiased text labels for the tile numbers, and threw in tile/map selection and editing. Tilemaps are fully editable, and while the 16x16 chunks aren't movable (yet), I've put in the ability to create new chunks by clicking on non-existent areas. Now for a question on GUI and tile editing: Should I do it in a separate dialog, via right or double click in the tile selection pane? Or should I have it available in the main window, in a third frame (probably to the left of the map editor, and under the tile selection box)?
66
« on: December 24, 2012, 02:18:22 pm »
I've now made enough progress on this to start a thread on it. Basically, the goal of this side project is to be able to easily generate content for the game. Right now, warp tiles, NPC positions, items, moves and such have to be coded in by hand (ugh).
It's coded in Java, and so far I've got most of the drawing routines done, the GUI layout, and lots of asm/hex/int conversion routines written. Tilefile support is pretty much done, the tricky part is next going to be importing the map files.
Features list (planned, some implemented already) -Tile Editor --24x24 mode for creating large tiles as 4 12x12s --Double click to edit tile --Copy/Paste at least -Map Editor --Display of entire game map on the side for better map design --Right click to add NPC, trigger, or warp -Save and load as z80 source
67
« on: December 22, 2012, 01:09:28 pm »
Jacobly, I think that's a result of sourcecoder/tokens parsing which represents the token r1 as {r1}
Just kidding, there're double brackets.
68
« on: December 22, 2012, 01:07:44 pm »
In memory, there is no difference between "actual data" and "strings" in Axe. "HELLO WORLD" is literally equivalent to [48454C4C4F20574F524C44] which is also equivalent to Data(72,69,76,76,79,32,87,79,82,76,68)
69
« on: December 21, 2012, 09:04:16 pm »
The main compiler has only the two speed modes, slow and optimized or fast and unoptimized. The two passes aren't for optimization, so it's not like a third pass could be easily added for "extra optimization." (Well, maybe it could but it's just not how it's set up now. FYI the two passes are like this: first for the bulk of the code, second to fill in the symbol addresses (labels, pointers, etc.)
70
« on: December 20, 2012, 09:21:20 pm »
I think that Axe moved A-Z a few versions ago; L1 is 768 bytes. Also, L2 is perfectly safe, I think now just as safe as L1 in 1.2.1 (used to be interrupts used that area, but no more). Edit: Actually, i just remembered that MirageOS uses L2 for its custom interrupts. Used to be you could put an FnOff at the beginning of your program to disable MOS interrupts, but I don't know if that still works (I'm 60% sure that it should) For some reason the TI docs list L2 (statVars) as being only 531 bytes, but other areas of free ram start right after where L2 ends for at least a few hundred more bytes, so basically L2 is a lot bigger than 531 bytes. Edit2: L2 points to 871 bytes of free ram, but you may have to zero (using Fill or something) the extra 340 bytes of RAM starting at 8C4D at the end of your program. Source: http://ourl.ca/16406
71
« on: December 19, 2012, 10:42:18 pm »
Update, sort of. The npc engine is (almost) all wrapped up. Only the store is left to program in, and in the mean time I've been working on content. I've added in about 9 areas now, which isn't too much. I'm finding both calcGS and my rle compressor both becoming increasingly difficult to work with, so I'm announcing a side project- an graphical IDE of sorts to manage production of game content. I'm going to try to write in C as a learning experience (just started it) and ill probably make a separate topic for it once it really gets underway. In the meantime I'm completely open to story and gameplay element requests and discussion gimme some ideas!
72
« on: December 19, 2012, 10:19:17 pm »
@stevon8er, your method uses a different one than mine That code is good if you want the screen to scroll only if the player is near the edges; mine keeps the camera centered on the player. Also my code there is barely optimized lol, though I took the liberty of quick-optimizing yours for you (Didn't go crazy here, tried to keep the same overall layout and readability.) ...
0->C->D+8->X->Y
.till [clear] is pressed While 1 MOVE() MAP() .2 subroutines are called Pt-on(X,Y,pic1) DispGraphClrDraw EndIf getKey(15)
Lbl MOVE getKey(3)-getKey(2)+X !If +1 //if x = -1 ->x //make x = 0, since the !If +1 statement left a 0 in hl C-- //decrement C Else!If -89 //otherwise, check if x is 88 (actually, we're checking if x+1-89=0, but it's the same thing right?) C++ 88->X End
getKey(1)-getKey(4)+Y !If +1 ->Y D-- Else!If -57 D++ 56->Y End //and same stuff for Y. Halved the number of getKeys here.
Return
Lbl MAP
.Okay, so the main driving force behind the optimization logic here is that we want to move as much stuff as we can outside of loops. .So for example, C and D will never change while we're in the loop so... .I made up some variable names but you can use whatever you want. D/8->tileY*15+GDB0->tilePointer C/8->tileX -(C^8)-8->offX -(D^8)->screenY
For(9) //for the 9 rows to be drawn tileX->tileX0 offX->screenX For(A,0,12) Pt-on(screenX+8->screenX,screenY,{tilePointer+A}*8+pic0) End screenY+8->screenY //move the Y "pen position" down a row tilePointer+15->tilePointer //next row of tiles End Return
73
« on: December 19, 2012, 05:35:06 pm »
There are basically two ways to do it, one using your method where you keep track of the offset and tile separately, or a method where they are combined into one value. I've always used this latter method, which I'll try to briefly explain here.
The only value we'll bother keeping track of is absolute X and Y position, in pixels. If we're using 8x8 tiles, that means the tile coordinate of our point X,Y is the tile point X/8,Y/8. (Remember Axe division throws out the decimal/fractional portion). To find the pixel offset, we'll use the modulus operator ^8. Both of these operations are pretty fast since 8 is a nice power of 2.
Maybe we can make a routine that takes two coordinates for arguments, and returns what tile number that pixel lies in
Lbl getTile {r2/8*tileMapWidth+(r1/8)+pointer} Return
For optimization's sake, you can leave out the first r2 which is kind of nice. So anyway, now you can check collisions on any pixel-point you want-- for example, checking all 4 corners of a player sprite.
getTile(X,Y)+getTile(X+7,Y+7)+getTile(X,Y+7)+getTile(X+7,Y)
would add up the tile# of all 4 corners of your player; this is a nice way to check for collisions if 0 is the only traversable tile.
Now, how do we draw the tilemap with this scheme? It's pretty easy, we can start with pseudocode.
For(row,0,8) For(column,0,12) Pt-On(column*8-xOffset,row*8-yOffset,{yTile+column*tileMapWidth+xTile+pointer}*8+tileSprites}) End End
I'll let you fill in the rest.
74
« on: December 19, 2012, 03:26:19 pm »
Nice work on the NPCs. Does the background sun flicker that much on real hardware?
75
« on: December 18, 2012, 10:59:26 am »
You can use any free ram space, or if you're using a program you can even make your own spaces!
A-Z and theta are just locations in memory that have predefined names. L1 (768 bytes), L2 (531 bytes, but actually bigger), L4 (256 bytes), and L5 (128 bytes) are pointers to other areas of memory that are usually free to use.
Pages: 1 ... 3 4 [5] 6 7 ... 123
|