BBC BASIC for Windows
Programming >> BBC BASIC language >> Single line TINT-RGB-r,g,b (difficult)
http://bb4w.conforums.com/index.cgi?board=language&action=display&num=1464004290

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