Qbasicnews.com

Full Version: custom putting without def seg or that stuff
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i was talking to the folks at tek-tips about accessing pixels in a get/put array without def seg or that stuff. here's what we came up with. tell me if it's any good, or if you'd rather stick with the traditional way.

Quote:Barok (MIS) Nov 14, 2003
okay, so of course, when you GET an image, the variables in the array holding the image would look like this.

image(0) = 160 'width times 8
image(1) = 20 'height
image(2) = 2342 'first two pixels
image(3) = 5435 'next two pixels...
...
...

of course, qb adds the first pixel color to the second times 256, like this...

image(2) = color1 + color2 * 256

now, my question is this: how can i find out what one pixel would be? does anyone know how i could learn what, say, color1 would be without using def seg, varseg, and varptr? thanks.





Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!




Tek-Tips Forums is Member Supported. Click Here to donate.
CubeE101 (Programmer) Nov 14, 2003
Use DEF SEG and PEEK

FUNCTION GetColor%(x as integer, y as integer, image() as integer)
DEF SEG = VARSEG(image(0)) 'Set the Segment to the array
offset& = VARPTR(image(2)) 'Get the Offset of the first pixel (always 4)
width& = image(0) \ 8 'get the width
height = image(1) 'get height

IF x >= 0 AND y >= 0 AND x <= width& AND y <= height THEN
color = PEEK(offset + x + (y * width&)
END IF
DEF SEG 'Restore Segment
END FUNCTION
Have Fun, Be Young... Code BASIC
-Josh

http://cubee.topcities.com



Mark this post as a helpful/expert post!


Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



qbasicking (Programmer) Nov 14, 2003
I'm not quite sure:

colour1% = (image(2))MOD 256
colour2% = image(2) - colour1% * 256

I think this works, if it doesn't a similar code will, but I'll have to look it up exactly. Why don't you want to use DEF SEG< VARSEG, or VARPTR?


Mark this post as a helpful/expert post!


Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



Barok (MIS) Nov 14, 2003
thanks cubee, but that' what i'm trying to avoid.

i want to find it out mainly because of speed. if i can find out how to find out what the colours are, then i can save my programs from using lots of useless def segs (they are changed a split second later to &ha000, then back to the varseg of the image, then back to &ha000, etc. etc.)





Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



qbasicking (Programmer) Nov 15, 2003
Unless you are using a really slow computer or plan to be doing this ALOT it shouldn't slow down your program too much.

Anyway - I was half right above, but I figured out the rest of the code. First of all, the way you have it written above, it wouldn't be two pixils at a time, it would be four.
Instead of image() use image%()

FUNCTION colour1% (a%)
IF a% < 0 THEN neg% = 1: a% = -a%
colour1% = a% MOD 256
IF neg% = 1 THEN colour1% = 128 + (128 - a%)
END FUNCTION

FUNCTION colour2% (a%)
IF a% < 0 THEN neg% = 1: a% = -a%
colour2% = a% \ 256
IF neg% = 1 THEN colour2% = 127 + (128 - colour2%)
END FUNCTION

Let me explain why this works.
First when you said: image(2) = color1 + color2 * 256 you were right and wrong, remember that computers work in binary actually: image(2) = colour1 + colour2 * 11111111

You have to have the negative handler because if your second colour is more than 127 it will be forced to use the first binary bit to make the number. Qbasic uses that bit as the positive/negative switch, so qbasic reads
1110000110101111 which the computer knows as 57775 as
-25007




Mark this post as a helpful/expert post!


Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



CubeE101 (Programmer) Nov 15, 2003
I suppose you could use Hex$...

H$ = Hex$(image(2))
colour1% = Val("&H" + Left$(H$,2))
colour2% = Val("&H" + Right$(H$,2))

you can test it like this...
-----------------------------------
Dim image(10) As Integer
Screen 13
Pset (0,0),255
Pset (1,0),245
Get(0,0)-(2,2),image

H$ = Hex$(image(2))
colour1% = Val("&H" + Left$(H$,2))
colour2% = Val("&H" + Right$(H$,2))

Print colour1%
Print colour2%
-----------------------------------

And to go the other way...
image(2) = Val("&H" + Hex$(colour1%) + Hex$(colour2%))

Have Fun and Good Luck...
Have Fun, Be Young... Code BASIC
-Josh

http://cubee.topcities.com



Mark this post as a helpful/expert post!


Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



CubeE101 (Programmer) Nov 15, 2003
BTW...

Let me know if it is Faster than the DEF SEG method...

also the reason I use an extra variable H$ instead of using 2 Hex$ functions was for speed... you can also try it the other way and bench mark between those 2 methods also...

The other way is...
colour1% = Val("&H" + Left$(Hex$(image(2)),2))
colour2% = Val("&H" + Right$(Hex$(image(2)),2))

Now... It Would Be nice to be able to make a buffer the size of the screen...
Dim Scrn(32000) As Integer
And be able to use inline assembly (Call Absolute) to move the pointer to video memory...
That way you could Write/Read to the screen just by changing the array
Have Fun, Be Young... Code BASIC
-Josh

http://cubee.topcities.com



Mark this post as a helpful/expert post!


Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



Barok (MIS) Nov 16, 2003
thanks cubee, that helps alot! Big Grin

btw, with your buffer should be this:

dim scrn(32001) as integer

because the screen has 64004 pixels. an integer equals 2 bytes, so that would bring it to 32002, and since we include 0, that makes it 32001.





Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



CubeE101 (Programmer) Nov 16, 2003
No...

The Screen has 64000 Pixels (320 x 200)
If you are NOT using PUT... You only Need 32000 Integers...

The other 2 integers are to store the 4 bytes used for Width & Height of the Get/Put Array...

But I was talking about writing straight to the screen via an array...

So I Could have actually said...
Dim Scrn(31999) As Integer
But I rounded it up to 32000 just 4 fun
Have Fun, Be Young... Code BASIC
-Josh

http://cubee.topcities.com



Mark this post as a helpful/expert post!


Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



Barok (MIS) Nov 16, 2003
whoops... completely forgot about that. haven't done anything with buffering for a while... usually you want the buffer to be PUT compatible though. Thanks for correcting me.





Inappropriate post?
If so, Red Flag it!


Check out the FAQ
area for this forum!



CubeE101 (Programmer) Nov 17, 2003
The Reason I would want to do that, (set an array pointer to video memory) is to have the screen update when you change the array, and bypass the PUT command, then the screen would update when you change the array And would not have to use DEF SEG, Peek, Poke or Put...
Have Fun, Be Young... Code BASIC
-Josh

http://cubee.topcities.com

of course you can. But peek/poke is probably faster because you can access the image byte by byte numerically. In an integer array, you have 16-bits a value. So if you want to access individual bytes (1 byte per pixel) you have to either waste calculations breaking each integer down or mess with strings, which is pretty ugly (I dont even know if you can use GET/PUt with that, actually.)

You know what's even faster though? Anything but QB Wink Libraries, my friend. They're nifty.
If you want to use GETed array without DEF SEG and PEEK (which I prefer, and POKE of course), you use the array indices.

Code:
DIM BLA((10*10+4)\2) AS INTEGER

SCREEN 13
LINE (0,0)-(9,9),1, BF

GET (0,0)-(9,9), BLA
BLA is an array of 104 bytes, 52 integers. Now you can:

Code:
Wid% = BLA(0) \ 8 ' don't know sure about this though
Hei% = BLA(1)

Hereby you can get the width and height of an image.

Now to read pixels:
Code:
FUNCTION readPixel% (PixelNo AS INTEGER)
   ind! = CSNG(PixelNo) / 2 + 2
   IF ind! = INT(ind!) THEN
      readPixel% = (BLA(INT(ind!)) AND &HFF00&) \ &H100
   ELSE
      readPixel% = (BLA(INT(ind!)) AND &HFF)
   END IF
END FUNCTION
Where PixelNo is the pixel number of the pixel you want to read.

Btw, right from my head, without error-checking and such. Hope there are no errors or mistakes.

Hope this helped you out Wink
Will this have any practical use? If so then you should use ASM cuz QB will be really slow =(
Er, the whole point is to use only QB code... :roll:
I am confused. Is this for some QB compo?
no, for purists.
Dumb purists.

*Runs and hides behind the couch with his AK-47. Ready for action =P*
and, if you're a "purist", that's a pretty silly way to go about things Smile
It's just another way of programming, don't fuss about it. Also I like PQB too, but the rest as well Wink