(Link to AcmlmWiki) Offline: thank ||bass
Register | Login
Views: 13,040,846
Main | Memberlist | Active users | Calendar | Chat | Online users
Ranks | FAQ | ACS | Stats | Color Chart | Search | Photo album
06-09-24 05:26 PM
0 users currently in Programming.
Acmlm's Board - I3 Archive - Programming - VB6 Overflowing NES rendering... New poll | |
Pages: 1 2 3Add to favorites | Next newer thread | Next older thread
User Post
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 04-29-06 11:36 AM Link | Quote
OK, I have the NES tile rendering example by TFG. And I seem to getting some overflow problems when I try and loop it. Here's my code:

'Get offsets
TileOff1 = "&H315D0"
TileOff2 = "&H315D8"

'Set colors
Pallette2BPP.Color1 = RGB(51, 0, 134)
Pallette2BPP.Color2 = RGB(191, 115, 0)
Pallette2BPP.Color3 = RGB(0, 207, 255)
Pallette2BPP.Color4 = RGB(239, 235, 180)

For y = 0 To 7
For x = 0 To 7
curBit = Mid(Bin(romdata(TileOff1)), x + 1, 1)
curBit2 = Mid(Bin(romdata(TileOff2)), x + 1, 1)

'Draw the tile
Select Case (curBit + curBit2)
Case "00": Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color1, BF
Case "10": Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color2, BF
Case "01": Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color3, BF
Case "11": Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color4, BF
End Select

'Offset + 1
TileDec1 = Str$(CLng(TileOff1)) + 1
TileDec2 = Str$(CLng(TileOff2)) + 1
TileOff1 = hex(TileDec1)
TileOff2 = hex(TileDec2)
Next x
Next y


Technically this should work, but it seems to overflow at the curBit2 when x gets to 2.

Also, is there any easier way to add 1 to an offset without converting it to decimal and then back to hex.
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6321 days
Last view: 6321 days
Posted on 04-29-06 06:41 PM Link | Quote
Originally posted by Arthus
TileOff1 = "&H315D0"
TileOff2 = "&H315D8"

Why are the numbers in quotes?
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 04-29-06 07:06 PM Link | Quote
Because there is a "&H" before them... I don't know, but VB yells at me if I take them away...
Disch

Red Cheep-cheep


 





Since: 12-10-05

Last post: 6600 days
Last view: 6600 days
Posted on 04-29-06 08:09 PM Link | Quote
It looks to me like you're working with strings. Which is complete madness.

Stick with integers. At no point you should be doing any kind of converting to/from strings. Strings should not be involved in any way.
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 04-29-06 08:56 PM Link | Quote
Ok, I took out everything that related to strings... and I still get an overflow error on the curBit2... I don't understand why it's doing this...
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6321 days
Last view: 6321 days
Posted on 04-29-06 09:08 PM Link | Quote
The &h is valid in VB; it's equivilant to 0x in most languages to indicate a hex number. "ANumber = &hFF" is the same as "ANumber = 255". I should warn you, though, that VB6 seems to have bugs when it comes to hex numbers; even when you use a Long variable (4 bytes) it handles them as if you used an Integer (2 bytes); &hFFFF will come out as -1 instead of 65535 (-1 should be &hFFFFFFFF for a Long). I suggest you just put them in decimal with the hex address in a comment.

Also, instead of using Mid() and Bin(), you can just use the logical And and Shift operators. I forget how to do shifts in VB (if you even can), but here's how you'd do that in C:
unsigned char Bit;
unsigned int TileOff1 = 0x315D0;
unsigned int TileOff2 = 0x315D8;

for(y=0; y<8; y++)
{
for(x=0; x<8; x++)
{
Bit = (romdata[TileOff1] >> x) & 1;
Bit |= ((romdata[TileOff2] >> x) & 1) << 1;
switch(Bit)
{
case 0:
//Draw colour 0 here
break;

case 1:
//Draw colour 1 here
break;

//...
}
}
TileOff1++;
TileOff2++;
}


Hopefully this VB code is equivilant, but I haven't done VB in ages. I forget how to shift entirely; you might just have to multiply/divide by powers of two.
Dim Bit as Byte
Dim TileOff1 As Long = 202192
Dim TileOff2 As Long = 202200
For y = 0 To 7
For x = 0 To 7
Bit = (romdata(TileOff1) [right-shift-by] x) And 1
Bit = Bit Or ((romdata(TileOff2) [right-shift-by] x) And 1) [left-shift-by] 1
Select Case Bit
Case 0:
'Draw colour 0 here

Case 1:
'Draw colour 1 here

'...
End Select
Next x
TileOff1 = TileOff1 + 1
TileOff2 = TileOff2 + 1
Next y


Also notice I put the TileOff1/2 increments outside of the for x loop. If you put them inside, then you'd get bit 0 of one byte, bit 1 of the next, and so on.
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 04-29-06 09:21 PM Link | Quote
I found this using Google, it's custom created VB6 Functions that act like the shift functions in C. So how would I use these? Like so?:

RShift(romdata(TileOff1),x)
wboy









Since: 01-05-06

Last post: 6504 days
Last view: 6504 days
Posted on 04-29-06 11:13 PM Link | Quote
Originally posted by HyperMackerel
...I should warn you, though, that VB6 seems to have bugs when it comes to hex numbers; even when you use a Long variable (4 bytes) it handles them as if you used an Integer (2 bytes); &hFFFF will come out as -1 instead of 65535 (-1 should be &hFFFFFFFF for a Long). I suggest you just put them in decimal with the hex address in a comment.


In VB6 &HFFFF is the same as &HFFFF% (forced integer value) which returns -1.

&HFFFF& (forced long value) will return 65535.
Guy Perfect









Since: 11-18-05

Last post: 6322 days
Last view: 6321 days
Posted on 04-30-06 12:43 AM Link | Quote
Silly HyperHacker. Always looking for something mean to say about VB.

No, VB is not buggy in that regard. Numeric literals in most BASIC variants take the data type of the smallest type required to hold the value. The expression &HFFFF is 16 bits, which fits in an Integer variable. Since the Integer data type is signed, it will yield a -1.

Explicitly typecasting the literal with the & character for the Long data type, thusly writing it as &HFFFF&, will yeild a 65535.
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 04-30-06 12:52 AM Link | Quote
Yea well, here is the code I have now, addapted from HH's and some mod's to let VB use it...

Public Sub PaintTile(Buffer As PictureBox)
Dim Bit As Byte
Dim TileOff1 As Long
Dim TileOff2 As Long
'Set colors
Pallette2BPP.Color1 = RGB(51, 0, 134)
Pallette2BPP.Color2 = RGB(191, 115, 0)
Pallette2BPP.Color3 = RGB(0, 207, 255)
Pallette2BPP.Color4 = RGB(239, 235, 180)
TileOff1 = 202192
TileOff2 = 202200
For y = 0 To 7
For x = 0 To 7
Bit = RShift(romdata(TileOff1), x) And 1
Bit = Bit Or LShift((RShift(romdata(TileOff2), x) And 1), 1)
Select Case Bit
Case 0:
Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color1, BF
Case 1:
Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color2, BF
Case 2:
Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color3, BF
Case 3:
Buffer.Line (x * 2, y * 2)-Step(16, 16), Pallette2BPP.Color4, BF
End Select
Next x
TileOff1 = TileOff1 + 1
TileOff2 = TileOff2 + 1
Next y

End Sub


Now I get a division by zero on the bolded line... Can anyone see any problems...

Also, the RShift and the LShift are custom functions from the link I posted before.
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6321 days
Last view: 6321 days
Posted on 04-30-06 03:27 AM Link | Quote
On that line? I can see it crashing in the LShift() function if you didn't call Init() first, but there's no division on that line.
Originally posted by BGNG
Numeric literals in most BASIC variants take the data type of the smallest type required to hold the value. The expression &HFFFF is 16 bits, which fits in an Integer variable. Since the Integer data type is signed, it will yield a -1.

Explicitly typecasting the literal with the & character for the Long data type, thusly writing it as &HFFFF&, will yeild a 65535.

Ah, I forgot about that trick. Though it seems if I'm assigning a value to a 32-bit variable, it shouldn't be treating the value as 16-bit.
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 04-30-06 04:56 AM Link | Quote
OK, here is the function that it's calling:
Public Function LShift(ByVal lThis As Long, ByVal lBits As Long) As Long
If (lBits <= 0) Then
LShift = lThis
ElseIf (lBits > 63) Then
' ... error ...
ElseIf (lBits > 31) Then
LShift = 0
Else
If (lThis And m_lPower2(31)) = m_lPower2(31) Then
LShift = (lThis And &H7FFFFFFF) \ m_lPower2(lBits) Or m_lPower2(31 - lBits)
Else
LShift = lThis \ m_lPower2(lBits)
End If
End If
End Function


And the bolded is what's causing the error.
interdpth

Mole
MZM rapist


 





Since: 11-18-05

Last post: 6320 days
Last view: 6320 days
Posted on 04-30-06 02:59 PM Link | Quote
'<<
Public Function Shr(BasNum As Long, Rot As Integer)
For s = 0 To (Rot - 1): BasNum = basenum * 2: Next s
Shr = BasNum
End Function
'>>
Public Function Shl(BasNum As Long, Rot As Integer)
For s = 0 To (Rot - 1): BasNum = Fix(BasNum / 2): Next s
Shl = BasNum
End Function

Easier
Basnum is the number to be shifted Rot is how many shifts.
Disch

Red Cheep-cheep


 





Since: 12-10-05

Last post: 6600 days
Last view: 6600 days
Posted on 04-30-06 03:12 PM Link | Quote
All of this crap can be avoided if you just unroll that inner loop and divide by constants... which is what I would recommend doing anyway. Calling a power routine and doing all this unnecessary extra work is pretty ridiculous.

KISS - "Keep it simple, stupid"

C-esque code which can be mimiced easily with VB since there is no bitshifting:


BYTE a, b;
int y;

for(y = 0; y < 8; y++)
{
a = ROM[offset + y];
b = ROM[offset + y + 8];

OutputPixel( 0, y, ((a / 128) & 1) | ((b / 64) & 2) );
OutputPixel( 1, y, ((a / 64) & 1) | ((b / 32) & 2) );
OutputPixel( 2, y, ((a / 32) & 1) | ((b / 16) & 2) );
OutputPixel( 3, y, ((a / 16) & 1) | ((b / 8) & 2) );
OutputPixel( 4, y, ((a / 8) & 1) | ((b / 4) & 2) );
OutputPixel( 5, y, ((a / 4) & 1) | ((b / 2) & 2) );
OutputPixel( 6, y, ((a / 2) & 1) | ((b) & 2) );
OutputPixel( 7, y, ((a) & 1) | ((b * 2) & 2) );
}
Guy Perfect









Since: 11-18-05

Last post: 6322 days
Last view: 6321 days
Posted on 04-30-06 04:50 PM Link | Quote
Originally posted by Arthus
OK, here is the function that it's calling:
LShift = (lThis And &H7FFFFFFF) \ m_lPower2(lBits) Or m_lPower2(31 - lBits)
And the bolded is what's causing the error.

Ooh! Ooh! I know the answer! The largest data type that Visual Basic can do bitwise operations on is a 32-bit, unsigned value. That means that saying "A = B And 4294967296#" will cause an overflow error because 4294967296 is larger than the 32-bit unsigned maximum of 4294967295.

I've looked long and hard and have not found any option or function that will circumvent this shortcoming. The only way to do bitwise operations on data that requires more than 32 bits is to use a different programming language like C or FreeBASIC.

The And operation looks okay, since &H7FFFFFFF is 32 bits, but that Or might be causing problems depending on the value of your operands.

Remember that the Integer Division operation \ has higher operator precedence than Or
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 05-01-06 01:29 AM Link | Quote
OK, I took Disch's C-Esque code and attempted to turn it into VB, seeing as I don't know how the OutputPixel() function works, I just too a random stab in the dark.

Public Sub PaintTile(Buffer As PictureBox)
Dim a As Byte
Dim b As Byte
Dim y As Integer

offset = 202192

Pallette2BPP.Color1 = RGB(0, 0, 0)
Pallette2BPP.Color2 = RGB(255, 0, 0)
Pallette2BPP.Color3 = RGB(0, 255, 0)
Pallette2BPP.Color4 = RGB(0, 0, 255)

For y = 0 To 7
a = romdata(offset + y)
b = romdata(offset + y + 8)
Buffer.Line (0, y)-Step(((a / 128) & 1), ((b / 64) & 2)), Pallette2BPP.Color1, BF
Buffer.Line (1, y)-Step(((a / 64) & 1), ((b / 32) & 2)), Pallette2BPP.Color2, BF
Buffer.Line (2, y)-Step(((a / 32) & 1), ((b / 16) & 2)), Pallette2BPP.Color3, BF
Buffer.Line (3, y)-Step(((a / 16) & 1), ((b / 8) & 2)), Pallette2BPP.Color4, BF
Buffer.Line (4, y)-Step(((a / 48) & 1), ((b / 4) & 2)), Pallette2BPP.Color1, BF
Buffer.Line (5, y)-Step(((a / 4) & 1), ((b / 2) & 2)), Pallette2BPP.Color2, BF
Buffer.Line (6, y)-Step(((a / 2) & 1), ((b) & 2)), Pallette2BPP.Color3, BF
Buffer.Line (7, y)-Step(((a) & 1), ((b * 2) & 2)), Pallette2BPP.Color4, BF
Next
End Sub


The good news is, it doesn't overflow. The bad news is, it doesn't output anything remotely like the tile it should be. I have attached the tile it outputs.

Attachments

HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6321 days
Last view: 6321 days
Posted on 05-01-06 01:42 AM Link | Quote
Well...
Originally posted by Arthus
Buffer.Line (0, y)-Step(((a / 128) & 1), ((b / 64) & 2)), Pallette2BPP.Color1, BF
Buffer.Line (1, y)-Step(((a / 64) & 1), ((b / 32) & 2)), Pallette2BPP.Color2, BF
Buffer.Line (2, y)-Step(((a / 32) & 1), ((b / 16) & 2)), Pallette2BPP.Color3, BF
Buffer.Line (3, y)-Step(((a / 16) & 1), ((b / 8) & 2)), Pallette2BPP.Color4, BF
Buffer.Line (4, y)-Step(((a / 48) & 1), ((b / 4) & 2)), Pallette2BPP.Color1, BF
Buffer.Line (5, y)-Step(((a / 4) & 1), ((b / 2) & 2)), Pallette2BPP.Color2, BF
Buffer.Line (6, y)-Step(((a / 2) & 1), ((b) & 2)), Pallette2BPP.Color3, BF
Buffer.Line (7, y)-Step(((a) & 1), ((b * 2) & 2)), Pallette2BPP.Color4, BF

You're telling it to draw black, red, green, blue and that's exactly what it's doing.
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 05-01-06 02:04 AM Link | Quote
I know im telling it to draw red, blue, black and green. But the offset for the tile isn't straight lines. It should come up as a red, blue, black and green houses.
Disch

Red Cheep-cheep


 





Since: 12-10-05

Last post: 6600 days
Last view: 6600 days
Posted on 05-01-06 02:17 AM Link | Quote
My OutputPixel() pseudo function took 3 params: X-coord, Y-coord, and a "color" to place at that coord.

The given code will only affect the image in an 8x8 range (X or Y coords never go higher than 7). And the color value is always 0 - 3. If you want to apply a palette to that, you might do something like:


OutputPixel( x,y, Palette[ ((a / 128) & 1) | ((b / 64) & 2) ] );


Where "Palette" is a 4-entry array with actual colors to output.

If you want a wider range, like say you want the tile to be drawn with one of several palettes -- you could do something like the following:


OutputPixel( x,y, Palette[ ((a / 128) & 1) | ((b / 64) & 2) | c ] );


Where 'c' is your palette selection value (should be a multiple of 4.

ie... 0, 4, 8, 12, etc -- to choose which palette you want to use.


Also note (I don't know if you realized this)... but that straight line '|' character is the C operator for a bitwise OR instruction. You can substitute that with addition if you like. the '&' character is the C operator for a bitwise AND instruction.
Arthus

140


 





Since: 11-17-05
From: Australia

Last post: 6533 days
Last view: 6533 days
Posted on 05-01-06 02:41 AM Link | Quote
See, that would be the problem. I don't know any C, I tried it, and I couldn't get anything to work. SO i'll leave that for a little while. I'll try to figure out this bit in VB then.

EDIT: Ok, I tried that, I got this red/black line dealy. Still no pregress, I should learn how exactly the tiles work maybe...


(edited by Arthus on 05-01-06 01:52 AM)
Pages: 1 2 3Add to favorites | Next newer thread | Next older thread
Acmlm's Board - I3 Archive - Programming - VB6 Overflowing NES rendering... |


ABII

Acmlmboard 1.92.999, 9/17/2006
©2000-2006 Acmlm, Emuz, Blades, Xkeeper

Page rendered in 0.021 seconds; used 458.58 kB (max 587.38 kB)