/*  uiloop.c: (c) 2002 sibn

    This file is part of GWiz.

    GWiz is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    GWiz is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with GWiz; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* Do, the stuff, that buys me beer. 
   Re, the guys that sells me beer. 
   Mi, the guy, that buys the beer. 
   Fa, the distance to my beer. 
   So, I think I'll have a beer.
   La, lalalalala beer.
   Ti, no thanks I'm drinking beer.
   And that brings us back to (looks at empty glass) doh! */

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <stdlib.h>
#include "gwiz.h"
#include "uiloop.h"
#include "prefsdat.h"
#include "text.h"
#include "maploader.h"
#include "menus.h"
#include "camp.h"
#include "keyconfig.h"
#include "playerpawn.h"
#include "castle.h"
#include "playergen.h"
#include "keynames.h"
#include "joystick.h"

extern GwizApp gwiz;

void UILoop (void)
{
    SDL_Event event;
    SDL_Rect canvasdimensions;
    int tilechanged = 0;
    
    canvasdimensions.x = 0;
    canvasdimensions.y = 0;
    canvasdimensions.h = gwiz.canvas->h;
    canvasdimensions.w = gwiz.canvas->w;
    gwiz.x = 128; /* Ground zero. (heh.  not any more. now it's 128. */
    gwiz.y = 128;
    gwiz.z = 1;
    gwiz.face = NORTH;
    
    EnterCastle();
    MapWalls();
    
    while (SDL_WaitEvent (&event) != 0)
	{
	    SDL_Event *e = &event;

	    if (EventIsCancel (e))
		{
		    Camp();
		}
	    if (EventIsUp (e))
		{
		    MovePlayer (FWD);
		    tilechanged = 1;
		}
	    if (EventIsStepBack (e))
		{
		    MovePlayer (BKWD);
		    tilechanged = 1;
		}
	    if (EventIsStepLeft (e))
		{
		    SlidePlayer (0);
		    tilechanged = 1;
		}
	    if (EventIsStepRight (e))
		{
		    SlidePlayer (1);
		    tilechanged = 1;
		}
	    if (EventIsLeft (e))
		{
		    SetFace (0);
		}
	    if (EventIsRight (e))
		{
		    SetFace (1);
		}
	    if (EventIsFta (e))
		{
		    SetFace (1);
		    SDL_FillRect (gwiz.canvas, &canvasdimensions,
				  0);
		    MapWalls();
		    SDL_Flip (gwiz.canvas);
		    SDL_Delay(100); /* watch yourself turn :) */
		    SetFace (1);
		}
	    if (EventIsOk (e))
		{
		    Act();
		    tilechanged = 1;
		}
	    if (event.key.keysym.sym == SDLK_F12)
		{
		    KeyConfig ();
		}

	   SDL_FillRect (gwiz.canvas, &canvasdimensions, 0);
	   MapWalls();
	    if (tilechanged)
		OnTileChanged();
	    tilechanged = FALSE;
	}
}

void MapWalls(void)
{
    SDL_Rect frect;
    frect.x = 0;
    frect.y = gwiz.canvas->h - gwiz.floor[0]->h;
    frect.w = gwiz.canvas->w;
    frect.h = gwiz.floor[0]->h;

    /* disabled until I can find a clean way to make it work.
    SDL_BlitSurface (gwiz.floor[(gwiz.ffi ? 0 : 1)], NULL, gwiz.canvas, &frect);
    gwiz.ffi = (gwiz.ffi ? 0 : 1);
    */

    switch (gwiz.face)
	{
	case NORTH:
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & NWALL) == NWALL)
		RenderWall (1);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & NDOOR) == NDOOR)
		RenderDoor (1);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & NWALL) == NWALL)
		RenderWall (2);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & NDOOR) == NDOOR)
		RenderDoor (2);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & NWALL) == NWALL)
		RenderWall (3);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & NDOOR) == NDOOR)
		RenderDoor (3);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & WWALL) == WWALL)
		RenderWall (4);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & WDOOR) == WDOOR)
		RenderDoor (4);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & WWALL) == WWALL)
		RenderWall (5);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & WDOOR) == WDOOR)
		RenderDoor (5);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & EWALL) == EWALL)
		RenderWall (6);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & EDOOR) == EDOOR)
		RenderDoor (6);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & EWALL) == EWALL)
		RenderWall (7);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & EDOOR) == EDOOR)
		RenderDoor (7);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & NWALL) == NWALL)
		RenderWall (8);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & NDOOR) == NDOOR)
		RenderDoor (8);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) == NWALL)
		RenderWall (9);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & NDOOR) == NDOOR)
		RenderDoor (9);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & NWALL) == NWALL)
		RenderWall (10);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & NDOOR) == NDOOR)
		RenderDoor (10);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) == WWALL)
		RenderWall (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & WDOOR) == WDOOR)
		RenderDoor (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) == EWALL)
		RenderWall (12);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & EDOOR) == EDOOR)
		RenderDoor (12);
	    break;
	case EAST:
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & EWALL) == EWALL)
		RenderWall (1);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & EDOOR) == EDOOR)
		RenderDoor (1);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & EWALL) == EWALL)
		RenderWall (2);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & EDOOR) == EDOOR)
		RenderDoor (2);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & EWALL) == EWALL)
		RenderWall (3);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & EDOOR) == EDOOR)
		RenderDoor (3);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & NWALL) == NWALL)
		RenderWall (4);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y-1] & NDOOR) == NDOOR)
		RenderDoor (4);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & NWALL) == NWALL)
		RenderWall (5);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & NDOOR) == NDOOR)
		RenderDoor (5);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & SWALL) == SWALL)
		RenderWall (6);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & SDOOR) == SDOOR)
		RenderDoor (6);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & SWALL) == SWALL)
		RenderWall (7);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & SDOOR) == SDOOR)
		RenderDoor (7);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & EWALL) == EWALL)
		RenderWall (8);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & EDOOR) == EDOOR)
		RenderDoor (8);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) == EWALL)
		RenderWall (9);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & EDOOR) == EDOOR)
		RenderDoor (9);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & EWALL) == EWALL)
		RenderWall (10);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & EDOOR) == EDOOR)
		RenderDoor (10);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) == NWALL)
		RenderWall (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & NDOOR) == NDOOR)
		RenderDoor (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) == SWALL)
		RenderWall (12);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & SDOOR) == SDOOR)
		RenderDoor (12);
	    break;
	case SOUTH:
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & SWALL) == SWALL)
		RenderWall (1);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & SDOOR) == SDOOR)
		RenderDoor (1);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & SWALL) == SWALL)
		RenderWall (2);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & SDOOR) == SDOOR)
		RenderDoor (2);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & SWALL) == SWALL)
		RenderWall (3);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & SDOOR) == SDOOR)
		RenderDoor (3);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & EWALL) == EWALL)
		RenderWall (4);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y+1] & EDOOR) == EDOOR)
		RenderDoor (4);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & EWALL) == EWALL)
		RenderWall (5);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & EDOOR) == EDOOR)
		RenderDoor (5);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & WWALL) == WWALL)
		RenderWall (6);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & WDOOR) == WDOOR)
		RenderDoor (6);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & WWALL) == WWALL)
		RenderWall (7);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & WDOOR) == WDOOR)
		RenderDoor (7);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & SWALL) == SWALL)
		RenderWall (8);
	    if ((gwiz.map.tile[gwiz.x+1][gwiz.y] & SDOOR) == SDOOR)
		RenderDoor (8);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) == SWALL)
		RenderWall (9);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & SDOOR) == SDOOR)
		RenderDoor (9);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & SWALL) == SWALL)
		RenderWall (10);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & SDOOR) == SDOOR)
		RenderDoor (10);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) == EWALL)
		RenderWall (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & EDOOR) == EDOOR)
		RenderDoor (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) == WWALL)
		RenderWall (12);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & WDOOR) == WDOOR)
		RenderDoor (12);
	    break;
	case WEST:
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & WWALL) == WWALL)
		RenderWall (1);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & WDOOR) == WDOOR)
		RenderDoor (1);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & WWALL) == WWALL)
		RenderWall (2);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & WDOOR) == WDOOR)
		RenderDoor (2);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & WWALL) == WWALL)
		RenderWall (3);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & WDOOR) == WDOOR)
		RenderDoor (3);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & SWALL) == SWALL)
		RenderWall (4);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y+1] & SDOOR) == SDOOR)
		RenderDoor (4);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & SWALL) == SWALL)
		RenderWall (5);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & SDOOR) == SDOOR)
		RenderDoor (5);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & NWALL) == NWALL)
		RenderWall (6);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y] & NDOOR) == NDOOR)
		RenderDoor (6);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & NWALL) == NWALL)
		RenderWall (7);
	    if ((gwiz.map.tile[gwiz.x-1][gwiz.y-1] & NDOOR) == NDOOR)
		RenderDoor (7);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & WWALL) == WWALL)
		RenderWall (8);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y+1] & WDOOR) == WDOOR)
		RenderDoor (8);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) == WWALL)
		RenderWall (9);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & WDOOR) == WDOOR)
		RenderDoor (9);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & WWALL) == WWALL)
		RenderWall (10);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y-1] & WDOOR) == WDOOR)
		RenderDoor (10);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) == SWALL)
		RenderWall (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & SDOOR) == SDOOR)
		RenderDoor (11);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) == NWALL)
		RenderWall (12);
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & NDOOR) == NDOOR)
		RenderDoor (12);
	    break;
	}
    SDL_Flip (gwiz.canvas);
}

void RenderWall (int pos)
{
    SDL_Rect src, dest;
    src.x = 0;
    src.y = 0;
    switch (pos)
	{
	case 1:
	    src.w = gwiz.wall[0]->w;
	    src.h = gwiz.wall[0]->h;
	    dest.x = 40;
	    dest.y = 178;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[0], &src, gwiz.canvas, &dest);
	    break;
	case 2:
	    src.w = gwiz.wall[0]->w;
	    src.h = gwiz.wall[0]->h;
	    dest.x = 280;
	    dest.y = 178;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[0], &src, gwiz.canvas, &dest);
	    break;
	case 3:
	    src.w = gwiz.wall[0]->w;
	    src.h = gwiz.wall[0]->h;
	    dest.x = 520;
	    dest.y = 178;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[0], &src, gwiz.canvas, &dest);
	    break;
	case 4:
	    src.w = gwiz.wall[1]->w;
	    src.h = gwiz.wall[1]->h;
	    dest.x = -80;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[1], &src, gwiz.canvas, &dest);
	    break;
	case 5:
	    src.w = gwiz.wall[1]->w;
	    src.h = gwiz.wall[1]->h;
	    dest.x = 160;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[1], &src, gwiz.canvas, &dest);
	    break;
	case 6:
	    src.w = gwiz.wall[2]->w;
	    src.h = gwiz.wall[2]->h;
	    dest.x = 520;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[2], &src, gwiz.canvas, &dest);
	    break;
	case 7:
	    src.w = gwiz.wall[2]->w;
	    src.h = gwiz.wall[2]->h;
	    dest.x = 760;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[2], &src, gwiz.canvas, &dest);
	    break;
	case 8:
	    src.w = gwiz.wall[3]->w;
	    src.h = gwiz.wall[3]->h;
	    dest.x = -320;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[3], &src, gwiz.canvas, &dest);
	    break;
	case 9:
	    src.w = gwiz.wall[3]->w;
	    src.h = gwiz.wall[3]->h;
	    dest.x = 160;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[3], &src, gwiz.canvas, &dest);
	    break;
	case 10:
	    src.w = gwiz.wall[3]->w;
	    src.h = gwiz.wall[3]->h;
	    dest.x = 640;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[3], &src, gwiz.canvas, &dest);
	    break;
	case 11:
	    src.w = gwiz.wall[4]->w;
	    src.h = gwiz.wall[4]->h;
	    dest.x = 0;
	    dest.y = 0;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[4], &src, gwiz.canvas, &dest);
	    break;
	case 12:
	    src.w = gwiz.wall[5]->w;
	    src.h = gwiz.wall[5]->h;
	    dest.x = 640;
	    dest.y = 0;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.wall[5], &src, gwiz.canvas, &dest);
	    break;
	}
}

void RenderDoor (int pos)
{
    SDL_Rect src, dest;
    src.x = 0;
    src.y = 0;
    switch (pos)
	{
	case 1:
	    src.w = gwiz.wall[0]->w;
	    src.h = gwiz.wall[0]->h;
	    dest.x = 40;
	    dest.y = 178;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[0], &src, gwiz.canvas, &dest);
	    break;
	case 2:
	    src.w = gwiz.wall[0]->w;
	    src.h = gwiz.wall[0]->h;
	    dest.x = 280;
	    dest.y = 178;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[0], &src, gwiz.canvas, &dest);
	    break;
	case 3:
	    src.w = gwiz.wall[0]->w;
	    src.h = gwiz.wall[0]->h;
	    dest.x = 520;
	    dest.y = 178;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[0], &src, gwiz.canvas, &dest);
	    break;
	case 4:
	    src.w = gwiz.wall[1]->w;
	    src.h = gwiz.wall[1]->h;
	    dest.x = -80;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[1], &src, gwiz.canvas, &dest);
	    break;
	case 5:
	    src.w = gwiz.wall[1]->w;
	    src.h = gwiz.wall[1]->h;
	    dest.x = 160;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[1], &src, gwiz.canvas, &dest);
	    break;
	case 6:
	    src.w = gwiz.wall[2]->w;
	    src.h = gwiz.wall[2]->h;
	    dest.x = 520;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[2], &src, gwiz.canvas, &dest);
	    break;
	case 7:
	    src.w = gwiz.wall[2]->w;
	    src.h = gwiz.wall[2]->h;
	    dest.x = 760;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[2], &src, gwiz.canvas, &dest);
	    break;
	case 8:
	    src.w = gwiz.wall[3]->w;
	    src.h = gwiz.wall[3]->h;
	    dest.x = -320;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[3], &src, gwiz.canvas, &dest);
	    break;
	case 9:
	    src.w = gwiz.wall[3]->w;
	    src.h = gwiz.wall[3]->h;
	    dest.x = 160;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[3], &src, gwiz.canvas, &dest);
	    break;
	case 10:
	    src.w = gwiz.wall[3]->w;
	    src.h = gwiz.wall[3]->h;
	    dest.x = 640;
	    dest.y = 60;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[3], &src, gwiz.canvas, &dest);
	    break;
	case 11:
	    src.w = gwiz.wall[4]->w;
	    src.h = gwiz.wall[4]->h;
	    dest.x = 0;
	    dest.y = 0;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[4], &src, gwiz.canvas, &dest);
	    break;
	case 12:
	    src.w = gwiz.wall[5]->w;
	    src.h = gwiz.wall[5]->h;
	    dest.x = 640;
	    dest.y = 0;
	    dest.w = src.w;
	    dest.h = src.h;
	    SDL_BlitSurface (gwiz.door[5], &src, gwiz.canvas, &dest);
	    break;
	}
}

void SetFace (int turn)
{
    /* i didn't #define LEFT and RIGHT.  But they're 0 and 1. :) */
    switch (turn)
	{
	case 0:
	    if (gwiz.face == NORTH)
		gwiz.face = WEST;
	    else
		gwiz.face--;
	    break;
	case 1:
	    if (gwiz.face == WEST)
		gwiz.face = NORTH;
	    else
		gwiz.face++;
	    break;
	}
}

void MovePlayer (int direction)
{
    switch (gwiz.face)
	{
	case NORTH:
	    if ((direction == FWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) != NWALL))
		gwiz.y--;
	    else if ((direction == FWD) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & NWALL ) == NWALL)
		Ouch();
	    if ((direction == BKWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) != SWALL))
		gwiz.y++;
	    else if ((direction == BKWD) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) == SWALL)
		Ouch();
	    break;
	case EAST:
	    if ((direction == FWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) != EWALL))
		gwiz.x++;
	    else if ((direction == FWD) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) == EWALL)
		Ouch();
	    if ((direction == BKWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) != WWALL))
		gwiz.x--;
	    else if ((direction == BKWD) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) == WWALL)
		Ouch();
	    break;
	case SOUTH:
	    if ((direction == FWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) != SWALL))
		gwiz.y++;
	    else if ((direction == FWD) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) == SWALL)
		Ouch();
	    if ((direction == BKWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) != NWALL))
		gwiz.y--;
	    else if ((direction == BKWD) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) == NWALL)
		Ouch();
	    break;
	case WEST:
	    if ((direction == FWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) != WWALL))
		gwiz.x--;
	    else if ((direction == FWD) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) == WWALL))
		Ouch();
	    if ((direction == BKWD) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) != EWALL))
		gwiz.x++;
	    else if ((direction == BKWD) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) == EWALL))
		Ouch();
	    break;
	}
}

void SlidePlayer (int direction)
{
    /* Note I could easily have used a "SetFace(0);MovePlayer(FWD);
       SetFace(1) combination to do this work, but it would probably be
       obvious that the direction were changing on a lot of machines. */
    switch (gwiz.face)
        {
	case NORTH:
	    if ((direction == 0) && 
		((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) != WWALL))
		gwiz.x--;
	    else if ((direction == 0) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) == WWALL)
		Ouch();
	    if ((direction == 1) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) != EWALL))
		gwiz.x++;
	    else if ((direction == 1) &&
		     (gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) == EWALL)
		Ouch();
	    break;
	case EAST:
	    if ((direction == 0) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) != NWALL))
		gwiz.y--;
	    else if ((direction == 0) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) == NWALL))
		Ouch();
	    if ((direction == 1) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) != SWALL))
		gwiz.y++;
	    else if ((direction == 1) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) == SWALL))
		Ouch();
	    break;
	case SOUTH:
	    if ((direction == 0) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) != EWALL))
		gwiz.x++;
	    else if ((direction == 0) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & EWALL) == EWALL))
		Ouch();
	    if ((direction == 1) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) != WWALL))
		gwiz.x--;
	    else if ((direction == 1) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & WWALL) == WWALL))
		Ouch();
	    break;
	case WEST:
	    if ((direction == 0) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) != SWALL))
		gwiz.y++;
	    else if ((direction == 0) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & SWALL) == SWALL))
		Ouch();
	    if ((direction == 1) &&
		((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) != NWALL))
		gwiz.y--;
	    else if ((direction == 1) &&
		     ((gwiz.map.tile[gwiz.x][gwiz.y] & NWALL) == NWALL))
		Ouch();
	    break;
	}
}

void Act(void)
{
    /* I considered other ways than "doorinvolved," but ultimately, this
       seemed like a reasonable solution at the time.  It works, and it's
       easy to read. */
    int doorinvolved = 0;
    if (gwiz.face == NORTH)
	{
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & NDOOR) == NDOOR)
		{
		    gwiz.y--;
		    doorinvolved = 1;
		}
	}
    if (gwiz.face == EAST)
	{
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & EDOOR) == EDOOR)
		{
		    gwiz.x++;
		    doorinvolved = 1;
		}
	}
    if (gwiz.face == SOUTH)
	{
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & SDOOR) == SDOOR)
		{
		    gwiz.y++;
		    doorinvolved = 1;
		}
	}
    if (gwiz.face == WEST)
	{
	    if ((gwiz.map.tile[gwiz.x][gwiz.y] & WDOOR) == WDOOR)
		{
		    gwiz.x--;
		    doorinvolved = 1;
		}
	}
    if (doorinvolved == FALSE)
	MovePlayer (FWD);
}

void WaitForAnyKey (void)
{
    SDL_Event event;
    
    while (SDL_WaitEvent (&event) != 0)
	{
	    switch (event.type)
		{
		case SDL_JOYBUTTONDOWN:
		case SDL_JOYAXISMOTION:
		    if (gwiz.joy.enabled)
			return;
		    break;
		case SDL_KEYDOWN:
		    return;
		case SDL_QUIT:
		    VerifyQuit();
		}
	}
}

int EventIsUp (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if ((sym == SDLK_UP) || (sym == gwiz.key.fwd))
		return (TRUE);
	    break;
	case SDL_JOYAXISMOTION:
	    if (gwiz.joy.enabled)
		if (JoyAxisMotion (event, NORTH))
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsDown (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if ((sym == SDLK_DOWN) || (sym == gwiz.key.bkwd))
		return (TRUE);
	    break;
	case SDL_JOYAXISMOTION:
	    if (gwiz.joy.enabled)
		if (JoyAxisMotion (event, SOUTH))
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsLeft (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if ((sym == SDLK_LEFT) || (sym == gwiz.key.lft))
		return (TRUE);
	    break;
	case SDL_JOYAXISMOTION:
	    if (gwiz.joy.enabled)
		if (JoyAxisMotion (event, WEST))
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsRight (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if ((sym == SDLK_RIGHT) || (sym == gwiz.key.rgt))
		return (TRUE);
	    break;
	case SDL_JOYAXISMOTION:
	    if (gwiz.joy.enabled)
		if (JoyAxisMotion (event, EAST))
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsOk (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if ((sym == SDLK_RETURN) || (sym == gwiz.key.act))
		return (TRUE);
	    break;
	case SDL_JOYBUTTONDOWN:
	    CheckJoy();
	    if (gwiz.joy.enabled)
		if (GetJoyButton (event) == gwiz.joy.act)
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsCancel (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if ((sym == SDLK_ESCAPE) || (sym == gwiz.key.cancel))
		return (TRUE);
	    break;
	case SDL_JOYBUTTONDOWN:
	    CheckJoy();
	    if (gwiz.joy.enabled)
		if (GetJoyButton (event) == gwiz.joy.cancel)
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsStepLeft (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if (sym == gwiz.key.slft)
		return (TRUE);
	    break;
	case SDL_JOYBUTTONDOWN:
	    CheckJoy();
	    if (gwiz.joy.enabled)
		if (GetJoyButton (event) == gwiz.joy.slft)
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsStepRight (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if (sym == gwiz.key.srgt)
		return (TRUE);
	    break;
	case SDL_JOYBUTTONDOWN:
	    CheckJoy();
	    if (gwiz.joy.enabled)
		if (GetJoyButton (event) == gwiz.joy.srgt)
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsStepBack (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if (sym == gwiz.key.bkwd)
		return (TRUE);
	    break;
	case SDL_JOYBUTTONDOWN:
	    CheckJoy();
	    if (gwiz.joy.enabled)
		if (GetJoyButton (event) == gwiz.joy.bkwd)
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}

int EventIsFta (SDL_Event *event)
{
    SDLKey sym = event->key.keysym.sym;
    switch (event->type)
	{
	case SDL_KEYDOWN:
	    if (sym == gwiz.key.fta)
		return (TRUE);
	    break;
	case SDL_JOYAXISMOTION:
	    if (gwiz.joy.enabled)
		if (JoyAxisMotion (event, SOUTH))
		    return (TRUE);
	    break;
	case SDL_QUIT:
	    VerifyQuit();
	    break;
	}
    return (FALSE);
}
