atm i'm writing code simultaneously for windows, mac, linux, psp and the ti c6xx platforms.
basically i use a global platfrom definition file for general stuff, which contains things like this:
Code: Select all
#ifdef WIN32
#define S_WIN32 1
#elif defined LINUX
#define S_LINUX 1
#elif defined MAC
#define S_MAC 1
#elif defined C6X
#define S_C6X 1
#elif defined DAVINCI
#define S_DAVINCI 1
#elif defined PSP
#define S_PSP 1
#else
#ERROR !no platform defined!
#endif
#ifdef S_DEBUG
/**
* Output debug string.
* @see Tracer::sf_TraceDebug()
*/
#define DBG( text ) utils::Tracer::sf_TraceDebug( text );
/**
* Output debug string, printf style.
* @see Tracer::sf_TraceDebugPrintf()
*/
#define DBGPF( format, args ) utils::Tracer::sf_TraceDebugPrintf( format, args );
//assert
#if defined S_WIN32
#define s_assertf { __asm int 3 }
#elif defined S_LINUX
//ok here's something stupid: when using single stepping
//using gdb, it will just step over the s_assert and
//ignore the SIGTRAP raised.
//It won't ignore it however if running, or if stepping
//over a function that contains the assert inside.
//Keep this in mind when debugging!
#define s_assertf { asm("int $3"); }
#elif defined S_MAC
#define s_assertf Debugger();
#elif defined S_C6X
#define s_assertf { asm("int 3") }
#elif defined S_PSP
#define s_assertf { asm("int 3"); }
#endif
/**
* Platform-independent assertion.
* Gets optimized away in release builds.
*/
#define s_assert( expr ) { if( !( expr ) ) s_assertf }
#else
then i write interfaces for all things that are really platform specific: threads, criticalsections, waitable objects, sockets, basic ui stuff... and implement these for every platform.
eg the criticalsection interface looks like this:
Code: Select all
class CriticalSection
{
public:
/**
* Constructor.
*/
CriticalSection();
/**
* Destructor.
*/
~CriticalSection();
/**
* Enters the CriticalSection.
* If another thread has entered before, the method
* blocks until that thread leaves it again.
* Else the method returns immedeately.
*/
void mf_Enter() const;
/**
* Trie to enter the CriticalSection.immedeately.
* If another thread has entered before, the method
* returns false and doe not enter, else it returns true
* after entering.
* @return false if the CriticalSection isn't free
*/
bool mf_bTryEnter() const;
/**
* Leave the CriticalSection.
* Make sure not to call this on a CriticalSection that
* has not been entered.
*/
void mf_Leave() const;
private:
#if defined S_WIN32
char m_hMutex[ 24 ]; //!< aka win32 CriticalSection
#elif defined S_C6X
LCK_Handle m_hMutex;
#elif defined S_LINUX
mutable pthread_mutex_t m_hMutex;
#elif defined S_PSP
SceUID m_hMutex;
#endif
CriticalSection (const CriticalSection&);
const CriticalSection& operator= (const CriticalSection&);
};
all methods are then implemented in psp_criticalsection.cpp/win32_criticalsection.cpp etc, so while building i just have to include the right file while compiling
the rest of the code uses the interfaces only, so all application code is completely platform independent.
i don't use fancy uis mostly, except on pc maybe and then i use qt which is pretty cross-platform, but opengl should do it too.
it's a *lot* of work, takes an equal lot of testing, but the pc/dsp part i have to code for my job anyway so i have the time..
once the code is there it's a dream to use: i first write it in my favorite ide on pc, test it for mem leaks etc, and when it works, i just use it on the platform i want, and i know it will work there too without surprises
hopefully this is a bit of interest for you, i'm not really allowed to post this code []-]