Author Topic: Optimization help [A:P]  (Read 8505 times)

0 Members and 2 Guests are viewing this topic.

Offline squidgetx

  • Food.
  • Project Author
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1881
  • Rating: +503/-17
  • rawr.
    • View Profile
Optimization help [A:P]
« on: January 26, 2013, 10:59:48 pm »
If anyone wants to take a crack at optimizing any of these routines, I'd be very grateful ;D. I've gone over them a few times, but haven't been able to get too much out of 'em.
Custom Menu Routine
Code: [Select]
:Lbl CMen
.Creates a menu and returns the int index of the value chosen, returns -1 if canceled with Alpha
.r1-X, r2-Y, r3- NUM OPTIONS,r4 longest entry length, r5 pointer to string data for choices, broken by 0's
:0→F
:41→K
:r1→A
:r2→B
:r3→C*7+4→r6
:r4→D*4+10→r3
:r6→r4
:Box()   \\box drawing routine that takes similar arguments to Rect
:B+3→r2
:r5→E→r3
:For(C)
:¦ A+8→r1
:¦ CText()  \\custom text routine, same argument format as text().
:¦ r2+7→r2  \\r2 is untouched in the routine, the x coord at the end of the text drawn returns at r1
:¦ r3++
:End
:Text(B+2*256+A+4→A+4)
:While 1
:¦ !If +6
:¦ ReturnEFFFF
:End
:If K
:=1-(K=4)+F
:!If +1
:+1
:End
:min(-1,C-1)→F
:{E86D7}-4→{E86D7}
:DrawF "   "
:Text(F*7*256+A)
:DrawF Str1P
:Else
:Delay()
:End
:DispGraphrr
:End!If getKey→K-54
:ReturnF
Custom decimal drawing routine
Code: [Select]
:Lbl CDec
.custom decimal drawing routine, arguments X,Y,Num
:.E0504→{E8251}r
:!If r3
:16
:CChar()
:Return
:End
:r3/10000→{E8452}
:r3/10/10/10^10→{E8453}
:r3/10/10^10→{E8454}
:r3/10^10→{E8455}
:r3^10→{E8456}
:0→{E8457}
:E8452→r3
:For(5)
:¦ If {r3}
:¦ !If {E8457}
:¦ 1→{E8457}
:End
:End
:If {E8457}
:{r3}+16
:CChar()
:End
:r3++
:End
:Return
Scrolling list implementation
Code: [Select]
:Lbl ItemS
:.SELECT ITEMS
.creates a scrolling menu, A is the visible offset of the cursor, B is the offset of the window
.r1 is the argument for starting value of the cursor
.oItem points to the beginning of item data which is in the format item ID, quantity
:If r1>5
:r1/6*6→B
:r1^6→A
:Else
:r1→A
:0→B
:End
:PrepI() \\prepares for dealing with items (just a getcalc call)
:41→K
:length(oItem)→L
:While 1
:¦ !If +6
:¦ Return‾1
:End
:If +48
:Box(30,0,66,40)
:3→r2
:B*2+oItem→F
:For(E,0,5)
:¦ If {F}→r1
:¦ GetI() \\copies item information using r1 to L5+e20
:¦ L5+E20→r3  \\this is the name of the item
:¦ CText(40)
:¦ Text(r2-1*256+84)
:¦ DrawF "x"
:¦ DrawF {F+1}►Dec \\quantity of item
:¦ Else
:¦ Str0N→r3
:¦ CText(40)
:End
:r2+7→r2
:F+2→F
:End
:
:!If K-1
:A++
:!If -5
:4→A
:If A+E≤L
:B++
:End
:End
:End
:!If K-4
:A--
:!If +1
:→A
:B--
:!If +1
:→B
:End
:End
:End
:
:Text(A*7+2*256+34)
:DrawF Str1P
:
:InfI({A+B*2+oItem}) \\displays information about the item in another box
:Else
:Delay()
:End
:
:DispGraphrr
:End!If getKey→K-54
:A+B+1
:Return
Size over speed tilemapper (only used to draw starting images)
Code: [Select]
:Lbl DrawM
.basic tilemapper, I care nothing about speed here, go for size. Draw1 is just a routine to draw a 12x12 bitmap in grayscale
.Y1 is tiles
.x, y char offset is 4,3
:ClrDrawrr
:.DRAW MAP θ=MAPFILE PTR
:‾8→T
:PY-3*48+θ+PX-4→F
:For(B,0,5)
:¦ For(A,0,8)
:¦ ¦ conj({F+A}*48+Y1,L1,48)
:¦ ¦
:¦ ¦ Draw1(A*4*3,T,L1)
:¦ End
:¦ T+12→T
:¦ F+48→F
:End
Asm 16x16 4level gray mask routine
Code: [Select]
#include "Axe.inc"

.db $00,$00


mask16:
;Grayscale mask command with 16x16 sprites

;Masked Sprite Format
;3 layers, 12x16
;Mask applied to both buffers
;Front Buffer
;Back Buffer
;SpritePointer always $8528
;byte to draw axv_R2 (X + y*12*12 + 48)
;aligned/unaligned by 4px axv_R1 0 or 1
ld hl,(axv_R1)
ld b,l
xor a \ cp b
jr z, draw
ld hl,$8528
ld b, 16
shiftMask:
ld a, $FF
rrd \ inc hl
rrd \ inc hl
djnz shiftMask
ld b, 32
xor a
shiftSprites:
rrd \ inc hl
rrd \ inc hl
djnz shiftSprites

draw:
ld hl,$9340 ;drawposition in hl
ld ix,$8528 ;sprite mask pointer
ld de,(axv_R2)
add hl, de
ld b,16
ld de, 11
drawFront:

ld a, (ix)
and (hl)
or (ix+32)
ld (hl), a
inc hl
inc ix

ld a, (ix)
and (hl)
or (ix+32)
ld (hl), a
add hl,de
inc ix

djnz drawFront


ld hl,$9872 ;reset registers
ld ix,$8528
ld de,(axv_R2)
add hl, de
ld b, 16
ld de,11
drawBack:
ld a, (ix)
and (hl)
or (ix+64)
ld (hl), a
inc hl
inc ix

ld a, (ix)
and (hl)
or (ix+64)
ld (hl), a
add hl,de
inc ix

djnz drawBack
Edit: one more, the map loading code. Seems like this could be cleaned up quite a bit
Code: [Select]
:Lbl LoadM
.Loads a map into theta using OverY and OverX coordinates
.24x24 tilemap for overX, overY coords storted at theta+2304
:OverY*24+OverX+θ+2304→r6
:.LOAD WARPS,NPCs,ETC
:conj({}-1*32+Y2,L5,32) \\load map information into L5
:{L5+E1E}r→A
:If {L5+E17}*5→B
:conj(Y2+A,E8000,B)
:End
:E8000+B→Ptrg
:A+B→A
:If {L5+E18}*4→B
:conj(A+Y2,Ptrg,B)
:End
:Ptrg+B→Pwrp
:A+B→A
:If {L5+E19}*6→B
:conj(A+Y2,Pwrp,B)
:
:End
:!If OverY
:Fill(θ,768,72)
:Else
:!If OverX
:
:FillM(θ) \\fill map with 16x16 square of 72s at theta
:Else
:DeCoM(r6-25,θ) \\decompress 16x16 map at r6-25 into theta
:End
:DeCoM(r6-24,θ+16)
:!If OverX-23
:FillM(θ+32)
:Else
:DeCoM(r6-23,θ+32)
:End
:End
:
:!If OverX
:FillM(θ+768)
:Else
:DeCoM(r6-1,θ+768)
:End
:DeCoM(r6,θ+768+16)
:!If OverX-23
:FillM(θ+768+32)
:Else
:DeCoM(r6+1,θ+768+32)
:End
:
:!If OverY-23
:Fill(θ+1536,768,72)
:Else
:!If OverX
:FillM(θ+1536)
:Else
:DeCoM(r6+23,θ+1536)
:End
:DeCoM(r6+24,θ+1536+16)
:!If OverX-23
:FillM(θ+1536+32)
:Else
:DeCoM(r6+25,θ+1536+32)
:End
:End
:Return
« Last Edit: January 26, 2013, 11:22:04 pm by squidgetx »

Offline Streetwalrus

  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3821
  • Rating: +80/-8
    • View Profile
Re: Optimization help [A:P]
« Reply #1 on: January 29, 2013, 04:21:00 am »
Unfortunately, I can't help you. Did you poke Runer about it ? :P

Offline squidgetx

  • Food.
  • Project Author
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1881
  • Rating: +503/-17
  • rawr.
    • View Profile
Re: Optimization help [A:P]
« Reply #2 on: January 29, 2013, 02:42:54 pm »
Yeah, he's working on it (I think)

Runer (or anyone who wants to look at this code), if you have questions feel free to pm me or just post here.

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: Optimization help [A:P]
« Reply #3 on: February 01, 2013, 06:17:14 am »
If you don't mind sacrificing a couple t-states (altogether maybe 30?) you can save around 30 bytes doing something like this:
Code: [Select]
;...
;...
draw:
;*******************
ld hl,drawReturn
push hl
ld hl,$9340 ;drawposition in hl
drawReturn:
;*******************
ld ix,$8528 ;sprite mask pointer
ld de,(axv_R2)
add hl, de
ld b,16
ld de, 11
drawFront:
ld a, (ix)
and (hl)
or (ix+32)
ld (hl), a
inc hl
inc ix

ld a, (ix)
and (hl)
or (ix+32)
ld (hl), a
add hl,de
inc ix

djnz drawFront

ld hl,$9872 ;reset registers
;*******************
ret
;*******************
Also, you might be able to get rid of the ld de,(axv_R2) and the ld hl,9872 for the second iteration by adding ($9872-$9340)-(12*16) to hl (12*16 for how much you changed hl in the drawFront loop). I might have my numbers off a bit, but you could try:
Code: [Select]
draw:
ld hl,drawReturn
push hl
ld hl,$9340 ;drawposition in hl
ld de,(axv_R2)
drawReturn:
ld ix,$8528 ;sprite mask pointer
add hl, de
ld b,16
ld de, 11
drawFront:
ld a, (ix)
and (hl)
or (ix+32)
ld (hl), a
inc hl
inc ix

ld a, (ix)
and (hl)
or (ix+32)
ld (hl), a
add hl,de
inc ix

djnz drawFront

ld de,($9872-$9340)-(12*16) ;update hl with the add hl,de after drawReturn
ret

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: Optimization help [A:P]
« Reply #4 on: February 01, 2013, 07:00:52 am »
For the custom decimal drawing routine, this might work:
Code: [Select]
:E8458→A
:While Ans
:r3^10→{A--}
:r3/10→r3
:End
Now A points to the first byte of the decimal expansion. I am not sure if Axe has a better way. In assembly, division routines do double duty to return a remainder as well. I think Axe uses the bcall() for division by 10, so you can probably do:
Code: [Select]
:E8458→A
:While r3
:r3/10→r3
:Asm(26006F     ;a→hl
:→{A--}
:End
But then you will need a special case for r3=0. I am actually not sure if these methods are faster or smaller.

Offline squidgetx

  • Food.
  • Project Author
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1881
  • Rating: +503/-17
  • rawr.
    • View Profile
Re: Optimization help [A:P]
« Reply #5 on: February 10, 2013, 11:34:26 am »
Thanks Xeda; I modified it a little bit because it wasnt working exactly for me.
Code: [Select]
!If r3
16
cchar()
return
end
e8456->A
while -e8452
r3^10->{a}
r3/10->r3
a--
end
a--
while 1
endif {a++}
while -e8457
{a}+16
cchar()a+1->a
end
return
« Last Edit: February 10, 2013, 11:35:15 am by squidgetx »

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: Optimization help [A:P]
« Reply #6 on: February 10, 2013, 11:49:04 am »
Wait, so :
Code: [Select]
r3^10→{a--}
Doesn't work? (You will need to initialise A as 8457h instead of 8456h) I think it is more optimised by 3 bytes if you do it that way (and 16 t-states).

Offline squidgetx

  • Food.
  • Project Author
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1881
  • Rating: +503/-17
  • rawr.
    • View Profile
Re: Optimization help [A:P]
« Reply #7 on: February 10, 2013, 12:06:08 pm »
Wait a minute...

Code: [Select]
!If r3
16
cchar()
return
end
e8457->A
while
r3^10->{a--}
r3/10->r3
end

while -e8457
{a}+16
cchar()
a++
end
return

..gets rid of that extra while loop also
« Last Edit: February 10, 2013, 12:13:20 pm by squidgetx »