Author Topic: screen fade routine  (Read 16121 times)

0 Members and 1 Guest are viewing this topic.

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: screen fade routine
« Reply #20 on: February 23, 2012 »
Oh, k. thx... no idea how to fix it though. I've had a play with the code. Stumped.

"c+(xres*yres)" doesn't work.

Remember I'm an utter newbie, and get lost very quickly.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: screen fade routine
« Reply #21 on: February 23, 2012 »
You need to loop through all the pixels and fade each one using the value of c to multiply each of the red/green/blue parts.

rgbav is the pixel colour read from each pixel, shaded and then written back to the pixel.

Do the looping for that inside the sub as calling the sub for each pixel would be slow.
« Last Edit: February 23, 2012 by Stonemonkey »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: screen fade routine
« Reply #22 on: February 24, 2012 »
Code: [Select]
sub fadescreen(byval c as integer)
dim as integer ptr s = @screen(0) ; point s to the beginning of screen memory
dim as uinteger rgbav,rv,gv,bv,p
for p = 0 to xres*yres-1

rgbav = *s ; pull out the pixel at 's'
rv = (rgbav shr 16) and &hff
gv = (rgbav shr 8) and &hff
bv = rgbav and &hff
'apply the brightness
rv = (rv * c) shr 8
gv = (gv * c) shr 8
bv = (bv * c) shr 8
'repack the colours
rgbav = (rv shl 16) or (gv shl 8) or bv or &hff000000
*s = rgbav ; put the pixel back to 's'
       s=s+1 ; go to the next pixel in screen memory
next
end sub

Jim
Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: screen fade routine
« Reply #23 on: February 25, 2012 »
@Jim. wow. Just as I was about to post again (for more help, as I was extremely stuck), it notified me that someone replied... and with much thanks (as I was pulling my hair out) it works as intended. Not real sure as to 'exactly' how its works at the moment, but I will be sure to read over the code 1000 times until I understand what's happening.

I have the basic 'jist' of what is going on, but the whole screen pointers n such I'm still yet to wrap my head around.

Much thanks again Jim.

K++ and all that jazz (<- does that actually add good karma to you? I forget to add that to ones that have helped me)

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: screen fade routine
« Reply #24 on: February 25, 2012 »
K++ and all that jazz (<- does that actually add good karma to you? I forget to add that to ones that have helped me)

You need to click 'applaud' under Jim's avatar to give him some Karma. People say "K++" just to let people know they've given them some karma :)
raizor

Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: screen fade routine
« Reply #25 on: February 25, 2012 »
Ahh, thought so, so now I need to hit 'Applaud' on a few profiles... like 10 times or so.. hehe Raizor, Jim, Stonemonkey, Shockwave... etc etc.. if you notice your karma jump by 10-20 points... it's from me :D

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: screen fade routine
« Reply #26 on: February 25, 2012 »
I have the basic 'jist' of what is going on, but the whole screen pointers n such I'm still yet to wrap my head around.


It might seem a little strange at first but it's not really all that tricky, and it can be very useful. I'll try to keep this simple but if there's anything you don't get just say.

Every variable in a program is stored somewhere in memory and has it's own unique address.

You can get the address of a variable using @

Code: [Select]
dim as integer a=10

print @a 'print the address in memory where the value of a is stored

'the address will be the same no matter what value is written into a

sleep

That address can be stored in a pointer and the contents of the memory it points to can be read or written to using *

Code: [Select]
dim as integer a=10

dim as integer pointer b=@a 'b contains (points to) the memory address of a

print *b 'prints the contents of the memory address b points to

'you can also write into the memory address
*b=20 'will have the same effect as a=20

sleep

Since an array is just a list of variables in an area of memory you can read/write from different parts of the array just by modifying the pointer, no symbol is used to modify the pointer.

Code: [Select]
dim as integer a(0 to 1)

a(0)=12
a(1)=34

dim as integer pointer b=@a(0) 'b points to the first address of the a array

print *b 'print the value in the address b points to

b=b+1 ' increment the pointer

print *b 'print the value in the new address b points to

sleep

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: screen fade routine
« Reply #27 on: February 25, 2012 »
@Stonemonkey... awesome response, and much thanks. Any little bit that helps me learn = very much appreciated.

With that third example as b being a pointer, does that mean each loop "b" is +1 each time, yet "a" still stays the same, so in fact that if I wanted to run a few different loops that point to the same thing, in effect I can setup the initial one... eg...

Code: [Select]
dim as integer a(0 to 2) , a(0)=10 , a(1)=100 , a(2)=1000

dim as integer pointer ap1=@a(0) , ap2=@a(0) , ap3=@a(0) ' the pointers ap1,ap2,ap3 that point back to a(0) which is "10"

for loopy as integer = 1 to 1000
    ap1=ap1+1+loopy
    ap2=ap2+3+loopy
    ap3=ap3+5+loopy
    cls
    print "ap1 = "+str(ap1)
    print "ap2 = "+str(ap2)
    print "ap3 = "+str(ap3)
next

print "this number is "+str(a(1)) ' which should return "100"

if a(1) <> "10000" then
    a(1)=10000 ' this changes the initial "a(1)" array from "100" to "10000"
endif

print "this number has been changed to a "+str(a(1)) ' which should return "10000"


I'm a lil' tired... but I hope I made some sense.

REALLY appreciate it Stonemonkey. I guess my next thing is setting up the different aspects of my demo's as buffers. So then I have my background buffer, scroller buffer, logo buffer etc etc etc, Thinking about doing it that way makes sense to me, as it would be easier to trace/modify/blit each one.

Thanks again.

*edited... see I did make a mistake. heh. Integers!!!!! not strings ;P
« Last Edit: February 25, 2012 by ttemper »

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: screen fade routine
« Reply #28 on: February 25, 2012 »
You have to be a bit more careful about how you modify your pointers, you only have an array of 3 integers there but you are adding 1,3,5 and loopy which goes from 1 to 1000.

Have a look at Jims loop and see how he's using the pointer to access the array and try some things out for yourself and see if you can get the results you expect.

EDIT: I think I see what you're saying, you can modify the pointer without changing the values? yes.

any_pointer=any_pointer+x 
'changes the address that the pointer points to but doesn't affect the contents of what it points to.

*any_pointer=*any_pointer+x
'changes the contents of the memory address my_pointer points to but doesn't affect the pointer. Any change made in this way is also apparent when read by the original variable or by another pointer.
« Last Edit: February 25, 2012 by Stonemonkey »

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: screen fade routine
« Reply #29 on: February 25, 2012 »
Hmm, I think I misunderstood and then wrote code that doesn't make much sense, my bad.

I'll have a read tomorrow when I'm less under the influence.

By your comments and me re-reading the code what I quickly wrote, I see how it's wrong.

As no, I don't want to keep changing the pointer (Although I see that can be done now also, so I can swap ap0 from pointing to a(0) which = 10, and repoint ap0 to a(2) which = 1000) as this wasn't my intention.

What you briefly explained here...

Code: [Select]
any_pointer=any_pointer+x 
'changes the address that the pointer points to but doesn't affect the contents of what it points to.

*any_pointer=*any_pointer+x
'changes the contents of the memory address my_pointer points to but doesn't affect the pointer.

^ explains what I was trying to understand. I'll give it another read over tomorrow. Much thanks.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: screen fade routine
« Reply #30 on: February 26, 2012 »
Perhaps I jumped a step going straight in with a pointer. Compare this code with the previous one
Code: [Select]
sub fadescreen(byval c as integer)
dim as uinteger rgbav,rv,gv,bv,p
for p = 0 to xres*yres-1

rgbav = screen(p) ; pull out the pixel at array entry 'p'
rv = (rgbav shr 16) and &hff
gv = (rgbav shr 8) and &hff
bv = rgbav and &hff
'apply the brightness
rv = (rv * c) shr 8
gv = (gv * c) shr 8
bv = (bv * c) shr 8
'repack the colours
rgbav = (rv shl 16) or (gv shl 8) or bv or &hff000000
screen(p) = rgbav ; put the pixel back to 'p'
next
end sub
These pieces of code do exactly the same thing.  So the step I skipped really is an optimisation.
Look at what happens for each loop in the above code
Code: [Select]
;p=0
rgbav = screen(0) ; pull out the pixel at array entry 0
;p=1
rgbav = screen(1) ; pull out the pixel at array entry 1
;p=2
rgbav = screen(2) ; pull out the pixel at array entry 2
...

So when we index an array we're asking the compiler:
"work out where screen is, offset by 'p' and pull out the value".

For the first 4 pixels this would be
1. address=screen+0*4
2. address=screen+1*4
3. address=screen+2*4
4. address=screen+3*4

But we're asking the same question again and again, starting from scratch, when in fact if we know the answer to "offset by 0" we can tell the answer to "offset by 1" is the same as just adding 1 to the previous answer.  And then, "offset by 2" is just adding 1 again.

For the first 4 pixels this would be
1. address=screen
2. address=address+4
3. address=address+4
4. address=address+4

You can see the answers are the same in both cases.  n.b. We are adding 4 because 4bytes is the size of an integer is the size of the rgba pixels we are working with.

Actually, maybe it will help to write that out longwise:
1. address=screen
2. address=screen+4
3. address=screen+4+4
4. address=screen+4+4+4
and simplifying
1. address=screen+0*4
2. address=screen+1*4
3. address=screen+2*4
4. address=screen+3*4

So, we should be
1) thinking of the screen as an array of pixels.  In this case it's one dimensional, and we have to imagine it as being rectangular.
2) seeing that an array is really just a pointer to where the data starts in memory
3) noticing that indexing an array is just taking that pointer and offsetting in to it by the size of the index
4) seeing that some kinds of arithmetic, especially adding and subtracting, can be applied to pointers just as they can be to integers.
5) noting that doing arithmetic on pointers has no effect on the memory or variables being pointed at.

Hope that helps to understand.

Jim
Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: screen fade routine
« Reply #31 on: February 26, 2012 »
@Jim, thanks, I'll have a read through this thread properly this week. Really appreciate the help guys.