/* Copyright (C) 2002 Sony Computer Entertainment America */
/*        All Rights Reserved.  SCEA Confidential         */

#ifndef LIBUTIL_H
#define LIBUTIL_H

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <eetypes.h>
#include <eeregs.h>

#ifdef __cplusplus
extern "C" {
#endif

  /* system */
#define MODULE_PATH_HD "host0:/usr/local/sce/iop/modules/"
#define MODULE_PATH_CD "cdrom0:\\IOP\\"
#define SUFFIX_CD ";1"


/* File used for run-time CD decision. Not present on debug, 
   and can be renamed to test CD code on T10K. */
#define HDD_FILE "host0:/usr/local/sce/bin/dssim"

/* Call this once at the beginning of all apps. 
   Initializes QueryCD (by testing for HDD_FILE),
   then calls SystemReset.*/
void SystemInit();

/* If flag, initialize the CD.  Then reboot IOP. */
void SystemReset(int resetcd_flag);

/* Exit, and load new elf (works with CD) */
void SystemExit(char *file);

/* Run-time query whether to use CD or not. */
int QueryCD();

/* Generate a new string properly for cd/tool */
char* FixFile(const char*hd_path, const char*cd_path, const char*file);

/* Load .irx module, from dir above unless dir set by user (below).*/
int LoadIRX(char *name);

/* Load .irx module, from dir above unless dir set by user (below).
   Pass parameters to irx module. */
int LoadIRXParam(char *name, const char* param, int len);

/* Manually set the dir from which to load .irx modules. */
void SetIRXPath(char *path);

/* Get the current .irx load dir. */
char *GetIRXPath();  // user can query changed IRX path

#define ERROR printf
#define LOG if (QueryCD()==0) printf
  //#define LOG 

// kernel
int CreateSimpleSema();
int StartSimpleThread( void *entry, int priority);
int sceGsSyncVMultithread(int val);

#define UNCACHED_ACCEL(x) ((u_int)(x)|0x30000000)
#define _prefetch0(addr) asm volatile ("pref 0, 0(%0)": :"r"(addr))
#define _prefetch64(addr) asm volatile ("pref 0, 64(%0)": :"r"(addr))
#define _prefetch128(addr) asm volatile ("pref 0, 128(%0)": :"r"(addr))
#define _prefetch768(addr) asm volatile ("pref 0, 768(%0)": :"r"(addr))

  // does not work for CW???
#define _prefetch(offset, addr) asm volatile ("pref 0, %1(%0)": :"r"(addr),"I"(offset))

int readFile(const char *filename, unsigned char **data, int *size);

  // these are wrappers of memalign() and free()
  // re-implement them if you wish to use your own memory management
void* mymemalign(int alignment, int size);
void myfree(void* data);

u_long128* quadmemcpy(u_long128* dest, u_long128* src, int quadcount);


// math
// fast packing functions
  u_long128 packquadw(u_int val);
  u_long128 packquadh(u_short val);
  u_long128 packquadb(u_char val);

#define RAD2DEG (180.0f/M_PI)
#define DEG2RAD (M_PI/180.0f)

#define myabs(x) (((x)>0) ? (x):(-(x)))
#define max(a,b) (((a > (b)) ? (a) : (b)))
#define min(a,b) (((a < (b)) ? (a) : (b)))
#define limit(x,a,b) (x)=min(max((a),(x)),(b))
float frand();

#define sceVector sceVu0FVECTOR __attribute__ ((aligned (16)))


// pad
#include <libpad.h>
/* pad data struct */
typedef struct {
  unsigned int cnt; /* updata count*/
  unsigned int status; /* pad status */
  unsigned short button; /* 16 buttons */
  unsigned short button2; /* 16 buttons */
  unsigned char r3h;
  unsigned char r3v;
  unsigned char l3h;
  unsigned char l3v;
  unsigned char r3h2;
  unsigned char r3v2;
  unsigned char l3h2;
  unsigned char l3v2;
  unsigned char Lright;
  unsigned char Lleft;
  unsigned char Lup;
  unsigned char Ldown;
  unsigned char Rup;
  unsigned char Rright;
  unsigned char Rdown;
  unsigned char Rleft;
  unsigned char L1;
  unsigned char R1;
  unsigned char L2;
  unsigned char R2;
} scePadData; 

int scePadOpen(int port);
int scePadReadSimple(int port, scePadData*data, int size);

#define SCE_PADL (SCE_PADLup|SCE_PADLdown|SCE_PADLright|SCE_PADLleft)
#define SCE_PADR (SCE_PADRup|SCE_PADRdown|SCE_PADRright|SCE_PADRleft)

// timer
#define timerTicksPerFrame 9500

typedef struct {
  tT_MODE t0Mode;
  tT_COUNT t0Count;
} EETimer;

void timerInit(EETimer* t);

void timerStart(EETimer* t);

int timerStop(EETimer* t);


#ifdef __cplusplus
}
#endif

#endif // LIBUTIL_H
