| |
ws
Registered: Apr 2012 Posts: 251 |
Simple bilinear interpolation in assembler
Hello,
for some reason, with increasing age, i am no longer interested in spending much time on re-inventing the wheel.
Therefore, i'd like to ask if any of you wizards perhaps know of a close solution to this problem:
Lets say you have a "heatmap" in a matrix of 20x10 cells.
Does anyone perhaps already have a fast and simple routine for interpolating all the values within these cells, so that when you have some cells with very high values and some cells with very low values, that more or less smooth transitions (image blur) can be achieved in very few rasterlines?
Google just spat out hardcore math for me, which i feel unable to wrap my head around, when attempted to translate to a c64 assembler solution. (I code in assembly, directly, no c++ or the like, pretty please).
best regards
WS |
|
... 24 posts hidden. Click here to view all posts.... |
| |
ws
Registered: Apr 2012 Posts: 251 |
that is actually a very nice hint, using stairs of tables.
but i just implemented my first attempt and obviously it just dampens all the values instead of mixing them, so as a conclusion:
after the first load of a cell, it cannot just be destructively set to a fixed translation value without being compared to its neighbours.
the reduction value must be related to the neighbouring cells.
example
f000 --> destructive --> 8421 - ok
f200 --> destructive --> 8531 - not ok, must be A531
(just arbitrary example values)
workin on that.
[update]
by the way, this totally out of the blue, super far fetched noise generator which i utilize for creating data to be blurred, works surprisingly well (IN VICE!):
drawdom ldx #$00
paintle
lda $dc01
eor $d800
sta $db00
eor $db00
eor $0400,x
adc $d800,x
sta $0400,x
inx
bne paintle
rts |
| |
ws
Registered: Apr 2012 Posts: 251 |
[update 2 on noise generator: works surprisingly well on a real c64, too. actually best performance i had with bus noise to this day. duh. (it needs to run twice for good entropy.) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
i strongly advice against using open i/o space for "noise". it is _not_ noise in the first place (what you are reading is what was left on the bus by the previous vic fetch) and on some C64s you will see just zeros or $ff. |
| |
ws
Registered: Apr 2012 Posts: 251 |
Youre probably right, i'd also confirm that a mechanism like this should not be used without prior testing on several "chipsets", i must admit that i am quite obsessed with that method, though :-) I only use it for testing purposes, because i am too lazy to setup the SID noise method (if i remember correctly that that was possible). |
| |
ws
Registered: Apr 2012 Posts: 251 |
okay. this really seems to be the fastest way:
do_blur clc
lda datafield,x
adc datafield+1,x
ror
sta datafield,x
inx
cpx #$00
bne do_blur
demo: http://dl.dataelephant.net/blur.zip (press space to...)
this is a 2 iterations blur, only thing i am going to add is looking back n pixels plus avoiding backshift.
and yes, i must really learn to think less wishful. took me quite some time to grasp the simpleness of the problem. too many images in my head.
ps: if anyone hints me towards formatting source code nicely in this csdb thing, i will happily comply. |
| |
ws
Registered: Apr 2012 Posts: 251 |
i am pretty satisfied already:
http://dl.dataelephant.net/blur_it4.zip
4 iterations simple 1 cell blur. i am impressed how easy this stuff is, compared to trying to imagine it.
(prg+src inside zip) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting wertstahlps: if anyone hints me towards formatting source code nicely in this csdb thing, i will happily comply.
Just follow the Read more link on the comment entry form.
But in short, wrap your code segments in [ code]/[ /code] (only without the spaces after the "["s) |
| |
ws
Registered: Apr 2012 Posts: 251 |
;-------------------------------------------------
linenums = #$05
linecount byte $05 ;(+1)
blur lda linenums ;---
sta linecount ;---
ldx #$00
do_blurX ldy #$26
x_blurX lda $0400+1,x
lsr
lsr
lsr
sta pot
lda $0400-1,x
lsr
lsr
lsr
clc
adc pot
sta pot
lda $0400,x
lsr
clc
adc pot
bcc noclip
lda #$ff
noclip sta $0400,x
inx
dey
bne x_blurX
inx ;---
inx ;--- these and this mechanism is
;--- just there to provide a visual gap
;--- ofcourse the scanning could be seamless
dec linecount ;---
bne do_blurX ;---
rts
;================
pot byte $0
needs deeper thought, but it works, horizontally, though. |
| |
Digger
Registered: Mar 2005 Posts: 437 |
.prg would be good :) |
| |
Rastah Bar Account closed
Registered: Oct 2012 Posts: 336 |
I can see some optimizations. For example, you can get rid of 2 LSRs by first adding ($0401,x)/2 and ($3ff,x)/2 and dividing the result by 4.
lda $401,x
lsr
sta pot
lda $03ff,x
lsr
clc
adc pot
lsr
lsr
sta pot
Also, does it ever clip? ($400,x)/2 <= 128 and ($3ff,x)/8+($401,x)/8 <= 64, so their sum will not exceed 192.
And I would use a ZP address for pot. |
Previous - 1 | 2 | 3 | 4 - Next |