r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

shadwolf
14-Jan-2005
[167x11]
for example if I say walk is frame 0 10 for human but for aliens 
in my game I nead to have only frames 0 to 5 for the walk I need 
to make 2 animation list and 2 animation switches to handle human 
(main caracter of my game for example) and alien
If i have alien type 1 alien type 2 alien type 3 etc... and all of 
them with different set of animation it could be very heavy task 
to handle all of them using MD2 but that's not our purpose in fact 
 :)
data-type sensitive editor  but normally rebol is datatype unsensive 
 :)
so or we allways ue struct! to typify our variables (wich can't be 
reuse). In C if I make SDM2Header *a, *b; a content and b content 
(physical memory localtion) will not be the same
in rebol a: SMD2Header and b: SMD2Header will point to the same memory 
chunk ...
>> a: SMD2Header
>> b: SMD2Header
>> a/m_iMagicNum: 1234234
== 1234234
>> probe b/m_iMagicNum
1234234
== 1234234
>>
and that normal becaus in C to initialise data I will use a malloc 
call witch will attrubute to a and b on the same based type different 
memory location
in my example program that exploite the SMD2Header strucure we can 
see:
//-------------------------------------------------------------
//- Load
//- Loads an MD2 model from file
//-------------------------------------------------------------
bool CMd2::Load(const char * szFilename)
{
	unsigned char * ucpBuffer = 0;
	unsigned char * ucpPtr = 0;
	unsigned char * ucpTmpPtr = 0; 
	int iFileSize = 0;
	FILE * f;
	
	if(!(f = fopen(szFilename, "rb")))
	{
		APP->Log(COLOR_RED, "Could not open MD2 file %s", szFilename);
		return false;
	}

	//check file size and read it all into the buffer
	int iStart = ftell(f);
	fseek(f, 0, SEEK_END);
	int iEnd = ftell(f);
	fseek(f, 0, SEEK_SET);
	iFileSize = iEnd - iStart;

	//Allocate memory for whole file
	ucpBuffer = new unsigned char[iFileSize];
	ucpPtr = ucpBuffer;

	if(!ucpBuffer)
	{

  APP->Log(COLOR_RED, "Could not allocate memory for %s", szFilename);
		return false;
	}

	//Load file into buffer
	if(fread(ucpBuffer, 1, iFileSize, f) != (unsigned)iFileSize)
	{
		APP->Log(COLOR_RED, "Could not read from %s", szFilename);
		delete [] ucpBuffer;
		return false;
	}

	//close the file, we don't need it anymore
	fclose(f);

	//get the header
	memcpy(&m_Head, ucpPtr, sizeof(SMD2Header));

	//make sure it is a valid MD2 file before we get going
	if(m_Head.m_iMagicNum != 844121161 || m_Head.m_iVersion != 8)
	{
		APP->Log(COLOR_RED, "%s is not a valid MD2 file", szFilename);
		delete [] ucpBuffer;
		return false;
	}
	
	ucpTmpPtr = ucpPtr;
	ucpTmpPtr += m_Head.m_iOffsetFrames;

	//read the frames
	m_pFrames = new SMD2Frame[m_Head.m_iNumFrames];
	
	for(int i = 0; i < m_Head.m_iNumFrames; i++)
	{
		float fScale[3];
		float fTrans[3];
		m_pFrames[i].m_pVerts = new SMD2Vert[m_Head.m_iNumVertices];
		//expand the verices
		memcpy(fScale, ucpTmpPtr, 12);
		memcpy(fTrans, ucpTmpPtr + 12, 12);
		memcpy(m_pFrames[i].m_caName, ucpTmpPtr + 24, 16);
		ucpTmpPtr += 40;
		for(int j = 0; j < m_Head.m_iNumVertices; j++)
		{

   //swap y and z coords to convert to the proper orientation on screen

   m_pFrames[i].m_pVerts[j].m_fVert[0] = ucpTmpPtr[0] * fScale[0] + 
   fTrans[0];

   m_pFrames[i].m_pVerts[j].m_fVert[1] = ucpTmpPtr[2] * fScale[2] + 
   fTrans[2];

   m_pFrames[i].m_pVerts[j].m_fVert[2] = ucpTmpPtr[1] * fScale[1] + 
   fTrans[1];
			m_pFrames[i].m_pVerts[j].m_ucReserved = ucpTmpPtr[3];
			ucpTmpPtr += 4;
		}
		
	}

	//Read in the triangles
	ucpTmpPtr = ucpPtr;
	ucpTmpPtr += m_Head.m_iOffsetTriangles;
	m_pTriangles = new SMD2Tri[m_Head.m_iNumTriangles];
	memcpy(m_pTriangles, ucpTmpPtr, 12 * m_Head.m_iNumTriangles);

	//Read the U/V texture coords
	ucpTmpPtr = ucpPtr;
	ucpTmpPtr += m_Head.m_iOffsetTexCoords;
	m_pTexCoords = new SMD2TexCoord[m_Head.m_iNumTexCoords];
	
	short * sTexCoords = new short[m_Head.m_iNumTexCoords * 2];
	memcpy(sTexCoords, ucpTmpPtr, 4 * m_Head.m_iNumTexCoords);

	for(i = 0; i < m_Head.m_iNumTexCoords; i++)
	{

  m_pTexCoords[i].m_fTex[0] = (float)sTexCoords[2*i] / m_Head.m_iSkinWidthPx;

  m_pTexCoords[i].m_fTex[1] = (float)sTexCoords[2*i+1] / m_Head.m_iSkinHeightPx;
	}
	
	delete [] sTexCoords;

	//Read the skin filenames
	ucpTmpPtr = ucpPtr;
	ucpTmpPtr += m_Head.m_iOffsetSkins;
	m_pSkins = new SMD2Skin[m_Head.m_iNumSkins];
	
	//Load textures
	for(i = 0; i < m_Head.m_iNumSkins; i++)
	{
		memcpy(m_pSkins[i].m_caSkin, ucpTmpPtr, 64);
		//hack off the leading parts and just get the filename
		char * szEnd = strrchr(m_pSkins[i].m_caSkin, '/');
		
		if(szEnd)
		{
			szEnd++;
			strcpy(m_pSkins[i].m_caSkin, szEnd);
		}

		m_pSkins[i].m_Image.Load(m_pSkins[i].m_caSkin);
		ucpTmpPtr += 64;
	}
		
	delete [] ucpBuffer;
	return true;
}
countainer class :
class CMd2 : public CModel
{
public:

	//Set skin to one of the files specified in the md2 files itself
	void SetSkin(unsigned int uiSkin);
	//Set skin to a different image
	void SetSkin(CImage& skin);

	//Load the file
	bool Load(const char * szFilename);
	
	//Render file at the initial position
	void Render();
	//Render the file at a certain frame
	void Render(unsigned int uiFrame);


 //Animate the md2 model (start and end frames of 0 and 0 will loop 
 through the WHOLE model

 void Animate(float fSpeed = 30.0f, unsigned int uiStartFrame = 0, 
 unsigned int uiEndFrame = 0, bool bLoop = true);

	//constructors/destructo
	CMd2();
	CMd2(const char * szFile);
	~CMd2();

private:
	
	CTimer m_Timer;
	//file header information
	SMD2Header m_Head; 
	//Frame information
	SMD2Frame * m_pFrames;
	//Triangles
	SMD2Tri * m_pTriangles;
	//Texure coords
	SMD2TexCoord * m_pTexCoords;
	//Skin files
	SMD2Skin * m_pSkins;
	//Interpolated vertices
	SMD2Vert * m_pVerts;
	//Current skin
	unsigned int m_uiSkin;
	//Using a custom skin?
	bool m_bIsCustomSkin;
	//The custom skin
	CImage * m_pCustSkin;

};
eFishAnt
14-Jan-2005
[178]
you go too fast for me...;-)  I have to find some time this weekend 
to play with the first toys...
shadwolf
14-Jan-2005
[179x2]
so you make a SDM2Header *m_Header; to declare your header type from 
structure SMD3Header, then you read the correct emont of data in 
the file  storing it to ucpPtr then you init m_Header it using  memcpy(&m_Head, 
ucpPtr, sizeof(SMD2Header));
if you want to load 3 MD2 files you need only to make other main 
pointer to the information you retrieve from the file
Ladislav
14-Jan-2005
[181]
Shadwolf: "in rebol a: SMD2Header and b: SMD2Header will point to 
the same memory chunk ..."


yes, but you should do it as follows: a: make struct! SMD2Header 
b: make struct! SMD2Header
shadwolf
14-Jan-2005
[182x4]
in rebol you will need to load 3 files to declare SDM2Header_f1 SMD2Header_f3 
and SMD2Header_f3 with for both the stricly identical content tso 
your recoding 3 times or X times the same thing ...
I'm not an expert on struct! far of that (wel in C yes but in REBOL 
no and I think it's because I'm not using load/library capability 
until now) but that's a good discution to point to difficulties on 
this kind of task and I hope help rebol Core to have a bettre handling 
of that
ladyslav on declaration statement REBOL need me to give him the datas 
I ust tryed what you just propose:
>> a: make struct! SMD2Header
** Script Error: Invalid argument: (missing value)
** Near: a: make struct! SMD2Header
Ladislav
14-Jan-2005
[186x2]
a: make struct! SMD2Header none ; or [some values here]
if you supply none, you generate an "empty" struct
Cyphre
14-Jan-2005
[188]
shadwolf: have you read this? http://www.rebol.com/docs/library.html
shadwolf
14-Jan-2005
[189]
yes so I had to read the file first then make my variable content 
basing me on a precut of the rode datas from file to be allowed to 
fill my variable content on inititialisation
Ladislav
14-Jan-2005
[190]
you can create an empty struct using NONE and fill it using the read 
data
shadwolf
14-Jan-2005
[191x2]
yes I read it cyphre long time ago when it was recently published 
but one thing that's apear to me dangerous is for example use:
a-struct: make struct! [
        in-string [string!] "Input string"
        in-int [integer!] "Input integer"
    ] ["This is input" 42]
Cyphre
14-Jan-2005
[193]
what is dangerous on that?
shadwolf
14-Jan-2005
[194x4]
while in C my struct is struct a-struct { char in-string[25]; int 
in-int; }
how can I be certain using string! unlimited REBOL countainer to 
correctly feet with the char 25 strictly sized contained in C
no contained but countainer
the dangerous thing is that with rebal I can over pass easly the 
25 limitation and write every where in the countigous memeryy area 
;)
Cyphre
14-Jan-2005
[198]
If I understand you well you have tu create string! of length 25 
in rebol for your purpose.
shadwolf
14-Jan-2005
[199x2]
that's not a direct use for me I intent thru thi discution to enlight 
some problems that every one can infront using rebol external library 
capability
or reusing C/C++/VB binary struct based data type (like MD2 file 
format)
Cyphre
14-Jan-2005
[201]
It is on you to not override the length of the string IMO You have 
to deal with this as you are working with static  memory so it is 
not a problem of Rebol itself. I think you ca easily write 'dangerous' 
code when dealing with DLL interfaces ;) Making error in this are 
usually ends up with crash (memory acces violation).
shadwolf
14-Jan-2005
[202]
yes I know that ;)
eFishAnt
14-Jan-2005
[203]
maybe that IS a good point to make it harder to crash at the interface. 
 The toughest code to write is always the in-between stuff.
shadwolf
14-Jan-2005
[204x2]
the main purpose I purchase is to enhance and simplify the rebol 
interaction with external lib and C/C++/VB structure binary file 
based
and that's why I can here to expose the difficulties I see on that 
issue and try with you to get infos or solutions to propose to Carl
Cyphre
14-Jan-2005
[206]
so what is your solution? Do you know how to improve the interface?
eFishAnt
14-Jan-2005
[207]
It takes a guru level REBOLer who is also profishant in C to write 
an interface to a DLL, although there are becoming more and simple 
examples...but maybe shadwolf wants to make it a graphical process?
shadwolf
14-Jan-2005
[208]
not that far .... lol
eFishAnt
14-Jan-2005
[209]
an ez-dll.r which takes in a .h and a .dll and lets you play, experiment, 
and try to controll any .dll might be a fun project.
shadwolf
14-Jan-2005
[210]
Cyphre not at all and that's why I came here first to expose the 
problems then to seek solutions with you
eFishAnt
14-Jan-2005
[211]
I have written a research proposal grant for such a tool...
Cyphre
14-Jan-2005
[212]
Interfacing with lower-level naguages (such as C) from Rebol looks 
a bit harder but when you gain more experience with it (=no crashes 
anymore ;)) you realize it works logically. I was also dissapointed 
for the firt time I tried to use some DLL. But now I'm more optimistic. 
The only think I miss is the callback handling.
eFishAnt
14-Jan-2005
[213]
grant proposal (ah, was writing backwards in French)
shadwolf
14-Jan-2005
[214]
eFishAnt your right !!! in a C# ressource explorer motion (wich you 
can see in Shardevolp IDE for example ) could be an amazing thing 
and even more if the same code all you to do so on evry OS rebol 
stands in
[unknown: 5]
14-Jan-2005
[215]
Cyphre - you should let Carl know that you want callback handling. 
 I know several of us have wanted that.
eFishAnt
14-Jan-2005
[216]
Josh wrote a simple hello example .dll a while back, including how 
to write the .dll...I started to mention this to him, but we talk 
about lots of things...so not done yet...guess I can tell him to 
read this.