EDIT: I'll also be adding in a LOL-type internets story at the suggestion of Drak (#lobby) and a "Nullity" game mode which is reserved for only the masochistic professional (or professional masochist, whichever floats your boat. 1 life, no bombs. Potential Youtube vids, anyone?)
The system'll be flexible enough to allow loading of external levels (though I may not do that yet) and the ability to challenge individual spellcards in the practice mode.
Lv00En00:
cd.const(r0,-1)
Lv00En00L0:
cd.neg(r0)
cd.const(r2,5)
Lv00En00L1:
cd.const(r1,4)
cd.pause(r1)
cd.addy(r0)
cd.djnz(r2,Lv00En00L1)
cd.const(r2,5)
Lv00En00L2:
cd.const(r1,4)
cd.pause(r1)
cd.addx(r0)
cd.djnz(r2,Lv00En00L2)
cd.neg(r0)
cd.const(r2,5)
Lv00En00L3:
cd.const(r1,4)
cd.pause(r1)
cd.addy(r0)
cd.djnz(r2,Lv00En00L3)
cd.const(r2,5)
Lv00En00L4:
cd.const(r1,4)
cd.pause(r1)
cd.addx(r0)
cd.djnz(r2,Lv00En00L4)
cd.goto(Lv00En00L0)
Heh. Try to understand that :P
well there are people who owns one and actually does x.x. I don't really understand, though, because they have like 480K of archive (1.54 MB if they got the SE), they could fit 10 copies of Iambian's game or more when finished
And they'll probably have about that many copies. The underlying system is flexible enough for me to release various "editions" of the game, each with its own bosses and story lines. I could conceivably pump out these games as part of a series. I've already got three story ideas...That's pretty sweet. It's nice that your engine is that flexible. Oh and about the space, I really wouldn't worry about it too much. With good games people don't mind commiting some space to them. :D
With good games people don't mind commiting some space to them. :DWell I wouldn't say so, unless the trend has changed in the past year. Until 2005 people didn't mind about the space taken by games if they were good, but afteward it was a different story. You probably missed all the complaints and whining about how Reuben Quest 2 and Metroid II took way too much space on a 84+ x.x. THere were even people complaining about Desolate being too huge. I have no idea why people got so uptight about game file size in these years, considering many nearly worshipped authors of games like FFTOM and The Verdante Forest before
Well, that's it. I can actually foresee slamming face first into the 16KB memory limit for a 1 page application. I've just started working on the text system for the "story mode" in the game (where the story of the game is told in the dialogue between you and the boss of whatever level you're in) and I'm nearing 11KB.What kind of compression are you using? I'm getting pretty nice compression rates (~300 bytes for a fullscreen picture) for my pictures of loli's in this game. I'm using Vertical RLE. My game is 7.5K now, with the insane buffer and lots of loli's etc. Of course I'll be making a lot more code still, and it barely contains level data.
Know that I have to have boss and enemy image and script data for about 6 to 8 stages, each boss having its own portrait sprite and image data for each of its spellcards that it can use. Then there's your own characters, which I plan on including 6 to 8, each with its own portrait and spellcard images, and their own code. Don't mention anything about backgrounds, which there will be 8+, one for each stage, and maybe one for each of the boss fights. THEN, there will be the actual dialogue between you and the boss, which will vary depending on what character you select for the "adventure."
Then, there's the issue of having an actual title screen, which this game completely lacks at this point. Cramming it all in the remaining 5K seems unrealistic, so... now I have to figure out how to distribute all this data across two or more pages and still have the routines that need to access it still readily available.
BUT... on the bright side, the beta demo version that will release prior to actually writing a coherent story for this will remain as a 1 page, 16K application. I just want to let you all know that this game *will* end up being a 32K or (if worst comes to worst) a 48K app when all is said and done.
wish ya luck, iambian. btw, i decided to check out CelticII. any compatibility issues between that and xLib i may need to know?Do you mean CelticIII? With xLIB and CelticII I haven't had any problems. Plus, since with CelticII is a program and xLIB is an app I don't think there's much that would conflict.
Good luck Iambian!wish ya luck, iambian. btw, i decided to check out CelticII. any compatibility issues between that and xLib i may need to know?Do you mean CelticIII? With xLIB and CelticII I haven't had any problems. Plus, since with CelticII is a program and xLIB is an app I don't think there's much that would conflict.
...I actually sourced that one from one of my earlier games (port), "Fishy". The most recenter version included a cheat mode that made your sprite look like that, which I named "DevBlock", since I used it to test out a few things without ever having to worry about actually playing the game to encounter the problems.
Kinda confused why your ship is a puzzle frenzy block tho. :P
Filler until he make the actual sprite i'd assume.Actually... according to the first "storyline" I've planned out, that *is* an actual character.
So far looks really good. I played it on my TI-83+ and my TI-83+ SE and I came across no problems. I beat the demo on easy, and then tried and beat it on lunatic on a whim. Lunatic doesnt seem that maniacal really...Try without using any bombs :P That way you can't stay in the same place and just hold 2nd :)
I smell a feature...Really because I smell bacon.
I think Iambian will need to get rid of the word "Demo" in his title to get a feature though, because from what I remember ticalc.org no longer feature programs that are not finished :(True, but I remember that 2003 Joes Phatom star did (might have been the last one)
wel ticalc only recently started doing otherwise, like, a year after Wizards came outI think Iambian will need to get rid of the word "Demo" in his title to get a feature though, because from what I remember ticalc.org no longer feature programs that are not finished :(True, but I remember that 2003 Joes Phatom star did (might have been the last one)
Phatom Star (http://www.ticalc.org/archives/files/fileinfo/260/26096.html)
Also, be on the lookout for a new topic related to the game.Why? 11 pages isn't that much to sort through :D
Nice ;D So the new demo will have a bit of the story?QuoteAlso, be on the lookout for a new topic related to the game.Why? 11 pages isn't that much to sort through :D
Game size-wise, what's the current planned size so far?I think two flash pages, so ~32kB.
mhmmI remember putting Bubble Bobble's appvar into a group a long time ago so I could essentially have a loadable save state. :P (Last boss battle was epically hard.)
I wonder if there is a way to rename APPVars? Such program could be useful if for example I wanted to keep multiple replays in my calc archive to watch later
Sorta same old effect, except that I got the line routine to work now with a few additional tricks.This is an eye candy or a shooter game?
http://www.mediafire.com/imageview.php?quickkey=nvgzjgxhhem&thumb=4
I personally would rather see as much memory as possible given to the game engine and main engine if thats where it fits in. Seems to be that the slowness will not be so slow its unbearable and that by having that extra space we can make the game look better / sqeeze in more contentEhh. That's not quite what I meant. The point's null anyway. I'm not going to prebuffer the menu frames themselves, but the image files *will* be buffered. To help make the buffering scheme a bit clearer, I'll let some of the source do the talking :)
;VARIABLE EQUATES FOR ROUTINES LOCATED AT $9D95
ramseg1 = $9D95 ;0107b Common routines for multipage app management
ramseg2 = $9E00 ;0256b Common data resource tables
ramseg3 = $9F00 ;2048b | Menu data buffer | Stg background buffer |
ramseg4 = $A700 ;1024b |Menu system img buffer | Second bullet table |
ramseg5 = $AB00 ;0512b |Menu system img buffer | Spellcard background |
ramseg6 = $AD00 ;4096b |Menu system img buffer |Script resource buffer |
ramsegend = $BD00 ;8043t
The game field and the menu system are exclusive, therefore, can overlap perfectly. The menu data itself shouldn't be more than 2KB and the image data, no more than 4KB.I just wanna be able to do things right this time around.
The menu's look great, but on all of the screenshots i see only the menu's. How is the game itself going?The actual game play has not yet been recoded. I want to verify that all the data that is being passed to the main game engine is accurate given the selections from the menus that is depicted on the screen shots.
The prior script system could not be used since it was broken beyond repair.
Well, as long as you don't end up in perpetual rewrite hell, I support this completely. Looking forward to progress -- good luck!
Script system outline:
Internal notes:
Warning: Do not use the following for names of a script system command
"db", "dw", "end", "org", "byte", "word", "fill", "block", "addinstr",
"echo", "error", "list", "nolist", "equ", "show", "option", "seek"
These are reserved by SPASM
Naming conventions:
rx = virtual register 0-7
nn = 1 byte value
ww = 2 byte value
b = Some value between 0-7
s = Some value between 0-15
Some names will have a more descriptive label for its use. If one is used,
read the description to determine the data's size.
VERY IMPORTANT NOTE: ALL SCRIPT NAMES HAVE A PERIOD (.) PRECEDING THE NAMES
EVEN THOUGH THEY DO NOT SHOW IN THIS LIST. ALWAYS REMEMBER.
COMMANDSET AND NAME
==============================================================================
------------------------------------------------------------------------------
- NORMAL EVERYDAY USE --------------------------------------------------------
------------------------------------------------------------------------------
000 | No operation. The script system halts on encountering this.
NOP | Used for filler or something.
------------------------------------------------------------------------------
001-008 | LOAD(rx,nn)
LOAD | Stores a constant (1 byte) into a register.
2 bytes |
------------------------------------------------------------------------------
009-016 | ADD(rx,nn)
ADD | Adds a constant (1 byte) with a register, then stores the
2 bytes | results back to the register. Affects zero and carry flags.
| There's no subtract operand for this mode. Use a negative
| constant for doing that. There is no add with carry.
------------------------------------------------------------------------------
017-024 | CLEAR(rx)
CLEAR | Sets a register to zero.
1 byte |
------------------------------------------------------------------------------
025-032 | AND(rx,nn)
AND | Do a bitwise AND operation between a register and a constant
2 bytes | and store the result back into the register.
| Affects the zero flag. Does not affect the carry flag.
------------------------------------------------------------------------------
033-040 | XOR(rx,nn)
XOR | Do a bitwise XOR operation between a register and a constant
2 bytes | and store the result back into the register.
| Affects the zero flag. Does not affect the carry flag.
------------------------------------------------------------------------------
041-048 | OR(rx,nn)
OR | Do a bitwise OR operation between a register and a constant
2 bytes | and store the result back into the register.
| Affects the zero flag. Does not affect the carry flag.
------------------------------------------------------------------------------
049-056 | CPL(rx)
CPL | Inverts all bits in a register.
1 byte | Affects the zero flag.
| If you want to do NEG instead, just CPL, then INC it.
------------------------------------------------------------------------------
057-064 | WAIT(rx)
WAIT | Makes the script system wait for the number of game cycles
1 byte | that is stored in a register. Remember that 24 cycles is
| about one second's worth of time in normal gameplay mode.
| You should be setting that register to some known value
| before using this instruction. Feeding in 0 is using 256.
------------------------------------------------------------------------------
065-072 | CMP(rx,nn)
CMP | Performs subtraction between a register and a constant in
2 bytes | the form: register-constant. The result is NOT stored back,
| but instead, used to affect the zero and carry flags.
| Good for use with conditional jumps.
------------------------------------------------------------------------------
073-080 | TEST(rx,nn)
TEST | Performs a bitwise AND operation between a register and a
2 bytes | constant, but does NOT store the results back to the
| register. Instead, it's used to affect the zero flag.
| Used when you need to figure out which bits are set in a
| register, perhaps for conditional jumps?
------------------------------------------------------------------------------
081-088 | TRACK(rx)
TRACK | Output-only. Sets the given register to an angle that would,
1 byte | when used with the SHOOT command, fire a bullet directly
| toward the player.
------------------------------------------------------------------------------
089-096 | SHOOT(rx)
SHOOT | Fires a shot at the angle given in a register. 'nuff said.
1 byte |
------------------------------------------------------------------------------
097-104 | SETSTATS(rx,nn)
SETSTATS | Stores rx to an external variable. If you need to define
2 bytes | your own variables, look in the code developer's guide for
| more information.
------------------------------------------------------------------------------
105-112 | GETSTATS(rx,nn)
GETSTATS | Retrieves rx from an external variable. Again, if you need
2 bytes | to define your own variables, look in the code developer's
| guide for more information.
------------------------------------------------------------------------------
113-120 | MULT(rx,nn)
MULT | Multiplies a register by a constant, then stores the least
2 bytes | significant byte (LSB) of the result back into the register.
| NOTE: If it's possible, try to use the rotate/shift
| commands if you're dividing or multiplying by
| multiples of 2. It's much friendlier that way.
| The most significant byte (MSB) is stored in "sta.overflow"
| be accessed by the getstats command. Flags are affected as
| follows: Carry is set if the MSB is not zero. Zero is set if
| the result in the LSB was zero (even if the whole isn't)
------------------------------------------------------------------------------
121-128 | DIVIDE(rx,nn)
DIVIDE | Dividend (rx) / Divisor (nn) -> Quotient to (rx)
2 bytes | This is a slow operation. See if you can't use right shifts
| instead.
| The remainder is stored in "sta.overflow", which is accessed
| via getstats command. Flags are affected as follows:
| Carry is set if there is a remainder. Zero is set if the
| quotient is zero (does not check remainder).
|
------------------------------------------------------------------------------
129-136 | INC(rx)
INC | Increments rx by one. Same as ADD(rx,1) but much faster and
1 byte | uses less memory. Affects only the zero flag, to remain
| consistent with how the Z80 does things.
------------------------------------------------------------------------------
137-144 | DEC(rx)
DEC | Decrements rx by one. Same as ADD(rx,-1) but much faster and
1 byte | uses less memory. Affects only the zero flag, to remain
| consistent with how the Z80 does things.
------------------------------------------------------------------------------
145-152 | DJNZ(rx,label)
DJNZ | Automatically decrements the given register and takes the
2 bytes | specified relative jump while the register does not become
| zero that cycle. Just like Z80's djnz instruction, except
| you can use any register.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
153 | MOVE(rxa,rxb)
MOVE | Copies the contents of register B over to register A.
2 bytes | Register A is overwritten with B and B stays the same.
------------------------------------------------------------------------------
154 | SWAP(rxa,rxb)
SWAP | The values in register A and register B are swapped.
2 bytes | Nothing is destroyed in this operation.
------------------------------------------------------------------------------
155 | ADDRX(rxa,rxb)
ADDRX | Adds register A and register B, then stores the result
2 bytes | back into register A. Affects only the carry flag.
------------------------------------------------------------------------------
156 | SUBRX(rxa,rxb)
SUBRX | Subtracts register B from register A in the form of
2 bytes | rxa-rxb, then stores the result back into register A.
| Affects
|
|
------------------------------------------------------------------------------
157 | ROTR(rx,b) / ROTL(rx,b)
ROTR/ROTL | Rotates a given register a number of bits right or left
2 bytes | (respectively). All bits that leave one side of the register
| Immediately appears on the other side of the register.
| Flags are NOT affected.
| INTERNAL NOTE: Distinguishing between ROTR and ROTL is done
| with bit 7 of the data byte. (1=ROTL)
------------------------------------------------------------------------------
158 | SHIFTR(rx,b) / SHIFTL(rx,b)
SHIFTR/SHIFTL | Shifts a given register a number of bits right or left
2 bytes | (respectively. All bits that leave are gone forever. Bits
| shifted in will always be zero.
| Flags are NOT affected.
| INTERNAL NOTE: Distinguishing between ROTR and ROTL is done
| with bit 7 of the data byte. (1=SHIFTL)
------------------------------------------------------------------------------
159 | MULTRX(rxa,rxb)
MULTRX | Multiplies register A with register B, then stores the
2 bytes | LSB of the result back to register A.
------------------------------------------------------------------------------
160 | DIVIDERX(rxa,rxb)
DIVIDERX | Divides register A with register B in the form of rxa/rxb,
2 bytes | then stores the quotient to register A.
------------------------------------------------------------------------------
161 | ANDRX(rxa,rxb)
ANDRX | Performs the bitwise AND function between register A and
2 bytes | register B, then stores the result to register A. Affects
| the zero flag.
------------------------------------------------------------------------------
162 | ORRX(rxa,rxb)
ORRX | Performs the bitwise OR function between register A and
2 bytes | register B, then stores the result to register A. Affects
| the zero flag.
------------------------------------------------------------------------------
163 | XORX(rxa,rxb)
XORRX | Performs the bitwise XOR function between register A and
2 bytes | register B, then stores the result to register A. Affects
| the zero flag.
------------------------------------------------------------------------------
164 | CMPRX(rxa,rxb)
CMPRX | Performs virtual subtraction between register A and register
2 bytes | B. Does NOT store the result anywhere, but the carry and
| zero flags are affected as though subtraction took place.
| Useful for testing conditions.
------------------------------------------------------------------------------
165 | TEXTRX(rxa,rxb)
TESTRX | Performs a virtual AND function between register A and
2 bytes | register B. Does NOT store the result anywhere, but the
| zero flag is affected as though an AND function was done.
| Useful for testing bits to see if they're set.
------------------------------------------------------------------------------
166 | JUMPNC(label) [+ or - 127 bytes in either direction]
JUMPNC | Sets the script's execution pointer to wherever you defined
2 bytes | the label only if the result of flag altering command prior
| to this instruction stayed between 0 and 255 (carry flag
| reset)
------------------------------------------------------------------------------
167 | JUMPC(label) [+ or - 127 bytes in either direction]
JUMPC | Sets the script's execution pointer to wherever you defined
2 bytes | the label only if the result of flag altering command prior
| to this instruction crossed zero. (Carry flag set)
------------------------------------------------------------------------------
168 | JUMPNZ(label) [+ or - 127 bytes in either direction]
JUMPNZ | Sets the script's execution pointer to wherever you defined
2 bytes | the label only if the result of flag altering command prior
| to this instruction was NOT zero. (Zero flag reset)
------------------------------------------------------------------------------
169 | JUMPZ(label) [+ or - 127 bytes in either direction]
JUMPZ | Sets the script's execution pointer to wherever you defined
2 bytes | the label only if the result of flag altering command prior
| to this instruction was zero. (Zero flag set)
------------------------------------------------------------------------------
170 | JUMP(label) [+ or - 127 bytes in either direction]
JUMP | Unconditionally sets the script's execution pointer to
2 bytes | wherever the label is defined. Just like Z80's JR.
------------------------------------------------------------------------------
171 | NEWPOSRT(rx_angle,rx_radius)
NEWPOSRT | Changes the firing position from the center of the enemy to
3 bytes | radius away from that center at some angle, both of which
| are stored in registers. ANGLE is between 0 and 255, and
| RADIUS can be anything, just note that 90 is the length of
| the longest possible line on the screen. Keep that in mind
| so you don't clip.
| NOTE: Position is reset to center after a pause, or another
| use of the NEWPOSRT command.
------------------------------------------------------------------------------
172 | NEWPOSXY(rx_x,rx_y)
NEWPOSXY | Changes the firing position from the center of the enemy to
3 bytes | some offset X,Y away from the enemy. You MUST understand
| that Y is reversed (positive values move down, negative
| moves upward). To obtain negative values of a certain number
| you should CPL/INC it. Or store a negative number to the
| register to begin with. The screen is 64 by 64 pixels.
| NOTE: Position is reset to center after a pause, or another
| use of the NEWPOSRT command.
------------------------------------------------------------------------------
173 | USESPRITE(rx_resourceID,rx_locationID)
SETSPRITE | Sets a sprite found in resourceID to an active enemy sprite
3 bytes | found in locationID. resourceID refers to a place on the
| current script's resource table, which should be set at
| "codegen"-time. locationID refers to a number 0-3, which
| refers to which sprite slot to use (there are four).
------------------------------------------------------------------------------
174 | JUMPTABLE(rx_offset,nn_table_length) \.db label1,label2,...
JUMPTABLE | Allows you branch to different routines depending on what
3+n bytes | is in a register. You MUST put the table immediately after
| this instruction. Example:
|
| LOAD(r1,0) ;sets r1 to zero
| JUMPTABLE(r1,4) ;r1 is the offset, 4 is the number of labels
| .db Label_0 ;<-- Will be chosen, since it's the 0th one.
| .db Label_1 ;Next label. If r1=1, then this is taken.
| .db Label_2 ;Same, except if r1=2...
| .db Label_3 ;And again... If r1=3...
|
| Note: If r1 is a value outside the bounds, the table is
| skipped over and code beneath is will run.
| Note: The labels are relative addresses, + or - 127 bytes
| in either direction. This makes it prohibitive to use
| very large tables. If you need to make tables that
| large, use jump nodes as intermediaries.
| IMPORTANT NOTE: THE TABLE CANNOT BE LARGER THAN 16 LABELS!
| If you try to make it larger anyway, garden
| gnomes will (likely) invade your home.
| A typical use for this routine is retrieving the built-in
| difficulty level, and then branching to different attacks
| based on the difficulty, so one script does many things.
| See how *you* can abuse this sucker. I won't be stopping you
------------------------------------------------------------------------------
175 | CALL(ww_relativelabel)
CALL | Lets you run a subroutine so you can save precious space by
3 bytes | not having to replicate redudnant code. The spacing for this
| label is double-wide, so it can reach anywhere you need it
| to. DO NOT TRY TO CALL ANYTHING WHILE IN A SUBROUTINE.
| Endless loops and never getting back to the main code will
| result. It's safe this time around to do a PAUSE or a WAIT
| while you're in a subroutine, however. It's safe this time
| around to do a PAUSE/WAIT combination while in a subroutine.
------------------------------------------------------------------------------
176 | RETURN
RETURN | Exits a subroutine. Don't try to use this if you're not in
1 byte | a subroutine. Main script code all have exit points, and
| using this command is NOT one of them. You might end up
| crashing your calc or something.
------------------------------------------------------------------------------
177 | XYTORT(rxa_x,rxb_y,rxc_r,rxd_t)
XYTORT | Takes of the x,y coordinates found in registers A and B
3 bytes | (respectively), then uses the position given by the center
| of the enemy in use (or whereever newposxy/newposrt has
| changed it to) to output a distance and an angle in
| registers C and D, respectively.
------------------------------------------------------------------------------
178 | RTTOXY(rxa_r,rxb_t,rxc_x,rxd_y)
RTTOXY | Similar to above, except it takes a distance and an angle,
3 bytes | then converts it to its corresponding x,y coordinates,
| outputting to registers C and D, respectively.
| The starting position is the center of the enemy in use or
| wherever you changed it to via newposxy/newposrt.
|
------------------------------------------------------------------------------
179 | GETPLAYERXY(rxa_x,rxb_y)
GETPLAYERXY | Outputs the player's X,Y coordinates to registers A and B,
2 bytes | respectively. If you only need an angle, you should be using
| the TRACK command instead. Much faster that way.
I wanted to make sure it looked nice, but really, I just wanted to make sure that I have no dead test code sitting around like I did with the old CaDan.
StageScript:
.load(r1,128) ;starting angle
.load(r2,6) ;starting variable radius
.load(r4,5) ;counter for increment
.load(r5,1) ;toggle
.load(r6,10) ;delay between cycles. Also hardcoded in routine
StageScriptCont:
.load(r0,2) \ .wait(r0)
.newposrt(r1,r2) ;angle,radius
.add(r1,3)
.call(CustomMakeBullet)
.move(r3,r2)
.add(r3,3)
.newposrt(r1,r3)
.call(CustomMakeBullet)
.dec(r6)
.jumpnz(_) ;cycle delay
.load(r6,10)
.addrx(r2,r5) ;changing radius
.dec(r4)
.jumpnz(_)
.load(r4,5)
.cpl(r5)
.inc(r5)
_:
.setstats(r7,rs.debug1)
.jump(StageScriptCont)
CustomMakeBullet:
.runasm(_)
bit fbt1full,(iy+stateflags)
jr nz,SSSKIP
;Include and call ionRandom for varying bullet speeds when that test
;is about to be performed
ld c,$20
ld hl,freebullet1
ld e,(hl) ;1.READ
inc (hl) ;2.INC
ld d,$8C
ld a,(de)
ld (ix+7),a
jp p,$+7
set fbt1full,(iy+stateflags)
ld h,$88>>2
add a,a
ld L,a
add hl,hl
add hl,hl
xor a
ld (hl),CLSB(TestEBTShot)
inc L
ld (hl),CMSB(TestEBTShot)
inc L
ld (hl),c ;acc/TTL
inc L
ld (hl),b ;angle (allow to be uninitialized for now)
inc L
ld bc,(curpos) ;C=Y,B=X
ld (hl),a ;*.8 set to zero
inc L
ld (hl),c ;8.* X position
inc L
ld (hl),a ;*.8 also set to zero
inc L
ld (hl),b ;8.* Y position. Finished writing
SSSKIP:
jp r.runasm.ret
_:
.return
Wow I love how those bullets are moving around. It still looks smooth too.yeah it does look cool and they are only moving 1 direction down yay testing xD
for starters you documented or coded .newposxy (r.npxy in lib_script) and they are backwards x is y and y is x blah blah blah just pointing that out there :P
How do you get through these lines of bullets without getting hit??? O.O
[...]Quote from: geekboyfor starters you documented or coded .newposxy (r.npxy in lib_script) and they are backwards x is y and y is x blah blah blah just pointing that out there :P
StageScript:
.load(r1,-30) ;x
.load(r2,-30) ;y
.load(r3,30) ;loop range
.load(r4,1)
StgScptLoop:
.load(r7,2)
.wait(r7)
.newposxy(r1,r2)
.call(CustomMakeBullet)
.cpl(r1)
.inc(r1)
.newposxy(r1,r2)
.call(CustomMakeBullet)
.setstats(r0,rs.debug1)
.cpl(r1)
.inc(r1)
.addrx(r1,r4)
.dec(r3)
.jumpnz(_)
.load(r3,30)
.cpl(r4)
.inc(r4)
_:
.jump(StgScptLoop)
the last demo is from 2009 can we have a current demo? the screenshot is amazing!!!!!!!
that is ok I can wait as long as it is realesed by 2099 :P
Well, if we keep up this progress, we might have a three stage demo out by Christmas of this year. But what I'm really hoping for is a shot at this year's POTY so we're gonna try to get this thing rolling ASAP. Because there's all these 2012 things that the world's gonna end, so I might not get another chance at a POTY.Woo :D Can't wait :)
Erh. Apocalypse aside, I'm gonna see how fast I can get a *real* demo out.
We can probably put in a Duck Hunt mode. (j/k)*DualBLDR hyperventilates and then stops as soon as he reads JK...
But seriously, with how advanced the script system is going to be, we might add in a Tetris mode just to see how far we can take the idea.
Currently on the task list is putting in actual radially moving bullets. If I can get that done tonight, I might ask Geekboy pull together a (few) script(s) to demonstrate it.
We can probably put in a Duck Hunt mode. (j/k)*DualBLDR hyperventilates and then stops as soon as he reads JK...
But seriously, with how advanced the script system is going to be, we might add in a Tetris mode just to see how far we can take the idea.
Currently on the task list is putting in actual radially moving bullets. If I can get that done tonight, I might ask Geekboy pull together a (few) script(s) to demonstrate it.
Tetris mode? O.O
Can you explain, or does it mean like the enemies fall down like the tetris blocks and u hav to shoot them down?
Like that game Bubble Busters(?)
please post a screenie with all the characters you can useI think cemetech have some characters in screenshot
;Automagically clips x bounds. Idea given by calc84maniac
DrawClippedSprite: ;D=X E=Y A=spriteID. Allows negative numbers to an extent.
;screen dimensions are 64x64 pixels
rrca
rrca ;%11000000 get
ld c,a ;A is saved into C. Now let's start doing display sanity checks.
ld hl,$F940 ;H=-7 (carry=oob), L=64 (nocarry=oob)
ld a,d
cp L
jr c,_ ;skip further checking. We are in bounds
cp H
ret c ;kill routine if the sprite can't be displayed.
_:
ld a,e
cp L
jr c,_ ;same deal as above, since max width and height are the same as in X
cp H
ret c
_: ;if we reach here, sanity has been checked. Sprite is displayable.
ld L,c ;sprite ID selector in L for now, since C is being overwritten
ld bc,$0800 ;B=loop counter, C=offset modifier
ld a,e ;getting Y position.
cp 57 ;checking to see if is on either right or left edge
jr c,DrawClippedSpriteSkipYClip
jp m,_ ;jumping if result is still negative (top side clipping)
;Bottom-side clipping
;57=7, 58=6 59=5 60=4 61=3 62=2 63=1. Just limit loop counter.
cpl ;-58 -59 -60 -61 -62 -63 -64
add a,65 ;7 6 5 4 3 2 1
ld b,a ;new loop counter established
jp DrawClippedSpriteSkipYClip
_: ;This is the top-side clipping routine
;IN:CNT:OFFSET -1:7:1 -2:6:2 -3:5:3 -4:4:4 -5:3:5 -6:2:6 -7:1:6 NDS:NDS:NDS
neg
ld c,a ;offset established. Already? Wow.
cpl ;-2:7 -3:6 -4:5 -5:4 -6:3 -7:2 -8:1
add a,9 ;Yes.
ld b,a ;Loop counter achieved.
ld e,0 ;set new Y position at 0 to allow proper clipping
DrawClippedSpriteSkipYClip:
push bc ;save loop counter, RCL by pop af. Use C offset soon.
ld a,d ;now, let's start processing these coordinates, shall we?
and %00000111
ld b,a ;save for getting mask address
add a,a
add a,a
add a,a ;x8 %00111000
add a,L ;merge to get correct sprite position
add a,c ;add sprite offset for Y clipping
ld c,a ;position saved
ld a,b
add a,8 ;getting spritemask position
ld h,$40
ld L,a
ld b,(hl) ;B=spritemask
;At this point, C=spritepostionLSB, B=mask DE=XY,
ld L,e ;y
ld h,0
add hl,hl
add hl,hl
add hl,hl
ld e,c ;sprite positioner. C is free'd up, using E as LSB to complete addr
ld a,b ;mask (left side AND)
cpl ;invert it
ld c,a ;mask (right side AND)
ld a,d ;check x position for clippage.
cp 57 ;Check to see if X needs to be clipped
jr c,DrawClippedSpriteSkipXClip
jp m,_ ;If still negative, then jump to left side clippage.
;Right side clipping.
ld a,7 ;manually set to right side of screen
ld b,0 ;manually clear right side mask to avoid showing sprite on left
jp DrawClippedSpriteManualSetX
_:
ld c,0 ;manually clearing left side mask to avoid showing sprite on right
dec hl
bit 7,h ;checking to see if HL went negative
jr z,DrawClippedSpriteManualSetHL
ld hl,$7FFF ;handling corner case where clipping at top-left edge
jp DrawClippedSpriteManualSetEdge ;It's a freaking literal corner!
DrawClippedSpriteSkipXClip:
rrca
rrca
rrca
and %00000111
DrawClippedSpriteManualSetX:
add a,L
ld L,a
DrawClippedSpriteManualSetHL:
set 7,h ;83cc
DrawClippedSpriteManualSetEdge:
ld d,$87 ;D=MSB of sprite position, E already is LSB. Address completed.
;So what we have so far is: C=LSMask, B=RSMask DE=sprAddr HL=scrnAddr
pop af ;A=loop counter we saved from so long ago.
ld (itemp2),sp
ld sp,7 ;SP = using in place of DE for advancing HL.
DrawClippedSpriteDrawLoop:
ex af,af'
ld a,(de) ;FINALLY. We are writing out that sprite in accordance to
and c ;all of our carefully laid out plans. Of course... plans
or (hl) ;tend to never survive initial contact. Oh, well. That's
ld (hl),a ;what the debugging phase is for.
inc hl
ld a,(de)
and b ;These comments have nothing to do with this particular stretch
or (hl) ;of code. Instead, I'm using this area to chronicle the debug
ld (hl),a ;phase. (1) Incomplete sanity check. Forgot to set HL fully.
add hl,sp ;(2) Bad inputs and script system incompatibility. (itemp1)
inc e ;needed to be preserved, and characte X,Y had subpixel data that
ex af,af' ;I needed to get rid of. (3) Reversed masks. (4) Top-left corner
dec a ;case addressed. Debugger used to find the problem. All fixed.
jr nz,DrawClippedSpriteDrawLoop
ld sp,(itemp2)
ret ;If your scale color is red, you're in good claws.
StageScript:
.load(r1,-30) ;x
.load(r2,-30) ;y
.load(r3,30) ;loop range
.load(r4,1)
StgScptLoop:
.call(TestSpriteRoutine)
.load(r7,2)
.wait(r7)
.newposxy(r1,r2)
.call(CustomMakeBullet)
.cpl(r1)
.inc(r1)
.newposxy(r1,r2)
.call(CustomMakeBullet)
.setstats(r0,rs.debug1)
.cpl(r1)
.inc(r1)
.addrx(r1,r4)
.dec(r3)
.jumpnz(_)
.load(r3,30)
.cpl(r4)
.inc(r4)
_:
.jump(StgScptLoop)
CustomMakeBullet:
.runasm(_)
bit fbt1full,(iy+stateflags)
jr nz,SSSKIP
;Include and call ionRandom for varying bullet speeds when that test
;is about to be performed
ld c,%10000011
ld hl,freebullet1
ld e,(hl) ;1.READ
inc (hl) ;2.INC
ld d,$8C
ld a,(de)
jp p,$+7
set fbt1full,(iy+stateflags)
ld h,$88>>2
add a,a
ld L,a
add hl,hl
add hl,hl
xor a
ld (hl),CLSB(TestEBTShot)
inc L
ld (hl),CMSB(TestEBTShot)
inc L
ld (hl),c ;acc/TTL
inc L
ld (hl),b ;angle (allow to be uninitialized for now)
inc L
ld bc,(curpos) ;C=Y,B=X
ld (hl),a ;*.8 set to zero
inc L
ld (hl),b ;8.* X position
inc L
ld (hl),a ;*.8 also set to zero
inc L
ld (hl),c ;8.* Y position. Finished writing
SSSKIP:
ld a,(characterID)
ld (ix+0),a
jp r.runasm.ret
_:
.return
TestSpriteRoutine: ;so ruinous. Just total hell is about to be unleashed.
.runasm(_)
ld de,(chary)
srl e
srl e
srl d
srl d
ld a,-10 \ call TestSpriteRoutineAddToY ;up above
ld a,-10 \ call TestSpriteRoutineAddToX ;top-left
ld a,10 \ call TestSpriteRoutineAddToY ;left
ld a,10 \ call TestSpriteRoutineAddToY ;bottom-left
ld a,10 \ call TestSpriteRoutineAddToX ;bottom
ld a,10 \ call TestSpriteRoutineAddToX ;bottom-right
ld a,-10 \ call TestSpriteRoutineAddToY ;right
ld a,-10 \ call TestSpriteRoutineAddToY ;top-right
jp r.runasm.ret
TestSpriteRoutineAddToY:
add a,e
ld e,a
push de
xor a
call DrawClippedSprite
pop de
ret
TestSpriteRoutineAddToX:
add a,d
ld d,a
push de
xor a
call DrawClippedSprite
pop de
ret
_:
.return
Yes, I *am* aware that there's way more Z80 ASM code than there is CaDan script code. See, the stage script became mine and Geekboy's best friend. A great way to test out assembly code.Comatose basically means lying on the floor, going into a coma
This time around, I got bullet tracking working. Couple with the fact that the angle values are interpolated to give a better shot AND that I've increased the number of angles in a circle to 256, these things are deadly-accurate. Long gone are the days where you can find a safe spot by taking advantage of the system's inaccuracies.
Even the non-interpolated version (which will appear in bullet engine as a bullet script) is fairly accurate. You don't want to be messing with this stuff!
So in hcwp last night iambian taught me how to use the sin cosine tables
well i think they work but i messed up my logic for shooting bullets so we got this instead
Clipped to save bandwidth
(NOTE this is not a real script :P though it would kill everything pretty nicely >.> <.<)
So in hcwp last night iambian taught me how to use the sin cosine tables
well i think they work but i messed up my logic for shooting bullets so we got this instead
(http://cadan.57o9.org/Screenshots/FAILFAIL.gif)
(NOTE this is not a real script :P though it would kill everything pretty nicely >.> <.<)
Aww, look! It's the cute Iambian shooting fire with his cyoot dragon breath. Who's a cute little dragon? You are. </Cooing>^_^ *happehfaic*
It looks awesome! Major props to you guys; I realize that it was really to code, but it looks amazing. Excellent work!
Did someone say something about replays? What'll that do?
Replays are keystroke recordings that form up a movie of what you have done that game session. If you had a particularly awesome run but forgot to turn on the record feature of Wabbitemu, or if you're out on the road playing on a real TI-83 Plus, you can save what you did and have an automatic replay of it so you can show your friends how awesome you are.That is really frikin' tight. How many can you you have saved at once?
After all. Vids or it didn't happen.
However much memory you have. I figure that a single stage will eat up anywhere around 8 to 12KB apiece, depending on how much you mash the buttons and how long the stage is.[...]That is really frikin' tight. How many can you you have saved at once?
Mega thanks to iambian for getting that working was giving me a headache.
Anyway.
I Took what he had and changed some stuff around mostly making it use our PRNG routines so that we can rely on the fire spread in replays. I also made it feel a bit more natural by using the same PRNG output to limit the bullets travel time in a seemingly random fashion like fire :P
(http://cadan.57o9.org/Screenshots/FIREFIRE.gif)
(note ignore the scoreboard i did not enable hex mode like Iambian so its all giberished :P)
Aww, look! It's the cute Iambian shooting fire with his cyoot dragon breath. Who's a cute little dragon? You are. </Cooing>^_^ *happehfaic*
It looks awesome! Major props to you guys; I realize that it was really to code, but it looks amazing. Excellent work!
Did someone say something about replays? What'll that do?
</nonproductivepost>
Replays are keystroke recordings that form up a movie of what you have done that game session. If you had a particularly awesome run but forgot to turn on the record feature of Wabbitemu, or if you're out on the road playing on a real TI-83 Plus, you can save what you did and have an automatic replay of it so you can show your friends how awesome you are.
After all. Vids or it didn't happen.
Wow, that would be awesome O.O Is it okay if I use that replay feature in some of my programs if I ever feel up to it? That would be lovely for walk throughs and help features for games !
Replays sound pretty cool.Does it store the key, and then how long it was pressed, or does it store whatever key is pressed each time through?it stores what keys are pressed every game cycle then uses a modified RLE scheme to compress them on the fly. well thats the intent at least. to my knowledge not a lick of it has been coded. other important behind the scenes things to work on >.<
(http://www.omnimaga.org/index.php?action=dlattach;topic=40.0;attach=10044;image)0.o
This is a little late, but...Quote from: http://ourl.ca/2637/255828(http://www.omnimaga.org/index.php?action=dlattach;topic=40.0;attach=10044;image)0.o
What's the theory behind that? I've been trying to get aiming like that working since something like January...
he does some crazy fucking shit with it though to get it to be that accurate though...And this is why we love him.
This is a little late, but...Quote from: http://ourl.ca/2637/255828(http://www.omnimaga.org/index.php?action=dlattach;topic=40.0;attach=10044;image)0.o
What's the theory behind that? I've been trying to get aiming like that working since something like January...
ArcTanTable:
.db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 ;|00 00|
.db 64,32,19,13,10,08,07,06,05,05,04,04,03,03,03,03 ;|01 04|
.db 64,45,32,24,19,16,13,11,10,09,08,07,07,06,06,05 ;|02 08|
.db 64,51,40,32,26,22,19,16,15,13,12,11,10,09,09,08 ;|03 12|
.db 64,54,45,38,32,27,24,21,19,17,16,14,13,12,11,11 ;|04 16|
.db 64,56,48,42,37,32,28,25,23,21,19,17,16,15,14,13 ;|05 20|
.db 64,57,51,45,40,36,32,29,26,24,22,20,19,18,16,16 ;|06 24|
.db 64,58,53,48,43,39,35,32,29,27,25,23,22,20,19,18 ;|07 28|
.db 64,59,54,49,45,41,38,35,32,30,27,26,24,22,21,20 ;|08 32|
.db 64,59,55,51,47,43,40,37,34,32,30,28,26,25,23,22 ;|09 36|
.db 64,60,56,52,48,45,42,39,37,34,32,30,28,27,25,24 ;|10 40|
.db 64,60,57,53,50,47,44,41,38,36,34,32,30,29,27,26 ;|11 44|
.db 64,61,57,54,51,48,45,42,40,38,36,34,32,30,29,27 ;|12 48|
.db 64,61,58,55,52,49,46,44,42,39,37,35,34,32,30,29 ;|13 52|
.db 64,61,58,55,53,50,48,45,43,41,39,37,35,34,32,31 ;|14 56|
.db 64,61,59,56,53,51,48,46,44,42,40,38,37,35,33,32 ;|15 60|
;Warning: Loads and loads of register-juggling ahead.
r.arctan: ;in: HL=(x1,y1) DE=(x2,y2)
ld b,0 ;initializing...
ld a,e ;
rrca \ rrca \ and %00111111
sub L ;y1-y2
jr nc,_ ;result is negative. Set B for flags (bit 0) and adjust Y for pos.
set 0,b
neg
_:
ld e,a ;D=Y for later
rlca \ rlca ;shifting so that %00yyyynn is %yyyynn00 for later. n matters not
ld L,a ;half-result in L now
ld a,d
rrca \ rrca \ and %00111111
sub H ;x1-x2
jr nc,_ ;result is negative. Set B for flags (bit 1) and adjust X for pos.
set 1,b
neg
_:
ld c,a ;C=X for results later
rrca \ rrca ;shifting so that %00xxxxnn is %nn00xxxx. n still matters not.
xor L ;combine with Y
and $0F ;mask out to keep old X low bits
xor L ;and we have %yyyyxxxx
ld L,b ;saving flags into L for now.
ld h,e ;restore H for... stuffs
ld ix,ArcTanTable
ld e,a
ld d,0
add ix,de ;We have our offset now.
;So at this point, C=X, H=Y, L=flags.
;Let's go ahead and do X-interpolation first.
ld a,c
and %00000011 ;value-ranking
ld c,(ix+0) ;storing non-adjusted "output" value into C
jr z,r.arctan.skipx
ld e,a ;Loop for second half of X interpolate
cpl ;ranking first value on inverse of distance to next number
add a,5 ;So 1=3,2=2,3=1
ld b,a
xor a
_:
add a,c
djnz -_
ld c,(ix+1)
ld b,e
_:
add a,c
djnz -_
rra \ rra
and %00111111
ld c,a ;out by the time we're done with everything.
r.arctan.skipx:
ld a,h
ld H,c ;H=InterpolatedX
and %00000011 ;value-ranking
ld c,(ix+0) ;storing non-adjusted "output" value into C
jr z,r.arctan.skipy
ld e,a ;Loop for second half of Y interpolate
cpl ;ranking first value on inverse of distance to next number
add a,5 ;So 1=3,2=2,3=1
ld b,a
xor a
_:
add a,c
djnz -_
ld c,(ix+16)
ld b,e
_:
add a,c
djnz -_
rra \ rra ;Also trying to get any leftovers from too many values of 64
cp 64
jr z,_
and %00111111
_:
ld c,a ;added. Since 64*4 is a 9 bit number, getting that back.
r.arctan.skipy:
ld a,c
add a,H
rra
cp 64
jr z,_
and %00111111 ;and NOW we have our final angle. (if it wasn't 64...)
_:
ld b,0 ;Set to 128 if X is negative. For additions later on.
bit 1,L
jr z,_
ld b,128
neg ;negate angle
_:
bit 0,L
jr z,_
neg ;negate angle again if (-,-) else first neg. Still correct :)
_:
add a,b ;completing the angle
ld c,a ;saving the completed angle to C
ret
Does that lowercase "t" have an extra pixel?Yes. That was intentional and is part of the font.
(http://img.removedfromgame.com/imgs/CaDan47.gif)
I don't think you need a cursor to go through the letters. If you choose a letter, the cursor automatically jumps one to the right. Like in most name input screen in Gameboy games or like this: http://img.photobucket.com/albums/v626/bublnsqeek/tutorials/nameinput.gif :) .I would prefer a cursor in the name, especially since the name input screen will be automatically filled out with the name you used the last time (Or "Nameless" if you're starting fresh with a new install). If something is already in the field, it might take more thought than strictly necessary to figure out where you are.