#ifndef QUAKE_IPC_H_
#define QUAKE_IPC_H_

enum IPCMessageType
{
	kPrintMessage,
	kPrintNumber,
	kPrintFloat,
	kInit,
	kMalloc,
	kMallocResponse,
	kFree,
	kStopAllSounds,
	kPlayMP3,
	kStopMP3,
	kFOpen,
	kFClose,
	kFRead,
	
	kS_Init,
	kS_AmbientOff,
	kS_AmbientOn,
	kS_Shutdown,
	kS_TouchSound,
	kS_ClearBuffer,
	kS_StaticSound,
	kS_StartSound,
	kS_StopSound,
	kS_PrecacheSound,
	kS_ClearPrecache,
	kS_Update,
	kS_StopAllSounds,
	kS_BeginPrecaching,
	kS_EndPrecaching,
	kS_ExtraUpdate,
	kS_LocalSound,
	
	kS_LoadSound,
	kS_LoadSoundResponse,
	
	kHalt,
	kLidHasClosed,
	kLidHasOpened,
	kLidHasClosedResponse,
	kLidHasOpenedResponse,
	
	kPing,
	kPingResponse,
	
	kFreeTime,
	kRunningOut,
	kGetReady,
	
	kStartWifi,
};

struct QuakeIPCRegion
{
	unsigned int message;
	unsigned int message_type;
};
volatile struct QuakeIPCRegion *quake_ipc_9to7 = (volatile struct QuakeIPCRegion *)0x2400000;
volatile unsigned char *quake_ipc_9to7_buf = 0;
volatile struct QuakeIPCRegion *quake_ipc_7to9 = (volatile struct QuakeIPCRegion *)0x2400000 + sizeof(struct QuakeIPCRegion);
volatile unsigned char *quake_ipc_7to9_buf = 0;

//#define WITH_PRINTF

#ifdef WITH_PRINTF
#define ARM7_PRINTF(args...) \
{\
	while(quake_ipc_7to9->message == 0xffffffff);\
	sprintf((char *)quake_ipc_7to9_buf, args);/*memset((char *)quake_ipc_7to9_buf, 0, 100);*/\
	quake_ipc_7to9->message_type = kPrintMessage;\
	quake_ipc_7to9->message = 0xffffffff;\
	while(quake_ipc_7to9->message == 0xffffffff);\
}

#else

#define ARM7_PRINTF(args...)
//#define ARM7_PRINT(string)
//#define ARM7_PRINT_NUMBER(number)

#endif

#define ARM7_PRINT(string) \
{\
	while(quake_ipc_7to9->message == 0xffffffff);\
	memcpy((void *)quake_ipc_7to9_buf, string, strlen(string) + 1);\
	quake_ipc_7to9->message_type = kPrintMessage;\
	quake_ipc_7to9->message = 0xffffffff;\
	while(quake_ipc_7to9->message == 0xffffffff);\
}

#define ARM7_PRINT_NUMBER(number) \
{\
	while(quake_ipc_7to9->message == 0xffffffff);\
	*((unsigned int *)quake_ipc_7to9_buf) = (unsigned int)number;\
	quake_ipc_7to9->message_type = kPrintNumber;\
	quake_ipc_7to9->message = 0xffffffff;\
	while(quake_ipc_7to9->message == 0xffffffff);\
}

#define ARM7_PRINT_FLOAT(number) \
{\
	while(quake_ipc_7to9->message == 0xffffffff);\
	*((float *)quake_ipc_7to9_buf) = number;\
	quake_ipc_7to9->message_type = kPrintFloat;\
	quake_ipc_7to9->message = 0xffffffff;\
	while(quake_ipc_7to9->message == 0xffffffff);\
}

#define ARM7_HALT() \
{\
	while(quake_ipc_7to9->message == 0xffffffff);\
	quake_ipc_7to9->message_type = kHalt;\
	quake_ipc_7to9->message = 0xffffffff;\
	while(1);\
}

#endif /*QUAKE_IPC_H_*/
