IonicWind Software

Aurora Compiler => Coding Help - Aurora 101 => Topic started by: J B Wood (Zumwalt) on November 18, 2006, 12:43:02 PM

Title: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 12:43:02 PM

FootballList = new(CPointerList,1);
FootballList->Create();

for (int i=0;i<15;i++)
{
#break;
pFootball = FootballList->Add(NEW(sFootball,1));


This adds the first item to the list, but when it loops to the second item, it gives access violation error, what am I doing wrong?
Thanks
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 01:38:32 PM
I assume FootbalList id defined as CPointerList *FootballList somewhere?

What are you doing after the last statement?

Here is a somewhat complete linked list example that I was using to illustrate CPointerList to someone else:


class MyAPP
{
declare _MyAPP();
declare MyAPP();
declare AddData(C3DMesh *data);
declare PrintData();
declare DeleteData();
declare GenerateData();
declare CollisionTest(),int;
CPointerList *m_pList;
}


MyAPP::MyAPP()
{
//the constructor allocates the list and creates it.
m_pList = new(CPointerList,1);
m_pList->Create();
}

MyAPP::_MyAPP()
{
//The destructor removes all objects and deletes the list
//that was allocated in the constructor.
DeleteData();
delete m_pList;
}

MyAPP::GenerateData()
{
int count = RAND(20,100);
for(int x=0;x < count;x++)
{
//allocate the 'object'
C3DMesh *data = new(C3DMesh,1);
AddData(data);
}

}

MyAPP::AddData(C3DMesh *data)
{
//add a pointer to the list
m_pList->Add(data);
}

MyAPP::PrintData()
{
//You iterate (loop) through any list
//by getting a pointer to the first list node GetFirst
//and using GetNext to get a pointer to the next node.
//A list is just a chain of data.
for(pointer pos = m_pList->GetFirst(); pos; pos=m_pList->GetNext(pos))
{
C3DMesh *pData = m_pList->GetData(pos);
//instead of printing a number we could 'draw' the mesh or change all of there positions
//pData->SetPosition(x,y,z);
//pData->Draw();
//For the moment we'll just pring the address of the mesh
print(hex$(pData));
}
}

MyAPP::DeleteData()
{
//we change and iterate so we can call delete ourselves.
//this is necessary so the destructor of each mesh object is called.
//Since CPointerList doesn't care what the pointers are it will just call delete on a void pointer
//and the class destructor won't get called.
pointer pos = m_pList->GetFirst();
while(pos)
{
C3DMesh *pData = m_pList->GetData(pos);
pos = m_pList->GetNext(pos);
delete pData;
}
m_pList->RemoveAll(false);
}

MyAPP::CollisionTest(),int
{
for(pointer pos=m_pList->GetFirst(); pos; pos=m_pList->GetNext(pos))
{
C3DMesh *pData = m_pList->GetData(pos);
//start with the current pos since there is no need to
//test the mesh twice. 
for(pointer pos2=pos; pos2; pos2=m_pList->GetNext(pos2))
{
if(pos != pos2) //don't test a mesh against itself
{
C3DMesh *pData2 = m_pList->GetData(pos2);
if(pData->ObjectCollided(pData2,false))
return true;
}
}
}
return false;
}

global sub main()
{
MyApp *theApp = new(MyApp,1);
//generate the data
theApp->GenerateData();
//print out the data
theApp->PrintData();
//delete the app class
delete theApp;
//wait for a key
while GetKey() = "";
}
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 02:03:25 PM
Yes its defined elsewhere, going to look over your example.
Making a somewhat simple sprite example that shows an animated footbal zoom across the screen.
This is the link to the avi of the same football I have animated.
Have to save it locally to play though cause IE does this funky open/show/close routine to it.
http://www.gamedevonline.com/subsite/photo_gallery/movies/FootBall.avi
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 02:11:54 PM

for (int i=0;i<15;i++)
{
#break;

pFootball = FootballList->Add(NEW(sFootball,1));
if (i==0)
{
tmpFootball="FootBall00.png";
*(sFootball)pFootball.x = 0;
*(sFootball)pFootball.y = 0;
*(sFootball)pFootball.resourceName = tmpFootball;
*(sFootball)pFootball.visible = TRUE;
}
if (i<10) && (i>0)
{
tmpFootball="FootBall0" + NumToStr(i) + ".png";
*(sFootball)pFootball.x = 0;
*(sFootball)pFootball.y = 0;
*(sFootball)pFootball.resourceName = tmpFootball;
*(sFootball)pFootball.visible = TRUE;
}
else
{
tmpFootball="FootBall" + NumToStr(i) + ".png";
*(sFootball)pFootball.x = 0;
*(sFootball)pFootball.y = 0;
*(sFootball)pFootball.resourceName = tmpFootball;
*(sFootball)pFootball.visible = TRUE;
}
}


That is what I am attempting to do, trying to track down why it thinks there is an access violation.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 02:45:13 PM
A)  Always check return values.  There is no guarantee that NEW will succeed.

B) Why this syntax?
*(sFootball)pFootball.x = 0;

Use this and see what happens.

for (int i=0;i<15;i++)
{
SFootball *pFootball = NEW(sFootball,1);
if(pFootball == NULL)
{
MessageBox(NULL,"Failed to create football","Error");
break; //break out of FOR loop
}
FootballList->Add(pFootball);
if (i==0)
{
tmpFootball="FootBall00.png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
if (i<10) && (i>0)
{
tmpFootball="FootBall0" + NumToStr(i) + ".png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
else
{
tmpFootball="FootBall" + NumToStr(i) + ".png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
}


Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 02:52:35 PM
Starting debug session...
[dll's loaded]
First chance exception: Address 0x00413DEA Access Violation.
Final chance exception: Address 0x00413DEA Access Violation.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 02:54:16 PM
This is my entire code at the moment:


#typedef UINT unsigned int;
DECLARE IMPORT,timeGetTime(),UINT;

struct sFootBall
{
int x,y; /* upper left corner of the football */
string resourceName; /* Name of the football resource */
int Visible; /* Set visible value */
}

global sub main()
{
C3DScreen Screen;
C3DCamera Camera;
CDirectInput DirectInput;
#break;
float Step = 0.1f;
float SpritePosition = 0.0f;

C3DSprite *MySprite;
CPointerList *FootballList;

string tmpFootball;

Screen.CreateWindowed(0,0,800,600,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE,0,"Flying Football - By Zumwalt",NULL,true);
Camera.Create(Screen);
DirectInput.Init(Screen);

FootballList = new(CPointerList,1);
FootballList->Create();

for (int i=0;i<15;i++)
{
sFootball *pFootball = NEW(sFootball,1);
if(pFootball == NULL)
{
MessageBox(NULL,"Failed to create football","Error");
break; //break out of FOR loop
}
FootballList->Add(pFootball);
if (i==0)
{
tmpFootball="FootBall00.png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
if (i<10) && (i>0)
{
tmpFootball="FootBall0" + NumToStr(i) + ".png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
else
{
tmpFootball="FootBall" + NumToStr(i) + ".png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
}
Screen.CloseScreen();
FootballList->RemoveAll(true);
if (MySprite) delete MySprite;
delete FootballList;
}

Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 03:34:17 PM
What line number?  See the call stack.  Also the line should be highlighted in the IDE when you run in debug mode.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 03:36:38 PM
 C3DSprite *MySprite = NULL;

You are never initializing the pointer, and then you are deleting it at the end.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 03:37:14 PM
Call stack:
Animation2d! C3DSprite@_C3DSprite + 22
Animation2d! main + 1460 File: C:\Program Files\Aurora\projects\animation2d\Football.src, Line: 68
Animation2d! _main + 48
kernel32! RegisterWaitForInputIdle + 73


Edit:
gofigure, like you said, it was the sprite object..
Back to sanity, getting some rootbeer and continuing down this path..
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 03:39:08 PM
I gave you the answer above your post.  Next time look at the call stack, Line 68 is where the crash was happening, nothing to do with the FOR loop.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 06:10:40 PM
OUI...

Its giving me an access violation error on line 95 now, and this time I looked before I am typing for help in the call stack.


FootballSprite->Load(Screen,pFootball->resourceName, 43, 42);


Screen is valid
pFootball->resourceName is valid
The image contains 1 frame, so I omit the other 2 values.
It just can't load the image into the sprite.
*scratches head*
The call stack even complains that ...

Call stack:
Animation2d! C3DSprite@Load + 48
Animation2d! main + 2106 File: C:\Program Files\Aurora\projects\animation2d\Football.src, Line: 95
Animation2d! _main + 48
kernel32! RegisterWaitForInputIdle + 73



while (!DirectInput.KeyDown(DIK_ESCAPE))
{
Screen.Clear(RGBA(32, 23, 30, 255));
Screen.BeginScene(Camera);

pos = FootballList->GetFirst();
while(pos != NULL)
{
pFootball = FootballList->GetData(pos);
pos = FootballList->GetNext(pos);
pFootball->x=pFootball->x + SpritePosition + Step* fAdjust;

DEBUG(pFootball->resourceName);
FootballSprite->Load(Screen,pFootball->resourceName, 43, 42);
FootballSprite->SetPosition(pFootball->x,pFootball->y);

Screen.Begin2D();
FootballSprite->Draw();
Screen.End2D();
Screen.RenderScene();
}
}


Anyway, still chugging on it.

Edit:
Well I know one thing that is obvious, I don't want to load a sprite on every pass...
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 06:51:14 PM
Good news.. and bad news for me...
I got it to work... BUT...
Now I need to determine if the object hits the edge of the screen and move it back, or you will never see the football... ever...
ZOOM...
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 06:58:20 PM
This code works, now to figure out how to smooth the animation.

#typedef UINT unsigned int;
DECLARE IMPORT,timeGetTime(),UINT;
declare import, GetLastError(),DWORD;
declare import, DEBUG alias OutputDebugStringA(string str);

struct sFootBall
{
int x,y; /* upper left corner of the football */
string resourceName; /* Name of the football resource */
int Visible; /* Set visible value */
}

global sub main()
{
C3DScreen Screen;
C3DCamera Camera;
CDirectInput DirectInput;
#break;
float Step = 0.1f;
float SpritePosition = 0.0f;

C3DSprite FootballSprite;
CPointerList *FootballList;

string tmpFootball;

Screen.CreateWindowed(0,0,800,600,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE,0,"Flying Football - By Zumwalt",NULL,true);
Camera.Create(Screen);
DirectInput.Init(Screen);

FootballList = new(CPointerList,1);
FootballList->Create();

float fadjust,fTarget;
fTarget = 1.0f / 60.0f * 1000.0f;
fAdjust = 1.0f;

for (int i=0;i<15;i++)
{
sFootball *pFootball = NEW(sFootball,1);
if(pFootball == NULL)
{
MessageBox(NULL,"Failed to create football","Error");
break; //break out of FOR loop
}
FootballList->Add(pFootball);

if (i<10)
{
if (i==0)
{
tmpFootball="FootBall00.png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
else
{
tmpFootball="FootBall0" + NumToStr(i) + ".png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
}
else
{
tmpFootball="FootBall" + NumToStr(i) + ".png";
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = tmpFootball;
pFootball->visible = TRUE;
}
}

int fps = 0;
int startTime;
pointer pos;

while (!DirectInput.KeyDown(DIK_ESCAPE))
{
Screen.Clear(RGBA(32, 23, 30, 255));
Screen.BeginScene(Camera);

pos = FootballList->GetFirst();
while(pos != NULL)
{
pFootball = FootballList->GetData(pos);
pos = FootballList->GetNext(pos);
//pFootball->x=pFootball->x + SpritePosition + Step* fAdjust;
pFootball->x=pFootball->x + 1;// * fAdjust;
DEBUG(pFootball->resourceName);
FootballSprite.Load(Screen,pFootball->resourceName, 43, 42);
FootballSprite.SetPosition(pFootball->x,pFootball->y);
Screen.Begin2D();
FootballSprite.Draw();
Screen.End2D();
Screen.RenderScene();
}
fAdjust = (timeGetTime() - startTime) / fTarget;
}

Screen.CloseScreen();
FootballList->RemoveAll(true);
//if (FootballSprite) delete FootballSprite;
delete FootballList;
}

Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 07:02:19 PM
Paul, how do we make the files physically compile into the binary?
They exist in my list of resources, but the exe doesn't include them inside it...
This program only runs in the compiler, but I can't take the EXE and double clidk on it without it telling me it can't find the images.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 07:51:28 PM
You're creating it as a project correct?  When compiling the project the first thing that happens is the resources get compiled so they are in the executable. 

Don't use a file extension as part of the resource name. 
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 08:00:45 PM
And you're still loading the sprite on every pass, eating up video memory each loop which will eventually cause the sprite loading to fail.

The correct way to animate an image is to use a single image with multiple frames, instead of trying to load a bunch of small ones.  But anyway your structure should have an individual C3DSprite pointer, allocate each one and load.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 18, 2006, 08:04:55 PM
It is a project, and no, it doesn't compile the resources into the project.
I know I need to optimize it, that goes without saying.
Mine won't load the resources unless I include the file extension as part of the resource call in the code.
Unless your talking about the Custom and changing the type?
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 09:14:35 PM
What I am saying is it is probably failing to load from resources in which case it tries and load it from a file.  Since your using '.png' as part of the resource identifer.  And when you run from the IDE it is finding the source image files on failure.

If it fails in all cases without the .png then you were never loading it from resources.  The identifier is just used to find the resource in the executable.  You can call it "crap" if you want and as long as the name matches it will load.

The resource compiler creates the .res file which gets linked by the linker.  If you're not getting an error in the first stage of compiling when it says "compiling resources..." then the data is there, you're just not accessing it correctly.  You can verify that the resources are included in the executable by using PE Explorer, or a similar program.  If you have VC++ you can open an executable as resources and view the resource tree from there.

Paul.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 18, 2006, 09:41:10 PM
And reading the Microsoft docs on the  D3DXCreateTextureFromResourceEx function, which is what the 3D engine uses to load a texture from resources yields this info:

Quote
    The resource being loaded must be of type RT_BITMAP or RT_RCDATA. Resource type RT_RCDATA is used to load formats other than bitmaps (such as .tga, .jpg, and .dds).

It doesn't specifically mention .png however that is not the only problem.  RCDATA resources are entered as text for the resouce compiler so the bytes of the image file would need to be converted to ASCII word values to go in between the BEGIN and END macros.  If you add a data resource you will see what I mean.

BEGIN
   0x0000 0x3f22 0x1122... etc
END

It is not too difficult to convert the file into words.

You could also try and add a custom resource with the type set to something like "PNG", which does add a data resource, however the D3DXCreateTextureFromResourceEx function will probably not be able to find it if its not an BITMAP or DATA resource.  Just something to experiment with.

Paul.
Title: Re: CPointerList issue...
Post by: sapero on November 19, 2006, 08:38:23 AM
here is a second possiblity using nasm macro incbin - include a file as raw data. The file can be any file like text, image, music...
Just define a label amd include the file:
declare file1();

#asm
file1: incbin "c:\boot.ini"
; terminate it with zero
db 0
#endasm

sub main()
{
string *lpsz = &file1;
return MessageBox(0, *lpsz, "");
}
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 19, 2006, 11:18:42 AM
Then why does it work in the IDE but doesn' t work stand alone?
I give it a number, I make it Custom, I tell it type PNG
I browse out to the file, select the file, and add it.

I have absolultely zero control over the file name when I browse out and select it from the file system, if you are talking about after I browse out, then edit the file line and remove the file extention from the file line, then ok.. maybe..

BUT, the NAME I give it is a NUMBER, the default is 1 when you click on ADD for a new resource, I change that 1 to another number that is not used.
So I am lost as to what in the earth you are talking about for the name.
Simply put, if I don't use the name in CODE with the extension, it has no clue how to use the resource, I can't use the number I gave it as the name since it doesn't know how to use that number "1" for instance wouldn't work.

I'll take step by step screen shots and post it.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 19, 2006, 11:32:55 AM
No need.  It won't work with .png files unless saved as I mentioned above. 

You are trying to use the file name as a resource identifier:

tmpFootball="FootBall0" + NumToStr(i) + ".png";

So after it fails to load them from resources it tries to load them from the current directory using that name.  Since you have physical files with those names it is working from the IDE. 

When you add a resource you do not use the file name as an identifier.  You use that number/name that is in the ID box, the one you supposidly changed from "1".  That is the identifier, not the file name.  The file name is only used by the resource compiler to add the data to the executable image.  Understand?

Resources are identified by ID and TYPE.  After they are compiled in the executable the filename no longer exisits.  Don't know how else to explain that  ::)
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 19, 2006, 11:42:36 AM
Perhaps if you just used a bitmap to get used to resources you would understand..

Add a bitmap to the resources and change the ID in the 'Add Resource' dialog to read IMAGE1,  it doesn't have to be a number. 

Load the image using:

sprite.Load(screen, "IMAGE1", width, height);

Where width and height are the dimensions of the bitmap.

Paul.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 19, 2006, 01:44:56 PM
The files don't exist in the current directory, I think I didn't mention that.
The project exists in :
C:\Program Files\Aurora\projects\animation2d

The resources exist in:
C:\Renders\FootBall

So what you are suggesting doesn't make sense to me.
If it couldn't find them and looks in the current working directory, it is a total of 6 levels off, first the IDE would have to know to move from the working directory to the c:\Renders\Football directory...

So I just don't get it.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 19, 2006, 02:09:27 PM
The IDE isn't doing anything.  Don't know how else to explain it.  The current directory is wherever the executable is and can be changed by external processes.  Probably the resource compiler is changing the directory to read the files so when you execute from the IDE it is still looking in that directory.

The point is you are not using the resource identifier correctly which is why I suggested something simple.  Start with the suggestion I gave you above your post and go from there.  The resource identifier IS NOT the filename of the resource.  The filename that you browse to is only used by the resource compiler to load in the data.  After it is compiled that name is meaningless, it is only the resource ID and TYPE that has importance.  Get that through your head and ignore the fact that it is running from the IDE.

The Load method of the sprite class is a switch .  What it does is:

#1 Try loading from resources first using the name provided as a resource identifier.

#2 If that fails try loading from a file using the name provided as a file name.

Understanding that realize that the resources are in the execuable under the ID you provide in the 'add resources' dialog.  Not under the filename that they are loaded from. So in all cases the Load method is failing under case #1 as your program is written.

Anyone else care to explain it to him?  Maybe I am just not being clear enough  :-\

Paul.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 20, 2006, 06:52:36 AM
Ok, end result for a single BMP is as follows:
(just create your own BMP and add it as a resource and replace the word "Female" with the name of your resource)
Although the sprite will work with PNG, the resource manager doesn't. It stores them in the exe, but when you try to load them, it has no clue how to handle them.
If you want to use a PNG just load it from disk.
BMP works like a champ. This code has a smooth scrolling image across the screen, no chop.


#typedef UINT unsigned int;
DECLARE IMPORT,timeGetTime(),UINT;
declare import, GetLastError(),DWORD;
declare import, DEBUG alias OutputDebugStringA(string str);

struct sFootBall
{
int x,y; /* upper left corner of the football */
string resourceName; /* Name of the football resource */
int Visible; /* Set visible value */
}

global sub main()
{
C3DScreen Screen;
C3DCamera Camera;
CDirectInput DirectInput;
#break;
float Step = 0.1f;
float SpritePosition = 0.0f;

C3DSprite FootballSprite;
CPointerList *FootballList;

Screen.CreateWindowed(0,0,800,600,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE,0,"Flying Football - By Zumwalt",NULL,true);
Camera.Create(Screen);
DirectInput.Init(Screen);

FootballList = new(CPointerList,1);
FootballList->Create();

float fadjust,fTarget;
fTarget = 1.0f / 60.0f * 1000.0f;
fAdjust = 1.0f;

sFootball *pFootball = NEW(sFootball,1);
if(pFootball == NULL)
{
MessageBox(NULL,"Failed to create football","Error");
}
FootballList->Add(pFootball);
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = "Female";
pFootball->visible = TRUE;

int fps = 0;
int startTime;
pointer pos;

while (!DirectInput.KeyDown(DIK_ESCAPE))
{
Screen.Clear(RGBA(32, 23, 30, 255));
Screen.BeginScene(Camera);
pos = FootballList->GetFirst();
while(pos != NULL)
{
pFootball = FootballList->GetData(pos);
pos = FootballList->GetNext(pos);
//pFootball->x=pFootball->x + SpritePosition + Step* fAdjust;
pFootball->x=pFootball->x + 1;// * fAdjust;
DEBUG(pFootball->resourceName);
FootballSprite.Load(Screen,pFootball->resourceName,100, 98);
FootballSprite.SetPosition(pFootball->x,pFootball->y);
Screen.Begin2D();
FootballSprite.Draw();
Screen.End2D();
Screen.RenderScene();
}
fAdjust = (timeGetTime() - startTime) / fTarget;
}

Screen.CloseScreen();
FootballList->RemoveAll(true);
delete FootballList;
}
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 20, 2006, 07:27:12 AM
Another version where the image only loads into memory 1 time, and not in the loop...

#typedef UINT unsigned int;
DECLARE IMPORT,timeGetTime(),UINT;
declare import, GetLastError(),DWORD;
declare import, DEBUG alias OutputDebugStringA(string str);

struct sFootBall
{
int x,y; /* upper left corner of the football */
string resourceName; /* Name of the football resource */
int Visible; /* Set visible value */
}

global sub main()
{
C3DScreen Screen;
C3DCamera Camera;
CDirectInput DirectInput;
#break;
float Step = 0.1f;
float SpritePosition = 0.0f;

C3DSprite FootballSprite;
CPointerList *FootballList;

Screen.CreateWindowed(0,0,800,600,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE,0,"Flying Football - By Zumwalt",NULL,true);
Camera.Create(Screen);
DirectInput.Init(Screen);

FootballList = new(CPointerList,1);
FootballList->Create();

float fadjust,fTarget;
fTarget = 1.0f / 60.0f * 1000.0f;
fAdjust = 1.0f;

sFootball *pFootball = NEW(sFootball,1);
if(pFootball == NULL)
{
MessageBox(NULL,"Failed to create football","Error");
}
FootballList->Add(pFootball);
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = "Female";
pFootball->visible = TRUE;

int fps = 0;
int startTime;
pointer pos;

pos = FootballList->GetFirst();
pFootball = FootballList->GetData(pos);
pos = FootballList->GetNext(pos);
//pFootball->x=pFootball->x + SpritePosition + Step* fAdjust;
DEBUG(pFootball->resourceName);
FootballSprite.Load(Screen,pFootball->resourceName,100, 98);
while (!DirectInput.KeyDown(DIK_ESCAPE))
{
Screen.Clear(RGBA(32, 23, 30, 255));
Screen.BeginScene(Camera);
pFootball->x=pFootball->x + 1;// * fAdjust;
FootballSprite.SetPosition(pFootball->x,pFootball->y);
Screen.Begin2D();
FootballSprite.Draw();
Screen.End2D();
Screen.RenderScene();
fAdjust = (timeGetTime() - startTime) / fTarget;
}
Screen.CloseScreen();
FootballList->RemoveAll(true);
delete FootballList;
}
Title: Re: CPointerList issue...
Post by: Kale on November 20, 2006, 07:38:04 AM
Quote from: Jonathan (zumwalt) Wood on November 20, 2006, 06:52:36 AM
Although the sprite will work with PNG, the resource manager doesn't. It stores them in the exe, but when you try to load them, it has no clue how to handle them.

I've also had no luck embedding PNGs into exes for sprite use. ???
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 20, 2006, 07:48:21 AM
The file is embeded in the exe, its using it that I have a problem with.
Here is more code, this one causes the image to scroll back and forth depending on if it reaches the edge of the screen.
This is now my base code for my space invaders :)

#typedef UINT unsigned int;
#define screen_width 800
#define screen_height 600

DECLARE IMPORT,timeGetTime(),UINT;
declare import, GetLastError(),DWORD;
declare import, DEBUG alias OutputDebugStringA(string str);

struct sFootBall
{
int x,y; /* upper left corner of the football */
string resourceName; /* Name of the football resource */
int Visible; /* Set visible value */
}

global sub main()
{
C3DScreen Screen;
C3DCamera Camera;
CDirectInput DirectInput;
#break;
float Step = 0.1f;
float SpritePosition = 0.0f;

C3DSprite FootballSprite;
CPointerList *FootballList;

Screen.CreateWindowed(0,0,screen_width,screen_height,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE,0,"Flying Football - By Zumwalt",NULL,true);
Camera.Create(Screen);
DirectInput.Init(Screen);

FootballList = new(CPointerList,1);
FootballList->Create();

float fadjust,fTarget;
fTarget = 1.0f / 60.0f * 1000.0f;
fAdjust = 1.0f;

sFootball *pFootball = NEW(sFootball,1);
if(pFootball == NULL)
{
MessageBox(NULL,"Failed to create football","Error");
}
FootballList->Add(pFootball);
pFootball->x = 0;
pFootball->y = 0;
pFootball->resourceName = "Female";
pFootball->visible = TRUE;

int fps = 0;
int startTime;
pointer pos;
int scrollState=0;

pos = FootballList->GetFirst();
pFootball = FootballList->GetData(pos);
pos = FootballList->GetNext(pos);
//pFootball->x=pFootball->x + SpritePosition + Step* fAdjust;
DEBUG(pFootball->resourceName);
FootballSprite.Load(Screen,pFootball->resourceName,100, 98);
while (!DirectInput.KeyDown(DIK_ESCAPE))
{
Screen.Clear(RGBA(32, 23, 30, 255));
Screen.BeginScene(Camera);

if (pFootball->x+100 > Screen_Width)
{
scrollState=1;

}
else if (pFootball->x < 0)
{
scrollState=0;
}


switch (scrollState)
{
case 0:
pFootball->x=pFootball->x + 1;
case 1:
pFootball->x=pFootball->x - 1;
}

FootballSprite.SetPosition(pFootball->x,pFootball->y);
Screen.Begin2D();
FootballSprite.Draw();
Screen.End2D();
Screen.RenderScene();
fAdjust = (timeGetTime() - startTime) / fTarget;

}
Screen.CloseScreen();
FootballList->RemoveAll(true);
delete FootballList;
}


Ignore the fact I got the word football all over the place, that was an ill begotten effort of mine.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 20, 2006, 11:34:40 AM
Quote from: Kale on November 20, 2006, 07:38:04 AM
Quote from: Jonathan (zumwalt) Wood on November 20, 2006, 06:52:36 AM
Although the sprite will work with PNG, the resource manager doesn't. It stores them in the exe, but when you try to load them, it has no clue how to handle them.

I've also had no luck embedding PNGs into exes for sprite use. ???

Kale,
If you read my description above you will see that you can't directly use them in a resource like a bitmap.  For whatever reason Microsoft decided to use the resource type RCDATA for other types of image files in the d3dx library.  So to use a .png file from resources it has to be converted to an ASCII file first, just like the old DATA statements in BASIC.  Each word in the .png file is outputted to the text file as a hex value.  Then you can cut an paste that data in between the BEGIN and END block of a "Data" resource.  Only then will the D3DXCreateTextureFromResourceEx function load it.  Which is what the sprite class uses to load the image from resources.

Not my choice of course.  It is just the way DirectX handles it.

Paul.
Title: Re: CPointerList issue...
Post by: Kale on November 20, 2006, 12:39:41 PM
Ah, i see. Thanks.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 20, 2006, 01:26:34 PM
If I ever get a free moment I'll whip up a little converter.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 20, 2006, 01:32:07 PM
Totally no rush Paul.
Title: Re: CPointerList issue...
Post by: Kale on November 20, 2006, 03:18:54 PM
Quote from: Paul Turley on November 18, 2006, 09:41:10 PM
And reading the Microsoft docs on the  D3DXCreateTextureFromResourceEx function, which is what the 3D engine uses to load a texture from resources yields this info:

Quote
    The resource being loaded must be of type RT_BITMAP or RT_RCDATA. Resource type RT_RCDATA is used to load formats other than bitmaps (such as .tga, .jpg, and .dds).

It doesn't specifically mention .png however that is not the only problem.  RCDATA resources are entered as text for the resouce compiler so the bytes of the image file would need to be converted to ASCII word values to go in between the BEGIN and END macros.  If you add a data resource you will see what I mean.

BEGIN
   0x0000 0x3f22 0x1122... etc
END

It is not too difficult to convert the file into words.

You could also try and add a custom resource with the type set to something like "PNG", which does add a data resource, however the D3DXCreateTextureFromResourceEx function will probably not be able to find it if its not an BITMAP or DATA resource.  Just something to experiment with.

Paul.

I tried converting a PNG file to hex words and copied into my project as a resource. Still no success. :( The attached file is the output of the convertor i've written.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 20, 2006, 06:24:27 PM
It probably won't work anyway, I tried a resource as a gif and a jpg also, using the scalable image type, and it didn't recognize any gif or any jpg, the only thing it recognizes is a bmp. Thats just my 2 cents.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 20, 2006, 06:47:31 PM
Give me some time.   How did you read write the words?  You have to remember endian order if your reading the file a byte at a time,
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 25, 2006, 02:14:16 PM
Ok, now on to remove, how do I remove an item from the list from any point in the list as long as I know its list position?
objlist->remove(pos)??
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 25, 2006, 02:23:46 PM
By position I assume you meant the pointer returned by the GetNext method.  And if so then that would be correct.

objlist->remove(pos,TRUE);

Would remove the node and delete the associated pointer.  If you are storing classes then you need to delete the associated pointer yourself.

See CList in the users guide which is the base class for CPointerList.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 25, 2006, 02:28:29 PM
Ok, this is what I got that is working, but for some reason, my invaders slow down incrimentally as I remove them from the list.

posGroup=objList->GetFirst();
while(posGroup != NULL)
{
pObject = objList->GetData(posGroup);
pObject->Invader.SetPosition(pObject->x,pObject->y);
if (pObject->currentHP > 0)
{
pObject->Invader.Draw();
posGroup = objList->GetNext(posGroup);
}
else
{
objList->Remove(posGroup,true);
posGroup = objList->GetFirst();
}


Which is very odd, the bullet should disappear but it is not, the aliens should continue down there original speed but there not, I got something funky going on, can't nail it down yet, has to be a logical error, since there is no physical errors causing a crash.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 25, 2006, 02:43:09 PM
Because your using GetFirst after a remove which causes the loop to continue


...else
{
     posGroup =  objList->Remove(posGroup,true);
     
}

Remove returns the next element of the list or NULL if the list end has been reached.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 25, 2006, 02:48:37 PM
But this causes it to crash when I kill an invader, the getfirst allows it to work.
But it doesn't work against the saucer, since when I remove it, it is the only one in the list.
OUI...
I got so far with this to be hitting a brick wall now.

So, what I need to do, is remove the invaders from the list, have the list shrink in size somehow with out the remaining invaders, then continue.
If the list is empty, delete the list and not reuse it.
If I just make the invaders invisible, the movement routine still makes them check against the edges, so I would have to look into both the collision routine and the movement routine to work around the fact that they are visible or not.

I know, this part can't be that hard, it has to be something simple I am over looking.
Title: Re: CPointerList issue...
Post by: Ionic Wind Support Team on November 25, 2006, 03:25:21 PM
I only gave you a solution to the code you presented.  You have to check the return of Remove for NULL to be sure you don't dereference a null pointer.  If it is the last element of the list then don't access it.

There is no 'shinking and growing' of a list, it is stored as a linked chain of pointers.  Once you remove the node it is removed from the chain.

Paul.
Title: Re: CPointerList issue...
Post by: J B Wood (Zumwalt) on November 25, 2006, 04:48:14 PM
Took a dinner break, now getting back on this, I think I'll just check against an internal structure element that I am already using and deal with the list that way.
I don't understand what is wrong in my movement logic at the moment, but once I get the attack logic done I'll rework the movement logic some.
I haven't decided how to handle sound yet, I don't think you have directsound implimented yet.
Title: Re: CPointerList issue...
Post by: John Syl. on November 26, 2006, 05:11:20 AM
 I think your problem is that as you delete you delay then ending of the loop by restarting the loop, so any further routines are not serviced.ÂÃ,  Taken to the extreme if there is always some thing to deleted it never gets out of the loop untill everything is deleted.ÂÃ,  What I do isÂÃ,  get the data, check if it is to be deleted, if it is to be deleted I then get the next pointer and save in a temp variable, remove the pointer including data, then set the pointer variable to the temp value and continue.
this will then got to the end of the list allowing an exit for the rest of the routines to be serviced at a reasonable time.

If it is not deleted just get the next pointer.

A quick mod to your code gives :-

posGroup=objList->GetFirst();
while(posGroup != NULL)
{
pObject = objList->GetData(posGroup);
pObject->Invader.SetPosition(pObject->x,pObject->y);
if (pObject->currentHP > 0)
{
pObject->Invader.Draw();
posGroup = objList->GetNext(posGroup);
}
else
{
ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  tempptr=objList->GetNext(posGroup);
objList->Remove(posGroup,true);
posGroup = tempptr;
}

If that makes sense.

John