Thursday, 21 August 2008
Simple and fun
http://FantasticContraption.com
Solve the different puzzles is really fun (after #12 get's harder), but compare your own solutions with your friends it's just awesome.
After solving the #13 compare your solution with mine (as a feature, it allows to save the solution and gives you a link you can send to your friends):
#13 - http://FantasticContraption.com/?designId=684627
Edited:
#14 - http://FantasticContraption.com/?designId=686419
#16 - http://FantasticContraption.com/?designId=687704
I have to say that it's not easy to catch my attention right now, but this game it's so fun, I couldn't avoid playing it and sending the link to my friends.
Enjoy!
J.
Monday, 21 July 2008
Working at Prince of Persia
As some of you know, I am in the final development stage of the Prince of Persia project, and as result of it, I am quite busy right now (and I will be until it is released).
I like the last months of the projects, I usually work like crazy, but it´s the moment when you see everything coming together for the first time since the start of the project, and it is really beautiful.
There are some cool Prince of Persia videos in GameTrailers, even if it´s not your type of game, I think it does worth a click to see them.
Check it here : http://www.gametrailers.com/game/6739.html
That´s it, just a quick post to show signs of life!!!
J.
Sunday, 16 March 2008
XML based script for use in tools
Some months ago, I was asked to find a way to store user profiles and other internal application data so it could be saved for later use and shared between the application users, not a big amount of information, but enough to avoid standard .ini files.
I had been using TinyXml in the past, but I do not really like the interface to access or store information (not really a problem of TinyXml but the xml itself), so I decided to use it but also to implement a small layer over it, to have a better interface from the application and at the same time hide as much as possible the standard xml usage.
Some small issues appeared though, as I had to encode regional characters into the xml files, so UTF-8 was selected as the xml encoding. I created a couple of functions to convert from ansi to utf8 and from utf8 to ansi, so save standard local text was possible (this is not intended to be a unicode universal conversion tool, but with few changes it can be used with any language and codepage).
Once the encoding problem was solved, I started to work on the intermediate layer, to enable the applications to store and retrieve data without any xml knowledge and doing it with the less possible amount of effort (the objective was to allow users to store and retrieve data, not to force then to learn the xml internals).
The result is a small class called DataScript (the name clearly indicates the intended use, it is not a script for decision making, it is just for data storage).
As a small example of use, look at this code to store and load some bits of information:
<code>
****** SAVE ******
DataScript root;
{
DataScript usersDataSection = root.addSection("USERS_DATA");
for (int i=0; i<mNumUsers; i++)
{
DataScript userSection = usersDataSection.addSection("USER");
userSection.setString("NAME", mUserData[i].mName.c_str());
userSection.setUInt("ID", mUserData[i].mId);
}
}
root.saveFile("DataScriptTest.sb");
******* LOAD *******
DataScript root;
if (root.loadFile("DataScriptTest.sb"))
{
DataScript usersSection = root["USERS_DATA"];
int numUsers = usersSection.count();
for (int i=0; i<numUsers; i++)
{
DataScript userData = usersSection[i];
sUserData * user = mUserData.addUser();
user->mName = userData.getString("NAME", "");
user->mId = userData.getUInt("ID", 0);
}
}
****** XML File generated *******
<?xml version="1.0" encoding="UTF-8" ?>
<Root>
<USERS_DATA>
<USER>
<NAME Str="Jaico" />
<ID UInt="1001" />
</USER>
<USER>
<NAME Str="Cherno" />
<ID UInt="2002" />
</USER>
</USERS_DATA>
</Root>
<code/>
Feel free to contact me if you need something like this, I will be happy to help in any way my limited free time allows me. I still have to search a place to store it and post a link to it, but in the meantime I can send it by email to anyone interested, just send me an email to cherno.olivares at the google mail system.
And this is all for this weekend, I have a really busy months in the horizon, but I will do my best to continue writing some articles.
Have a great day!
J.
Monday, 10 March 2008
Test with windows writer
I've just downloaded windows writer with the last messenger update and I'm testing it to see if I can avoid the pain of editing the blog online.
If this works will publish a couple of articles I have ready on my computer (waiting for a decent blog editor) in the following days (or maybe weekend, as I am a bit busy during the week).
Edited : Looks like editing the blog it is much easier using Windows Writer, try it if you have not yet (do not expect miracles though) .
Jaime
Monday, 12 November 2007
RTTI : How to import and export interfaces from classes in a cheap and easy way
I have been working on this for some time and tried different solutions but this one I am posting here is the one I like the most. It has some problems tho, as it does not work for DLL's unless you ask the DLL itself for the interface you are requesting, but in the general case, it is very simple to use and does not add any runtime cost (apart from a small amount of memory for each interface type).
Here is the code (I have formatted it a bit to fit into the blog, but I can send you the original file upon request to my email address)
That's all for now!
Cheers!
J.
//****************************************************************************
// Templatized RTTI
// Date(dd/mm/yyy): 22/06/2007
// Author: Jaime C. Olivares - cherno.olivares#gmailDOTYOUKNOW
//****************************************************************************
#ifndef _NW_RTTI_H_
#define _NW_RTTI_H_
typedef intptr_t NWRttiTypeId;
//----------------------------------------------------------------------------
// The RTTI itself
// It is a simple idea:
// The address of a static member of a templatized class
//----------------------------------------------------------------------------
template '<'class T'>' class NWRtti
{
public:
static inline NWRttiTypeId getTypeId();
private:
static int mDummyVar;
};
template '<'class T'>' /*static*/ int NWRtti'<'T'>'::mDummyVar = 0;
template '<'class T'>' /*static*/ inline NWRttiTypeId NWRtti'<'T'>'::getTypeId()
{
// avoids compiler to optimize and return same addr for all types
++mDummyVar;
// return the address of this member fn as RTTI
return (NWRttiTypeId)&getTypeId;
}
#define RTTI_TYPE_ID(T) static inline NWRttiTypeId getTypeId() \
{return NWRtti'<'T'>'::getTypeId();} // use this macro to have TypeId in classes
//----------------------------------------------------------------------------
// Helper class to inherit from by classes exporting interfaces
//----------------------------------------------------------------------------
class NWInterfaceProvider
{
public:
NWInterfaceProvider() {}
virtual ~NWInterfaceProvider() {}
template '<'class T'>' inline T * getInterface();
protected:
//derived classes must implement this fn
virtual void * getInterfaceFromID(NWRttiTypeId _typeId)=0;
template '<'class T'>' inline T * NWInterfaceProvider::getInterface()
{
return (T *) getInterfaceFromID(NWRtti'<'T'>'::getTypeId());
}
#endif //_NW_RTTI_H_
//****************************************************************************
// Example
//****************************************************************************
//----------------------------------------------------------------------------
// Some interfaces we want share
//----------------------------------------------------------------------------
//struct IEncoder
//{
// virtual unsigned int getEncodingCaps()=0;
// ...
//
// RTTI_TYPE_ID(IEncoder)
//};
//
//struct IVideoEncoder
//{
// virtual unsigned int getVideoEncoderCaps()=0;
// ...
//
// RTTI_TYPE_ID(IVideoEncoder)
//}
//
//struct IVideoEncoderH264
//{
// virtual int getVideoCodecH264KeyFramePeriod()=0;
// ...
//
// RTTI_TYPE_ID(IVideoEncoderH264)
//}
//----------------------------------------------------------------------------
// The exporter (or it's base class if any) inherits from NWInterfaceProvider
//----------------------------------------------------------------------------
//class VideoEncoderDicasH264 : public NWInterfaceProvider
//{
//public:
// ...
//
//protected:
// virtual void * getInterfaceFromID(NWRttiTypeId _iid);
// // Implement this fn to provide the valid interfaces
// //private:
// ...
//};
//----------------------------------------------------------------------------
// Exporter class fn (this class inherits from the interface): //----------------------------------------------------------------------------
// /*virtual*/ void * VideoEncoderDicasH264::getInterfaceFromID(NWRttiTypeId _iid)
//{
// if(_iid == IVideoEncoderH264::getTypeId())
// {
// return static_cast'<'IVideoEncoderH264*'>'(this);
// }
// else if(_iid == IVideoEncoder::getTypeId())
// {
// return static_cast'<'IVideoEncoder*'>'(this);
// }
// else if(_iid == IEncoder::getTypeId())
// {
// return static_cast'<'IEncoder*'>'(this);
// }
//
// return NULL; // if no base class just return NULL or
// //return Inherited::getInterfaceFromID(_iid); // if base class has other interfaces
//}
//----------------------------------------------------------------------------
// External use
//----------------------------------------------------------------------------
//void test()
//{
// VideoEncoderDicasH264 encoderObj;
//
// encoderObj.init();
//
// IEncoder * encoder = encoderObj.getInterface
// if(encoder)
// {
// unsigned int caps = encoder->getEncodingCaps();
// }
//
// IVideoEncoder * videoEncoder = encoderObj.getInterface'<'IVideoEncoder'>'();
// if(videoEncoder)
// {
// unsigned int caps = videoEncoder->getVideoEncoderCaps();
// }
//
// IVideoEncoderH264 * encH264 = encoderObj.getInterface'<'IVideoEncoderH264'>'();
// if(videoEncoderH264)
// {
// int keyFramePeriod = videoEncoderH264->getVideoCodecH264KeyFramePeriod();
// }
//
// encoderObj.shutdown();
//}
Relocated to Canada, back to business
Here I am, back from some months of virtual absence due to the new job I got at Montreal (Canada).
But now that I have arrived and got my new intertnet connection I am ready to start some posts.
First one to come... RTTI
See u around!
J.
Monday, 2 July 2007
This blog is starting... be patient
During the following weeks I'm going to write a bit about real c++ projects I'm working on.
I will cover different programming areas, from GUI to game AI or game architecture.
Some examples that will come soon are :
- A good coding standard
- User resistant init/done pattern
- Dynamic software architecture and tools needed to implement it :
..........- Cheap RTTI
..........- Interfaces, exporting and importing functionality with no type dependencies (apart from the interface itself)
..........- State based machines : Easy and versatile implementation
..........- State stack
..........- Messaging systems, channel or message oriented
..........- Script system for in-game use (to allow data driven designs)
-Some FrontEnd tools
..........- XML based script : A fast and easy script for tools
..........- Class delegates, or how to store and call class member pointers from other classes
..........- Property based Frontend / Gui
..........- Remote Frontend for use at diverse software applications
Try to enjoy the reading as much as I'm going to enjoy writing it!
Some feedback would be appreciated if you are interested on any subject.
Cheers!
Cherno