Memory Access Violation
Blitz3D Forums/Blitz3D Programming/Memory Access Violation
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
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.
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.
@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.
I just upgraded to V1.98 and it still happens.
Any other ideas?
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.
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.
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...
What? No one here likes a challenge?
How are your types created?
I'll post it when I get home.
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
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
I wonder if it's related to this problem posted in the bug reports forum:
Mav on ImagesCollideFunny thing is, I don't remember performing any major updates to my system, although it's always auto-downloading MS updates...
Probably. That's the old bug I was talking about. :)
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...
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...
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.
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.
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.
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.
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.
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.
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.
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.
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.