//==============================================================================
//
// Snake
// -----
// http://www.masterspace.biz/andreschnabel/
// 2006 by André Schnabel (thefrogs@web.de)
//
//==============================================================================

// utils.c

#include "utils.h"

#ifdef DREAMCAST
	#include <SDL/SDL_dreamcast.h>
#endif

font_t font, fontBlack;

// Shows an error and quits the program
void Error(const char *message)
{
	printf("Error: %s\n", message);
	fflush(stdout);
	exit(1);
}

// Initializes all the library stuff
void SysInit(void)
{
	int result;
	Uint32 scrFlags = SCR_FLAGS;
	pos_t fontOffset = { 0, 0 };
	dimensions_t fontOneCharDim = { 8, 13 };
		
	// Initialize the SDL
	result = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
	if(result == -1)
		Error("Can't init SDL!");
	
	// Video stuff
	SDL_WM_SetCaption(CAPTION, NULL);
	
	if(fullscreen)
		scrFlags += SDL_FULLSCREEN;
	
	screen = SDL_SetVideoMode(SCR_W, SCR_H, SCR_BPP, scrFlags);
	if(!screen)
		Error("Unable to set video mode!");
	
	if(fullscreen)
		SDL_Delay(2000);
	
	SDL_ShowCursor(SDL_FALSE);
	
#ifndef NO_SOUND
	// Audio stuff
	Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048);
	if(result == -1)
		Error("Can't start sound!");	
#endif

#ifdef DREAMCAST

  SDL_JoystickOpen(0);
  SDL_JoystickOpen(1);
  SDL_JoystickOpen(2);
  SDL_JoystickOpen(3);
  
  SDL_DC_MapKey(0,SDL_DC_START,SDLK_RETURN); //START button
  SDL_DC_MapKey(0,SDL_DC_UP,SDLK_UP);
  SDL_DC_MapKey(0,SDL_DC_DOWN,SDLK_DOWN);
  SDL_DC_MapKey(0,SDL_DC_LEFT,SDLK_LEFT);
  SDL_DC_MapKey(0,SDL_DC_RIGHT,SDLK_RIGHT);
  SDL_DC_MapKey(0,SDL_DC_L,SDLK_PAUSE); //R button
  SDL_DC_MapKey(0,SDL_DC_A,SDLK_RETURN); //a button
  SDL_DC_MapKey(0,SDL_DC_R,SDLK_ESCAPE); //L button
  
  SDL_DC_MapKey(1,SDL_DC_UP,SDLK_w);
  SDL_DC_MapKey(1,SDL_DC_DOWN,SDLK_s);
  SDL_DC_MapKey(1,SDL_DC_LEFT,SDLK_a);
  SDL_DC_MapKey(1,SDL_DC_RIGHT,SDLK_d);
  SDL_DC_MapKey(1,SDL_DC_L,SDLK_PAUSE); //R button
  
  SDL_DC_MapKey(2,SDL_DC_UP,SDLK_t);
  SDL_DC_MapKey(2,SDL_DC_DOWN,SDLK_g);
  SDL_DC_MapKey(2,SDL_DC_LEFT,SDLK_f);
  SDL_DC_MapKey(2,SDL_DC_RIGHT,SDLK_h);
  SDL_DC_MapKey(2,SDL_DC_L,SDLK_PAUSE); //R button
  
  SDL_DC_MapKey(3,SDL_DC_UP,SDLK_i);
  SDL_DC_MapKey(3,SDL_DC_DOWN,SDLK_k);
  SDL_DC_MapKey(3,SDL_DC_LEFT,SDLK_j);
  SDL_DC_MapKey(3,SDL_DC_RIGHT,SDLK_l);
  SDL_DC_MapKey(3,SDL_DC_L,SDLK_PAUSE); //R button

  //Dreamcast delay...
  SDL_Delay(20);
  SDL_Event event;
  while(SDL_PollEvent(&event))
   SDL_Delay(20);
#endif
	
	// Get our key array
	keys = SDL_GetKeyState(NULL);
	
	font = InitFont("fontmap.bmp", fontOffset, fontOneCharDim);
	fontBlack = InitFont("fontmapBlack.bmp", fontOffset, fontOneCharDim);
}

// Shutdowns all the library stuff
void SysQuit(void)
{
	FreeFont(&font);
	FreeFont(&fontBlack);

#ifndef NO_SOUND
	Mix_CloseAudio();
#endif
	
	// Shutdown the SDL
	SDL_Quit();
}

// Very basic input stuff
void SysInput(void)
{
	static SDL_Event event;
	
	// Check if the exit button was pressed	
	while(SDL_PollEvent(&event))
		if(event.type == SDL_QUIT)
			done = true;
	
	// Update the array of keys
	SDL_PumpEvents();
	
	if(keys[SDLK_ESCAPE])
		done = true;
}

// Flips the buffers
inline void SysFlip(void)
{
	SDL_Flip(screen);
}

// Restarts the video subsystem
void SysRestartVid(void)
{
	Uint32 flags = SCR_FLAGS;
	
	if(fullscreen)
		flags += SDL_FULLSCREEN;
	
	screen = SDL_SetVideoMode(SCR_W, SCR_H, SCR_BPP, flags);	
	if(!screen)
		Error("Unable to set video mode!");
}

// Loads an image out of a bitmap file, converts it to display format and
// applies a colorkey if useAlpha is true.
SDL_Surface *LoadImage(const char *filename, boolean useAlpha)
{
	char fullFname[256];
	SDL_Surface *temp, *image;
	char errMsg[20];
	Uint32 magenta;
	
	strcpy(fullFname, "images/");
	strcat(fullFname, filename);
	
	// Try to load the image out of the file
	temp = SDL_LoadBMP(fullFname);
	// No success?
	if(!temp)
	{
		sprintf(errMsg, "Can't load %s!", filename);
		Error(errMsg);
	}
	
	// Convert it to display format, for faster blitting
	image = SDL_DisplayFormat(temp);
	SDL_FreeSurface(temp);
	
	// Apply colorkey if necessary
	if(useAlpha)
	{
		magenta = SDL_MapRGB(image->format, 255, 0, 255);
		SDL_SetColorKey(image, SDL_SRCCOLORKEY, magenta);
	}
	
	return image;
}

#ifndef NO_SOUND
// Loads an wave file and checks whether it was sucessfull
Mix_Chunk *LoadWAV(const char *filename)
{
	char fullFname[256];	
	Mix_Chunk *chunk;
	
	strcpy(fullFname, "audio/");
	strcat(fullFname, filename);
	
	chunk = Mix_LoadWAV(fullFname);
	if(!chunk)
	{
		char errMsg[100];
		sprintf(errMsg, "Can't load sound: %s!", fullFname);
		Error(errMsg);
	}
	
	return chunk;
}

// Loads an music file and checks whether it was sucessfull
Mix_Music *LoadMUS(const char *filename)
{
	char fullFname[256];	
	Mix_Music *mus;
	
	strcpy(fullFname, "audio/");
	strcat(fullFname, filename);
	
	mus = Mix_LoadMUS(fullFname);
	if(!mus)
	{
		char errMsg[100];
		sprintf(errMsg, "Can't load music: %s!", fullFname);
		Error(errMsg);
	}
	
	return mus;
}
#endif

boolean IsPressed(keystate_t kState)
{
	return (kState == KSTATE_PRESSED);
}

void UpdateKey(keystate_t *kState, int keyId)
{
	if(keys[keyId])
	{
		if(*kState == KSTATE_RELEASED)
			*kState = KSTATE_PRESSED;
		else
			*kState = KSTATE_UNCHANGED;
	}
	else
		*kState = KSTATE_RELEASED;
}
