My good friend Alex and I were co-developing a computer game called "Super Merryo Trolls", and cutting apart other games in order to learn their programming secrets, using the computer equivalent of a forensics kit and lockpicks. One day at school he handed me a 3.5-inch disk with a demo on it, for a game called "Sword of Sodan".
"Hey, Bob," (we called each other, and several other friends, "bob" interchangeably) "Boot this up and watch it. Then hack the shit out of it, and tell me what you think."
That night I sent him this profanity-laced email:
Okay, bob, here's what I found after a ten-minute dissection of Sword of Sodan. These people did some really unhealthy things. First:
You thought PEI and PEA were the only memory-moving operations that didn't need a seperate load and store? You were wrong. Check this one out. These people set up things for a PEI, right?: set the direct page to $2500, set the write-flag to write to bank 1, LDA #00, PHA, PLB to set the bank, and then:
LDA #$0000 ... TSB 14 TSB 16 TSB 18 TSB 1A TSB 1C TSB 1E TSB 20 TSB 22 ...Has your ass exploded yet? Understand this:
The test and set bits command does a read AND THEN a write to the same location, all in one opcode. These people loaded in the value, set bits equivalent to $0000 (in effect, changing NOTHING) and then wrote the value back- back to bank 1, that is, thanks to the flag. Understand? They used TSB instead of PEI.
Now, this was pretty funky. For one thing, they never had to worry about the stack, because it wasn't involved. They could interrupt their GSes to hell and back with no ill effects. For another, they could have the direct page aligned. Tricky of them, keeping the stack uninvolved like that, right? WRONG.
This is why these people are idiots: What happens when you want to scroll?
The trouble with using a direct page TSB to move data from bank 0 to bank one is that it can only move from one exact place to another. Set your DP to $2500 and TSB $20, and you're gonna move from $002520 to $012520, whether you like it or not. "But, duh, gee, couldn't they just change the direct page setting when they wanted to scroll left or right?" No, because their destination in bank 1 would change right along with their source in bank 0. See why involving the stack is so important? Sure, they could do their updates from the top down, left to right, like the screen scans - but similar PEI code allows you to go from the top down, right to left, which is quite enough for syncing purposes unless you're an anal retentive fungus-brained dickweed dumbshit bastard.
Want to see how they "scrolled"? Well, first of all, they didn't have to worry about easing their sprites. Know why? Because they RE-DREW the WHOLE FUCKING BACKGROUND each time, like so:
pea 0303 plb plb ldx 04 (scroll value) lda $0000,x sta 14 lda $0002,x sta 16 lda $0004,x sta 18 lda $0006,x sta 1aSHIT!! SHIT!!! Why didn't they use PHA!? They're AFRAID of the stack, Alex!
It's true! They're in mortal peril from using the stack! If they used PHA to re-draw the background like this, they'd get naughty bits on the screen when an interrupt occured. It'd go at least >7000< cycles faster. My gosh, there has to be some sort of error-correction code we can append to your music player, to enable us to use the stack more often- because these people lived in sheer terror of it. And it cost them.
Try this: Boot up Sword of Sodan and watch the demo. Then boot up Trolls and play world 1-A. Our frame rate alone kicks their ass. ;)
Things revealed by the GA program:
- A cheezy 320 mode 8x8 italic-gothic font arranged in direct-to-screen format. You could rip it off if you wanted, but why bother. :P
- The two screens worth of background, arranged in memory in such a way that it is obvious that two screens was all they planned for. It's in $140 byte horizontal rows, one row after another vertically.
- Another screen of background that we never see in the demo version, with a repetitive fance and a G-rated statue of a female archer. Arranged in screen format- easy to find.
- Odd looking undulating patterns of code that can only be complied sprites, I'll look at this in a minute.
- Apparently, for these people, color 0 is black and color F is sunset-shaded sky followed by some 160 scanlines of drab dark green. The overlay color, perhaps? Nope. No overlays used, the sprites are compiled. Hmmm.
Oh no! Oh no, no, no! This is shit! Shit shit shit. The only redeeming quality is that their foreground field is in bank 0, allowing them direct page stores. Look at this, does it seem familiar?:
jmp 050044 ; No mystery here, a fucking jump table. jmp 051007 ; They can kiss any programming innovation jmp 051db3 ; awards goodbye. Why are these all LONG jumps? jmp 052b84 ; Oh, I see. The >last three< in the list go to jmp 054427 ; bank six instead. >:P jmp 055d2cat 05/0044:
phd ; Oh gosh, got to preserve everything- phb ; But after we jump to the sprite!??! pea 0101 ; I swear! This code is repeated before every sprite! plb ; Idiots, alex! Idiots!! plb txa ; Note: they set the bank to 1, but it's direct page so tcd ; it still goes to bank 0 clc lda #F0FF and 16 ora #0600 sta 16 ; These people are hardly blazing wonder bunnies. lda #0006 ; I would have used the stack for longer sprites: sta 18 ; LDA 16, and #, ora #, >PHA<. LDA 14, and #, ora #, >PHA<. lda #FF00 ; -But I'm just a stack-loving graphics asshole. and 1a sta 1a tdc adc #00a0 ; NOTE: This IS an adc #00a0! Realize that their window is tcd ; $80 wide! NOW do you see how they did their sprite lda #00f0 ; clipping? You could do the same on a PEA field, but you'd and 16 ; have to re-write a long string of identical 8-bit BRA values ora #6606 ; every time after drawing all your sprites for a particular sta 16 ; update. You may be able to use this idea in your game, ... ; Alex san: Another PEA field abuse, the cloned BRA for lda #2222 ; sprite-clipping. sta 20 lda #3422 sta 22 plb pld rtlAnd that's about it. Overall, I'm not very impressed. I didn't expect the TSB command, but it totally ruined their scrolling so I don't feel out-classed. :)
If the original developer of the Apple IIgs port of Sword of Sodan reads this, I apologize. But hey - at least you got paid, right?