Single line TINT-RGB-r,g,b (difficult)
Post by michael on May 23rd, 2016, 11:51am
It would be nice to get 3 values from one function, but a function can only return 1 value at a time.
I have a PROC version of this that makes it super easy to assign many values to variables, but again, I am exposing globals.
And the rule is, to keep variables hidden so it doesn't interfere with a programmers variables.
I am trying to keep it super simple, as I really want to make super easy tools for others to use. (just one line does the job)
The problem is.
You CAN transfer an array like this:
Code:
DIM a%(2)
a%(0)=100:a%(1)=10:a%(2)=50
DIM b%(2)
b%()=a%()
PRINT b%(0)
PRINT b%(1)
PRINT b%(2)
BUT you cant do that using a function
This program works, but I need to simplify this solution.
I could just have global variables and modify them all in the function, but that would expose global variables.
Perhaps a pointer solution? I have no idea.
Whom ever helps solves this puzzle, will help create the RGB Library.
I am slowly getting this Library perfected.
Code:
MODE 8
CLG
OFF
x%=0:y%=0:r=0:g=0:b=0
VDU 5
GCOL 15
CIRCLE FILL 100,100,100
r=FN_getrgb(100,100,"r")
g=FN_getrgb(100,100,"g")
b=FN_getrgb(100,100,"b")
MOVE 500,500:PRINT"r "+STR$(r)+" g "+STR$(g)+" b "+STR$(b)+""
END
DEFFN_getrgb(h,v,col$)
LOCAL r,g,b,rgb%
rgb%=TINT(h,v)
b=INT(rgb%/(256*256))
g=INT((rgb%-b *256*256)/256)
r=INT(rgb%-b*256*256-g*256)
IF col$="r" THEN result=r
IF col$="g" THEN result=g
IF col$="b" THEN result=b
=result
:'(
Re: Single line TINT-RGB-r,g,b (difficult)
Post by David Williams on May 23rd, 2016, 12:37pm
The following bit of code shows how to return multiple values from a subroutine (PROCedure):
Code: rgb% = &AABBCC
PROCgetRGBValues( rgb%, r&, g&, b& )
PRINT "r = &"; ~r&
PRINT "g = &"; ~g&
PRINT "b = &"; ~b&
END
DEF PROCgetRGBValues( rgb%, RETURN red&, RETURN green&, RETURN blue& )
red& = rgb% >> 16
green& = rgb% >> 8
blue& = rgb%
ENDPROC
The byte variables red&, green& and blue& are in fact not global, and are local to the subroutine 'getRGBValues'.
You needn't use byte variables of course, but if using integer variables you'd probably have to mask off (usually via AND) the unwanted bits in rgb% in order to extract the desired RGB values.
David.
--
Re: Single line TINT-RGB-r,g,b (difficult)
Post by michael on May 23rd, 2016, 12:47pm
Thankyou. I see what you are doing, but it wont work until I convert TINT return value to a hexadecimal value and then offer that value to your solution.
For now, I have only this global solution. I guess its enough for finding colors if your using globals.
Code:
MODE 8
CLG
OFF
x%=0:y%=0:r=0:g=0:b=0
VDU 5
GCOL 15
CIRCLE FILL 100,100,100
PROC_getrgb(100,100)
MOVE 500,500:PRINT"r "+STR$(r)+" g "+STR$(g)+" b "+STR$(b)+""
END
DEFPROC_getrgb(h,v)
rgb%=TINT(h,v)
b=INT(rgb%/(256*256))
g=INT((rgb%-b *256*256)/256)
r=INT(rgb%-b*256*256-g*256)
ENDPROC
Re: Single line TINT-RGB-r,g,b (difficult)
Post by Zaphod on May 23rd, 2016, 1:06pm
Not sure exactly what you are trying to do but there might be something of use here:
Code:
MODE 8
VDU 5
GCOL 12
r=0: b=1: g=2
CIRCLE FILL 100,100,100
PRINT FN_getrgb(100,100,r),FN_getrgb(100,100,b),FN_getrgb(100,100,g)
PROC_getrgb(102,105,b&())
MOVE 500,500
PRINT b&(0),b&(1),b&(2)
END
DEF FN_getrgb(x,y,col)
LOCAL rgb%, a&
rgb%=TINT(x,y)
CASE col OF
WHEN 0: a&=rgb% >> 16
WHEN 1: a&=rgb% >> 8
WHEN 2: a&=rgb%
ENDCASE
=a&
DEF PROC_getrgb(x,y,RETURN a&())
LOCAL rgb%
DIM a&(2)
rgb%=TINT(x,y)
a&()=(rgb% >> 16), (rgb% >> 8), rgb%
ENDPROC
I see you like comparing strings as in IF col$="r". That probably uses more memory and is slower.
Re: Single line TINT-RGB-r,g,b (difficult)
Post by michael on May 23rd, 2016, 2:07pm
Zaphod, looks like you have the final solution..
The PROC solution is small and tidy.
Thanks for that. I will try to pick out the best part and then it can be official in the tools here.. And I can clean up the other attempts that are not up to par.
I appreciate the help. Someone may want to use this to extract a color for a game or utility, and having RGB values makes it easy to understand the color you are dealing with.
Besides TINT needed a tool set up like this. Alone, TINT cant work in a COLOUR statement.
That's actually one reason this needed to be fixed once and for all.
This particular issue has been tormenting me long before I joined BBC Basic.
The last language I used that was capable of SEEING a color and returning that color properly was TURBO PASCAL 6.0 (1990)
It was the first language that I actually finished a board game and knowing the colors was essential for my game called VIRUS to work.
(but Turbo Pascal had only 16 colors in the core without new libraries) and would SEE only those colors, but it worked nonetheless
Liberty Basic (can) do it with APIs, but its a learning curve and the code presented.. is shall we say, kinda guarded and difficult to always work with..
I think with this, we finally have solved the basic parts for every day tools a person might use and now its time to work on animation again.
;D
Re: Single line TINT-RGB-r,g,b (difficult)
Post by Zaphod on May 23rd, 2016, 5:28pm
Or using structures you could do this.
Code: MODE 8
VDU 5
GCOL 7
CIRCLE FILL 100,100,100
MOVE 500,500
PROC_getrgb2(100,100, color{})
PRINT color.r&, color.g&, color.b&
END
DEF PROC_getrgb2(x,y,RETURN a{})
DIM a{r&,g&,b&,n&}
a{}!0=TINT(x,y)
ENDPROC
The structure member a.n& never has anything in it but is probably needed to stop corruption of the memory. It is safe to compile with crunched variable names as well.
Re: Single line TINT-RGB-r,g,b (difficult)
Post by michael on May 23rd, 2016, 11:51pm
These examples are very interesting. I am learning something new. Although I seen something similar before. Each type of example helps clear up the possible confusion. This is a great way to manage variables within a DEFPROC. Very useful.
I don't think you could do this in Liberty and in LBB I am unsure, as it does have the ability to use BBC Basic assembler and some BBC Basic commands according to Richard. (but this is irrelevant as I don't use Liberty anymore.. its just some thoughts)
Re: Single line TINT-RGB-r,g,b (difficult)
Post by JGHarston on May 28th, 2016, 11:43pm
So, combining your code with David's:
PROC_getrgb(horiz,vert,red,green,blue)
PRINT red,green,blue
...
DEFPROC_getrgb(h,v,RETURN r&,RETURN g&,RETURN b&)
LOCAL rgb%
rgb%=TINT(h,v)
r&=rgb%>>16
g&=rgb%>>8
b&=rgb%
ENDPROC