LATEST 'N' NOT-SO-GREATEST version of the Elevator Repairman knockoff:
The sprites is all screwed up because I rewrote part of the kernel and didn't have time to fix the variable setup routines. The kernel works fine; the variables just aren't being setup properly. But that's no big deal.
Oh yeah, I also took out a bunch of stuff (score, 48-char display, etc.) that was using RAM - I needed the RAM and I didn't want to waste time optimizing when the kernel is still in flux, so I just deleted all that stuff.
These are bigger deals: at the suggestion of supercat, I sunk a ton of RAM into making the elevators solid.
RAM is pretty tight now, but it should be manageable.
However, as I mentioned in the comments to the previous post, the routine that sets up all that RAM for the elevators takes a looooooong time. It took about 65 scanlines but I optimized it (and fixed some bugs) last night so now it takes about 48 scanlines. So I could split it between the overscan and the vblank, but that's such an annoying pain that I'm hoping to come up with something faster.
[EDIT: I knew I could count on you guys! With the suggested optimizations the whole thing runs in about 33 scanlines now - long, but not too long. New binary and source:
The new routine is in the comments; this post is plenty long already.]
Here's the routine in question:
SetElevRAMSubroutine ;--new method: ;--Y position of elevators ranges from 0 to 80 ;--so: ; upon beginning this routine, ElevY will hold values pointing to the tops ; of the elevators ; -so first thing to do is to subtract ELEV_HEIGHT from each Y position ; so that ElevY holds the *bottom* of the elevators ; -after processing the bottom of the elevators, flag that we processed ; the bottom of that elevator (temp variables) and add ELEV_HEIGHT back to the ; the Y position so that it points to the top. ; -after processing the top of the elevators, ORA ElevY with 128 (set top bit) ; -when the lowest Y position (ElevY) is a negative number (top bit set) then we are done. ldx #6 InitializeElevYLoop lda ElevY,X sec sbc #ELEV_HEIGHT sta ElevY,X lda #0 sta Temp+2,X;clear flags also dex bpl InitializeElevYLoop ;--initialize the bottom band with zeroes lda #0 sta ElevRAM sta ElevRAM+14 sta ElevRAM+29 sta ElevRAM+44 sta ElevBandHeight ldy #0 SetElevRAMLoop jsr FindLowestPtSubroutine ;--now Temp holds lowest value ; and Temp+1 holds index into which elevator is the lowest lda Temp bmi AllDone cmp ElevBandHeight,Y beq SameBand ;--else: new band, so ; bring all values from old band into new band: sta ElevBandHeight+1,Y lda ElevRAM,Y sta ElevRAM+1,Y lda ElevRAM+14,Y sta ElevRAM+15,Y lda ElevRAM+29,Y sta ElevRAM+30,Y lda ElevRAM+44,Y sta ElevRAM+45,Y iny SameBand ldx Temp+1 lda ElevPtrTableLo,X sta MiscPtr lda (MiscPtr),Y eor ElevFlipTable,X sta (MiscPtr),Y lda Temp+2,X ;flags that determine top or bottom of elev eor #$FF sta Temp+2,X bne JustProcessedElevBottom ;--else that was the top lda ElevY,X ora #$80 sta ElevY,X bne SetElevRAMLoop;branch always JustProcessedElevBottom ;--that was the bottom, now set it for the top lda ElevY,X clc adc #ELEV_HEIGHT sta ElevY,X bne SetElevRAMLoop;branch always AllDone ;--now we have to deal with situation where the highest ; elevator(s) is at the top line lda ElevBandHeight,Y cmp #80 bne NoElevAtVeryTop dey NoElevAtVeryTop sty Temp+2 ;save this value for later rts ;---------------------------------------------------------------------------- FindLowestPtSubroutine lda #255 sta Temp ldx #6 stx Temp+1 FindLowestPtLoop lda ElevY,X cmp Temp bcs NotLowestPt sta Temp stx Temp+1 NotLowestPt dex bpl FindLowestPtLoop ;--Temp+1 holds index into lowest elevator ; Temp holds the height of the low elevator rts
And here's the source if you want to see things with more context: