Omnimaga > Ash: Phoenix

Optimization help [A:P]

(1/2) > >>

squidgetx:
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: ---: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
--- End code ---
Custom decimal drawing routine

--- Code: ---: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
--- End code ---
Scrolling list implementation

--- Code: ---: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

--- End code ---
Size over speed tilemapper (only used to draw starting images)

--- Code: ---: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
--- End code ---
Asm 16x16 4level gray mask routine

--- Code: ---#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
--- End code ---
Edit: one more, the map loading code. Seems like this could be cleaned up quite a bit

--- Code: ---: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
--- End code ---

Streetwalrus:
Unfortunately, I can't help you. Did you poke Runer about it ? :P

squidgetx:
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.

chickendude:
If you don't mind sacrificing a couple t-states (altogether maybe 30?) you can save around 30 bytes doing something like this:

--- Code: ---;...
;...
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
;*******************
--- End code ---
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: ---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
--- End code ---

Xeda112358:
For the custom decimal drawing routine, this might work:

--- Code: ---:E8458→A
:While Ans
:r3^10→{A--}
:r3/10→r3
:End

--- End code ---
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: ---:E8458→A
:While r3
:r3/10→r3
:Asm(26006F     ;a→hl
:→{A--}
:End

--- End code ---
But then you will need a special case for r3=0. I am actually not sure if these methods are faster or smaller.

Navigation

[0] Message Index

[#] Next page

Go to full version