0 Members and 2 Guests are viewing this topic.
please post a screenie with all the characters you can use
;Automagically clips x bounds. Idea given by calc84maniacDrawClippedSprite: ;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 clippingDrawClippedSpriteSkipYClip: 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 %00000111DrawClippedSpriteManualSetX: add a,L ld L,aDrawClippedSpriteManualSetHL: set 7,h ;83ccDrawClippedSpriteManualSetEdge: 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 writingSSSKIP: 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.retTestSpriteRoutineAddToY: add a,e ld e,a push de xor a call DrawClippedSprite pop de retTestSpriteRoutineAddToX: add a,d ld d,a push de xor a call DrawClippedSprite pop de ret_: .return