Memory Access Violation

Blitz3D Forums/Blitz3D Programming/Memory Access Violation

WolRon(Posted 2008) [#1]
I keep getting a Memory Access Violation with this bit of code on the ImagesCollide line. I just can't see where the problem is. Can anyone else spot it?
	;check collisions
	For thisBullet.bullettype = Each bullettype
		exitloop = False
		For thisship.shiptype = Each shiptype
			If thisship\ID = 2
				If ImagesCollide(thisbullet\image, thisbullet\bulletx, thisbullet\bullety, 0, thisship\image, thisship\shipx, thisship\shipy, 0)
					FreeImage thisBullet\image
					Delete thisBullet
					FreeImage thisship\image
					Delete thisship
					exitloop = True
				EndIf
			EndIf
			If exitloop = True Then Exit
		Next
	Next



GfK(Posted 2008) [#2]
From that I'd guess it works perfectly the first time, but after that, the image data has been removed (and therefore removed from all other bullet/ship objects).

If you have a load of ship objects, then you also have a load of image pointers that point to the same chunk of data. Delete it once, and its gone from the others too.

Remove the FreeImage lines and that might fix it.


big10p(Posted 2008) [#3]
I also believe there's an old bug that sometimes used to cause ImagesCollide to MAV without reason.

Not sure if it was ever fixed. Try searching the bug reports forum to shed some more light.


WolRon(Posted 2008) [#4]
@GfK
Actually every object has its own image so that can't be it. I tried commenting out the Freeimage lines and that made no difference (although it DID seem to happen less, hmmm)

@big10p
I think I'm using an older version of Blitz3D (1.87). Maybe that's my problem. It seems weird that this error occurs in Debug mode and that's not normal debug behavior.


WolRon(Posted 2008) [#5]
I just upgraded to V1.98 and it still happens.

Any other ideas?


GfK(Posted 2008) [#6]
I think I'm using an older version of Blitz3D (1.87)
WTF?

Why would you do that? 1.87 must be at least three years out of date.


GfK(Posted 2008) [#7]
Before ImagesCollide, check that both thisShip and thisBullet are not Null, followed by a DebugStop. Then you should be able to step through and get a better idea of what's going on.

It has to be either a nulled object, or a missing image.


WolRon(Posted 2008) [#8]
Well, trying the use of the debuglog is proving difficult since it's a looped loop of about 100 objects within a 60 hz loop. That's a lot of debug logging.
----------------
One time when I got it to MAV, I checked the Type data for thisship and thisBullet and neither were null and both had (what looked like) valid image pointers.
I don't know if it matters but neither object was actually colliding, and both FreeImage lines were commented out.
----------------
A few times I commented out both of the FreeImage lines AND the Delete lines and the program never crashed...


WolRon(Posted 2008) [#9]
What? No one here likes a challenge?


GfK(Posted 2008) [#10]
How are your types created?


WolRon(Posted 2008) [#11]
I'll post it when I get home.


WolRon(Posted 2008) [#12]
For iter = 1 To 100
	thisship.shiptype = New shipType
	thisship\ID = 2
	thisship\image = CopyImage(enemyship)
	thisship\shipx# = Rnd(-1000, 1000)
	thisship\shipy# = Rnd(-1000, 1000)
	thisship\rotation# = Rnd(0, 360)
	RotateImage thisship\image, thisship\rotation
	thisship\velocity# = -1
Next
and...
	If shoot And MilliSecs() > lastshot
		thisBullet.bullettype = New bullettype
		thisBullet\image = CopyImage(bulletimage)
		RotateImage thisBullet\image, ship\rotation
		thisBullet\bulletx# = 400
		thisBullet\bullety# = 300
		thisBullet\xangle# = Sin(ship\rotation)
		thisBullet\yangle# = -(Cos(ship\rotation))
		thisBullet\velocity# = ship\velocity + 9
		lastshot = MilliSecs() + 200
	EndIf



WolRon(Posted 2008) [#13]
OK guys, I think this is a BUG. Check this out and tell me what you think.
I've added some extra checks to narrow down the problem. Here's the code:
	For thisBullet.bullettype = Each bullettype
		exitloop = False
		For thisship.shiptype = Each shiptype
			If thisship\ID = 2
				If thisbullet\image = 0 Then DebugLog "thisbullet\image=0"
				If thisship\image = 0 Then DebugLog "thisship\image=0"
				If thisbullet=Null Then DebugLog "thisbullet=null"
				If thisship=Null Then DebugLog "thisship=null"
				If ImagesCollide(thisbullet\image, thisbullet\bulletx, thisbullet\bullety, 0, ship\image, ship\shipx, ship\shipy, 0)
				EndIf
				If ImagesCollide(ship\image, ship\shipx, ship\shipy, 0, thisship\image, thisship\shipx+400, thisship\shipy+300, 0)
				EndIf
				If ImagesCollide(thisbullet\image, thisbullet\bulletx, thisbullet\bullety, 0, thisship\image, thisship\shipx+400, thisship\shipy+300, 0)
					FreeImage thisBullet\image
					Delete thisBullet
					FreeImage thisship\image
					Delete thisship
					exitloop = True
				EndIf
			EndIf
			If exitloop = True Then Exit
		Next
	Next


Now so far in my tests, I've had the MAV occur on the FIRST ImagesCollide line (which isn't so surprising) but I've ALSO had the MAV occur on the THIRD ImagesCollide line. And you'll notice that the THIRD line uses the same images and objects that the first two do, so it SHOULD HAVE MAV'd on one of the first two if it was MY mistake, don't you agree?

Also, in case it helps, which I doubt, but here's some of the object data for the objects in question one of the times I got the MAV on the THIRD ImagesCollide line:
thisship.shiptype
 id=2
 image=25195528
 shipx#=-440.574
 shipy#=-910.735
 rotation=169
 velocity#=-1.0

thisbullet.bullettype
 image=25200528
 bulletx#=-84.7722
 bullety#=-635.957
 xangle#=0.848048
 yangle#=-0.529919
 velocity#=10.0



WolRon(Posted 2008) [#14]
I wonder if it's related to this problem posted in the bug reports forum:
Mav on ImagesCollide

Funny thing is, I don't remember performing any major updates to my system, although it's always auto-downloading MS updates...


big10p(Posted 2008) [#15]
Probably. That's the old bug I was talking about. :)


Ross C(Posted 2008) [#16]
You could try and write your own imagecollide function. Once you load your images, create an array the same size as the image, only storing whether a pixel is masked or not. That way, you only need 1 bit per pixel, and checking should be fairly quick, just comparing two arrays. And it will never be the whole array either as it's very unlikely two big images will completely overlap.

Not great, but a possible workaround :o)

That aside, i've never had any problems like this with 2d work. Very odd i've never came across this myself...


WolRon(Posted 2008) [#17]
I'm certainly not interested in rewriting the ImagesCollide function.

1. That's unnecessary work.
2. I was writing this for one of my examples on my BASIC Programming Tutorial website. And this is the more important reason. The code is supposed to be as simplified as possible. There's no point in my reinventing the wheel for a tutorial.

So, what do I do now? I have no interest in writing code on another computer. All of my tools/resources are on this one.

You know, a very odd thing occured about the same time I started getting these MAV's. Another project I was working on wouldn't load a 3D mesh I was using. But strangely, now today it loads it. Frustrating...


Dreamora(Posted 2008) [#18]
then get whql certified drivers only (no modded or anything alike) or a graphic chip with less problems.

The 6xxx series is a well known problem series which in most cases borks badly and needed manual prevention algorithms from the dev teams.
NVIDIA broke something on that chip generation.

Simply said, its a power of 2, square only series ie it follows the DX7 specification. If you follow that as well, you won't have problems or at least far less.


WolRon(Posted 2008) [#19]
OK, check this out:
Card: NVIDIA GeForce 6100
Driver Provider: NVIDIA
Driver Date: 9/18/2005
Driver version: 8.1.3.3
Driver signer: Microsoft Windows Hardware Compatibility Publisher

I think I'll see if there's an updated driver. Being certified obviously has no benefit.


Gabriel(Posted 2008) [#20]

Simply said, its a power of 2, square only series ie it follows the DX7 specification

No it isn't. Nothing since the Voodoos has required square textures.


Dreamora(Posted 2008) [#21]
Yeah that is what I wanted to believe as well.

Fact is that with the 6600GT you won't be able to load any non-power of 2 square texture.
Either due to hardware or because the drivers enforce DX7 specifications.

The 8xxx drivers, which emulate DX7 through shaders, just to mention that, do that as well.
If you play "cool kid" and use media not following DX7 specs, you can only lose, not win.


Gabriel(Posted 2008) [#22]
Fact is that with the 6600GT you won't be able to load any non-power of 2 square texture.
Either due to hardware or because the drivers enforce DX7 specifications.

I have that precise card and it loads all manner of non-square textures just fine and has done with every single driver version I've ever used. Since I used the card on a daily basis for 2.5 years, that's a lot of driver versions.

The 8xxx drivers, which emulate DX7 through shaders, just to mention that, do that as well.
If you play "cool kid" and use media not following DX7 specs, you can only lose, not win.

I have one of those too. I'll test to confirm or deny.


Gabriel(Posted 2008) [#23]
And having tested, I can confirm that you're wrong about the 8x00 series too. They also load non-square textures just fine, just as I suspected.


Dreamora(Posted 2008) [#24]
Well then you are lucky or had the correct drivers.
We have had more than 1 report on the german boards that using 150 - 160 drivers on the 8000 series + loading a texture with 2 + 256 / 4+256 means straight death for the texture for example.

The power of two square might be "solved" again but different driver versions definitely suffered that problem and as it isn't following the DX7 specs its your problem if a user runs into it because your "coolness" ignores the API specification of the API you use.

Would be as if you use Max2D with nonsquare textures ... good luck and lots of fun, you break OGL 1.2 as well.


Gabriel(Posted 2008) [#25]
I'm sorry, but I'm not lucky and I don't have the correct drivers. You're fundamentally wrong about DirectX 7 and its texture capabilities. I just this minute dug out my old DX7 book, and found the section on textures. It specifically says that DirectX7 only adjusts the size of a texture to be square if the driver does not support non-square ( and it gives the Voodoo2 and Voodoo3 as examples. ) So it is not in the DX7 specs that textures have to be square. Quite the opposite, the API actually adapts them if needs be.

Furthermore, the cards you mention *can* handle non-square textures so even if their drivers are ( as they should be ) reporting that they don't need to be resized to square, it won't be a problem because they can handle it just fine.

Now if you've seen reports that people are having problems, then there may indeed be a bug in Blitz3D or a bug in a specific driver version, but it's just plain wrong to extrapolate that out and claim things about the entire range of cards, the entire range of drivers and the DX7 API itself which just aren't true. You're going to give people some very wrong ideas, and cost them a lot of time changing code which isn't wrong. If there's a bug, it needs to be reported so that BRL can confirm or deny if it's a bug with their code or in a specific driver.


WolRon(Posted 2008) [#26]
Just an update on this problem, in case anyone cares...

After more testing with the code in question, I've found that running my program full-screen has never caused a MAV.

The problem only ever seems to be a problem running windowed.

Don't know if that helps anybody (Blitz Research) out figuring out solutions/work arounds.

Right now my work around is just running full-screen all of the time.