#ifndef _SCREEN_SHARED_
#define _SCREEN_SHARED_

/*

	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
	and the "Aleph One" developers.
 
	This program 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.

	This program 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.

	This license is contained in the file "COPYING",
	which is included with this source code; it is available online at
	http://www.gnu.org/licenses/gpl.html

	Created by Loren Petrich,
	Dec. 23, 2000
	Contains everything shared between screen.cpp and screen_sdl.cpp
	
Dec 29, 2000 (Loren Petrich):
	Added stuff for doing screen messages

Mar 19, 2001 (Loren Petrich):
	Added some even bigger screen resolutions

Jan 25, 2002 (Br'fin (Jeremy Parsons)):
	Added accessors for datafields now opaque in Carbon

 Aug 6, 2003 (Woody Zenfell):
	Minor tweaks to screen_printf() mechanism (safer; resets when screen_reset called)
*/

#include "shell.h"
#include "fades.h"

#include <stdarg.h>
#ifndef HAVE_SNPRINTF
//#include "snprintf.h"	// for platforms that don't have it
// Maybe someone will work some autoconf/manual config.h magic so we can really only
// include snprintf.h (and snprintf.cpp in the build) when needed.
#endif

#define DESIRED_SCREEN_WIDTH 640
#define DESIRED_SCREEN_HEIGHT 480

// Biggest possible of those defined
#define MAXIMUM_WORLD_WIDTH 1900
#define MAXIMUM_WORLD_HEIGHT 1200

#define DEFAULT_WORLD_WIDTH 640
#define DEFAULT_WORLD_HEIGHT 320

//#include "Console.h"
#include "screen_drawing.h"
#include "ViewControl.h"
#include "screen.h"
#include "render.h"
#include "interface.h"

// LP addition: view sizes and display data


struct ViewSizeData
{
	short OverallWidth, OverallHeight;	// Of the display area, so as to properly center everything
	short MainWidth, MainHeight;		// Of the main 3D-rendered view
	short WithHUD, WithoutHUD;			// Corresponding entries that are with the HUD or without it
	short flags; // see below
};

enum { // view flags, has room for expansion
  _view_show_HUD = (1 << 0)
};

const ViewSizeData ViewSizes[NUMBER_OF_VIEW_SIZES] =
{
	{ 640,  480,  320,  160,    _320_160_HUD,   _640_480, _view_show_HUD},    //   _320_160_HUD
	{ 640,  480,  480,  240,    _480_240_HUD,   _640_480, _view_show_HUD},    //   _480_240_HUD
	{ 640,  480,  640,  320,    _640_320_HUD,   _640_480, _view_show_HUD},    //   _640_320_HUD
	{ 640,  480,  640,  480,    _640_320_HUD,   _640_480, 0},                 //   _640_480
	{ 800,  600,  800,  400,    _800_400_HUD,   _800_600, _view_show_HUD},    //   _800_400_HUD
	{ 800,  600,  800,  600,    _800_400_HUD,   _800_600, 0},                 //   _800_600
	{1024,  768, 1024,  512,   _1024_512_HUD,  _1024_768, _view_show_HUD},    //  _1024_512_HUD
	{1024,  768, 1024,  768,   _1024_512_HUD,  _1024_768, 0},                 //  _1024_768
	{1280, 1024, 1280,  640,   _1280_640_HUD, _1280_1024, _view_show_HUD},    //  _1280_640_HUD
	{1280, 1024, 1280, 1024,   _1280_640_HUD, _1280_1024, 0},                 //  _1280_1024
	{1600, 1200, 1600,  800,   _1600_800_HUD, _1600_1200, _view_show_HUD},    //  _1600_800_HUD
	{1600, 1200, 1600, 1200,   _1600_800_HUD, _1600_1200, 0},                 //  _1600_1200
	{1024,  640, 1024,  440,   _1024_440_HUD,  _1024_640, _view_show_HUD},    //  _1024_440_HUD
	{1024,  640, 1024,  640,   _1024_440_HUD,  _1024_640, 0},                 //  _1024_640
	{1280,  800, 1280,  600,   _1280_600_HUD,  _1280_800, _view_show_HUD},    //  _1280_600_HUD
	{1280,  800, 1280,  800,   _1280_600_HUD,  _1280_800, 0},                 //  _1280_800
	{1280,  854, 1280,  654, _1280_640WS_HUD,  _1280_854, _view_show_HUD},    //  _1280_640WS_HUD
	{1280,  854, 1280,  854, _1280_640WS_HUD,  _1280_854, _view_show_HUD},    //  _1280_854
	{1440,  900, 1440,  700,   _1440_700_HUD,  _1440_900, _view_show_HUD},    //  _1440_700_HUD
	{1440,  900, 1440,  700,   _1440_700_HUD,  _1440_900, 0},                 //  _1440_900
	{1680, 1050, 1680,  840,   _1680_840_HUD, _1680_1050, _view_show_HUD},    //  _1680_840_HUD
	{1680, 1050, 1680,  1050,  _1680_840_HUD, _1680_1050, 0},                 //  _1680_1050
	{1920, 1200, 1920,  950,   _1920_950_HUD, _1920_1200, _view_show_HUD},    //  _1900_950_HUD
	{1920, 1200, 1920,  1200,  _1920_950_HUD, _1920_1200, 0},                 //  _1900_1200
};

// Note: the overhead map will always fill all of the screen except for the HUD,
// and the terminal display will always have a size of 640*320.

/* ---------- globals */

static struct color_table *uncorrected_color_table; /* the pristine color environment of the game (can be 16bit) */
extern struct color_table *world_color_table; /* the gamma-corrected color environment of the game (can be 16bit) */
extern struct color_table *interface_color_table; /* always 8bit, for mixed-mode (i.e., valkyrie) fades */
extern struct color_table *visible_color_table; /* the color environment the player sees (can be 16bit) */

static struct view_data *world_view; /* should be static */

// Convenient package for the drawing target (contains dimensions and pixel-row pointers)
static struct bitmap_definition *world_pixels_structure;

// LP change: added stuff for keeping track of screen sizes;
// this is for forcing the clearing of the screen when resizing.
// These are initialized to improbable values.
static short PrevBufferWidth = INT16_MIN, PrevBufferHeight = INT16_MIN,
	PrevOffsetWidth = INT16_MIN, PrevOffsetHeight = INT16_MIN;

extern struct screen_mode_data screen_mode;

#define FRAME_SAMPLE_SIZE 20
static bool displaying_fps= false;
static short frame_count, frame_index;
static long frame_ticks[64];

// LP addition:
// whether to show one's position
static bool ShowPosition = false;

// Whether rendering of the HUD has been requested
static bool HUD_RenderRequest = false;

static bool screen_initialized= false;

extern short bit_depth;
extern short interface_bit_depth;

// LP addition: this is defined in overhead_map.c
// It indicates whether to render the overhead map in OpenGL
extern bool OGL_MapActive;


// Current screen messages:
const int NumScreenMessages = 7;
struct ScreenMessage
{
	enum {
		Len = 256
	};

	int TimeRemaining;	// How many more engine ticks until the message expires?
	char Text[Len];		// Text to display
	
	ScreenMessage(): TimeRemaining(0) {Text[0] = 0;}
};

static int MostRecentMessage = NumScreenMessages-1;
static ScreenMessage Messages[NumScreenMessages];

/* SB */
static struct ScriptHUDElement {
	/* I don't like this convention, but I'll follow it. */
	enum {
		Len = 256
	};
	/* this needs optimized (sorry, making fun of my grandmother...) */
	/* it's char[4] instead of int32 to make the OpenGL support simpler to implement */
	unsigned char icon[1024];
	bool isicon;
	int color;
	char text[Len];
} ScriptHUDElements[MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS];
/* /SB */

/* ---------- private prototypes */

static void set_overhead_map_status(bool status);
static void set_terminal_status(bool status);

/* ---------- code */

/* SB */
namespace icon {
	
	static inline char nextc(const char*& p, size_t& rem) {
		if(rem == 0) throw "end of string";
		--rem;
		return *(p++);
	}
	
	static inline unsigned char digit(char p) {
		if(p >= '0' && p <= '9') return p - '0';
		else if(p >= 'A' && p <= 'F') return p - 'A' + 0xA;
		else if(p >= 'a' && p <= 'f') return p - 'a' + 0xA;
		else throw "invalid digit";
	}
	
	static inline unsigned char readuc(const char*& p, size_t& rem) {
		char a = nextc(p, rem), b;
		b = nextc(p, rem);
		return (digit(a) << 4) | digit(b);
	}
	
	static bool parseicon(const char* p, size_t rem,
												unsigned char palette[768], int& numcolors,
												unsigned char graphic[256]) {
		char chars[256];
		try {
			char oc, c;
			size_t n, m;
			numcolors = 0;
			while(1) {
				c = nextc(p, rem);
				if(c >= '0' && c <= '9')
					numcolors = numcolors * 10 + (c - '0');
				else break;
			}
			if(numcolors == 0) return 1;
			oc = c;
			do {
				c = nextc(p, rem);
			} while(c == oc);
			n = 0;
			while(n < (size_t)numcolors) {
				chars[n] = c;
				palette[n * 3] = readuc(p, rem);
				palette[n * 3 + 1] = readuc(p, rem);
				palette[n * 3 + 2] = readuc(p, rem);
				++n;
				nextc(p, rem); /* ignore a char */
				c = nextc(p, rem);
			}
			n = 0;
			while(n < 256) {
				for(m = 0; m < (size_t)numcolors; ++m) {
					if(chars[m] == c) {
						graphic[n++] = (unsigned char)m;
						break;
					}
				}
				c = nextc(p, rem);
			}
		} catch(...) {
			return false;
		}
		return true;
	}
	
	static void seticon(int idx, unsigned char palette[768], unsigned char graphic[256]) {
		unsigned char* p1, *p2, px;
		int n;
		p1 = ScriptHUDElements[idx].icon;
		p2 = graphic;
		for(n = 0; n < 256; ++n) {
			px = *(p2++);
			*(p1++) = 0xFF;
			*(p1++) = palette[px * 3];
			*(p1++) = palette[px * 3 + 1];
			*(p1++) = palette[px * 3 + 2];
		}
		ScriptHUDElements[idx].isicon = true;
	}
	
}
/*
void SetScriptHUDColor(int idx, int color) {
	idx %= MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS; //* o_o *
	ScriptHUDElements[idx].color = color % 8; //* O_O *
}

void SetScriptHUDText(int idx, const char* text) {
	idx %= MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS;
	if(!text) text = "";
	strncpy(ScriptHUDElements[idx].text, text, 255);
	ScriptHUDElements[idx].text[255] = 0;
}

/*
bool SetScriptHUDIcon(int idx, const char* text, size_t rem) {
	unsigned char palette[768], graphic[256];
	int numcolors;
	idx %= MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS;
	if(text) {
		if(!icon::parseicon(text, rem, palette, numcolors, graphic)) return false;
		icon::seticon(idx, palette, graphic);
	} else ScriptHUDElements[idx].isicon = false;
	return true;
}

void SetScriptHUDSquare(int idx, int _color) {
	unsigned char palette[3]; /* short, I KNOW. *
	unsigned char graphic[256];
	idx %= MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS;
	ScriptHUDElements[idx].color = _color % 8;
	memset(graphic, 0, 256);
#if defined(mac)
	RGBColor color;
	_get_interface_color(_color+_computer_interface_text_color, &color);
	palette[0] = color.red >> 8;
	palette[1] = color.green >> 8;
	palette[2] = color.blue >> 8;
#elif defined(SDL)
	SDL_Color color;
	_get_interface_color(_color+_computer_interface_text_color, &color);
	palette[0] = color.r;
	palette[1] = color.g;
	palette[2] = color.b;
#endif
	icon::seticon(idx, palette, graphic);
    
}
/* /SB */
static void ResetFieldOfView();

// LP addition: this resets the screen; useful when starting a game
void reset_screen();


// LP change: resets field of view to whatever the player had had when reviving
void ResetFieldOfView()
{
	world_view->tunnel_vision_active = false;

/*	if (current_player->extravision_duration)
	{
		world_view->field_of_view = EXTRAVISION_FIELD_OF_VIEW;
		world_view->target_field_of_view = EXTRAVISION_FIELD_OF_VIEW;
	}
	else*/
	{
		world_view->field_of_view = NORMAL_FIELD_OF_VIEW;
		world_view->target_field_of_view = NORMAL_FIELD_OF_VIEW;
	}
}

/*bool zoom_overhead_map_out(
	void)
{
	bool Success = false;
	if (world_view->overhead_map_scale > OVERHEAD_MAP_MINIMUM_SCALE)
	{
		world_view->overhead_map_scale--;
		Success = true;
	}
	
	return Success;
}

bool zoom_overhead_map_in(
	void)
{
	bool Success = false;
	if (world_view->overhead_map_scale < OVERHEAD_MAP_MAXIMUM_SCALE)
	{
		world_view->overhead_map_scale++;
		Success = true;
	}

	return Success;
}

void start_teleporting_effect(
	bool out)
{
//	if (View_DoFoldEffect())
//		start_render_effect(world_view, out ? _render_effect_fold_out : _render_effect_fold_in);
}

void start_extravision_effect(
	bool out)
{
	// LP change: doing this by setting targets
//	world_view->target_field_of_view = out ? EXTRAVISION_FIELD_OF_VIEW : NORMAL_FIELD_OF_VIEW;
}

// LP addition:
void start_tunnel_vision_effect(bool out);

//CP addition: returns the screen info
*/

// LP: gets a size ID's related size ID's that show or hide the HUD, respectively
/*
short GetSizeWithHUD(short Size)
{
	assert(Size >= 0 && Size < NUMBER_OF_VIEW_SIZES);
	return ViewSizes[Size].WithHUD;
}

short GetSizeWithoutHUD(short Size)
{
	assert(Size >= 0 && Size < NUMBER_OF_VIEW_SIZES);
	return ViewSizes[Size].WithoutHUD;
}

/* These should be replaced with better preferences control functions */
// LP change: generalizing this
/*bool game_window_is_full_screen(
	void)
{
	short msize = screen_mode.size;
	assert(msize >= 0 && msize < NUMBER_OF_VIEW_SIZES);
	return (!TEST_FLAG(ViewSizes[msize].flags, _view_show_HUD));
}
*/

void change_gamma_level(
	short gamma_level);

/* ---------- private code */

// LP addition: routine for displaying text

#ifdef SDL
// Globals for communicating with the SDL contents of DisplayText
static SDL_Surface *DisplayTextDest = NULL;
static sdl_font_info *DisplayTextFont = NULL;
static short DisplayTextStyle = 0;
#endif
    /*
/*static* void DisplayText(short BaseX, short BaseY, const char *Text, unsigned char r = 0xff, unsigned char g = 0xff, unsigned char b = 0xff)
{

#ifdef HAVE_OPENGL
	// OpenGL version:
	// activate only in the main view, and also if OpenGL is being used for the overhead map
	if((OGL_MapActive || !world_view->overhead_map_active) && !world_view->terminal_mode_active)
		if (OGL_RenderText(BaseX, BaseY, Text, r, g, b)) return;
#endif

#if defined(mac)
	// C to Pascal
	RGBColor color;
	Str255 PasText;
	
	color.red = (r << 8) | r;
	color.green = (g << 8) | g;
	color.blue = (b << 8) | b;
	
	int Len = MIN(strlen(Text),255);
	PasText[0] = Len;
	memcpy(PasText+1,Text,Len);
	
	// LP change: drop shadow in both MacOS and SDL versions
	RGBForeColor(&rgb_black);
	MoveTo(BaseX+1,BaseY+1);
	DrawString(PasText);
	
	RGBForeColor(&color);
	MoveTo(BaseX,BaseY);
	DrawString(PasText);
	
#elif defined(SDL)

	draw_text(DisplayTextDest, Text, BaseX+1, BaseY+1, SDL_MapRGB(world_pixels->format, 0x00, 0x00, 0x00), DisplayTextFont, DisplayTextStyle);
	draw_text(DisplayTextDest, Text, BaseX, BaseY, SDL_MapRGB(world_pixels->format, r, g, b), DisplayTextFont, DisplayTextStyle);
	
#endif*
}*/


#if defined(mac)
static void update_fps_display(GrafPtr port, short xoffset = -1, short yoffset = -1)
#elif defined(SDL)
static void update_fps_display(SDL_Surface *s)
#endif
{
/*	if (displaying_fps && !player_in_terminal_mode(current_player_index))
	{
#if defined(mac)
		uint32 ticks= TickCount();
#elif defined(SDL)
		uint32 ticks = SDL_GetTicks();
#endif
		char fps[sizeof("120.00fps")];
		
		frame_ticks[frame_index]= ticks;
		frame_index= (frame_index+1)%FRAME_SAMPLE_SIZE;
		if (frame_count<FRAME_SAMPLE_SIZE)
		{
			frame_count+= 1;
			strcpy(fps, "--");
		}
		else
		{
		    float count = (FRAME_SAMPLE_SIZE * MACHINE_TICKS_PER_SECOND) / float(ticks-frame_ticks[frame_index]);
		    if (count >= TICKS_PER_SECOND)
			sprintf(fps, "%lu%s",(unsigned long)TICKS_PER_SECOND,".00fps");
		    else
			sprintf(fps, "%3.2ffps", count);
		}
		
		FontSpecifier& Font = GetOnScreenFont();
		
#if defined(mac)
		GrafPtr old_port;
		GetPort(&old_port);
		SetPort(port);
		Font.Use();
		Rect portRect;
		GetPortBounds(port, &portRect);
		short X0 = xoffset==-1?portRect.left:portRect.left+xoffset;
		short Y0 = yoffset==-1?portRect.bottom:portRect.top + yoffset;
#elif defined(SDL)
		DisplayTextDest = s;
		DisplayTextFont = Font.Info;
		DisplayTextStyle = Font.Style;
		short X0 = 0;
		short Y0 = s->h;
#endif
		// The line spacing is a generalization of "5" for larger fonts
		short Offset = Font.LineSpacing / 3;
		short X = X0 + Offset;
		short Y = Y0 - Offset;
		DisplayText(X,Y,fps);
		
#if defined(mac)
		RGBForeColor(&rgb_black);
		SetPort(old_port);
#endif
	}
	else
	{
		frame_count= frame_index= 0;
	}*/
}


#if defined(mac)
static void DisplayPosition(GrafPtr port)
#elif defined(SDL)
static void DisplayPosition(SDL_Surface *s)
#endif
{
/*	if (!ShowPosition) return;
		
	FontSpecifier& Font = GetOnScreenFont();
	
#if defined(mac)
	// Push
	GrafPtr old_port;
	GetPort(&old_port);
	SetPort(port);
	Font.Use();
	Rect portRect;
	GetPortBounds(port, &portRect);
	short X0 = portRect.left;
	short Y0 = portRect.top;
#elif defined(SDL)
	DisplayTextDest = s;
	DisplayTextFont = Font.Info;
	DisplayTextStyle = Font.Style;
	short X0 = 0;
	short Y0 = 0;
#endif
	
	short LineSpacing = Font.LineSpacing;
	short X = X0 + LineSpacing/3;
	short Y = Y0 + LineSpacing;
	const float FLOAT_WORLD_ONE = float(WORLD_ONE);
	const float AngleConvert = 360/float(FULL_CIRCLE);
	sprintf(temporary, "X       = %8.3f",world_view->origin.x/FLOAT_WORLD_ONE);
	DisplayText(X,Y,temporary);
	Y += LineSpacing;
	sprintf(temporary, "Y       = %8.3f",world_view->origin.y/FLOAT_WORLD_ONE);
	DisplayText(X,Y,temporary);
	Y += LineSpacing;
	sprintf(temporary, "Z       = %8.3f",world_view->origin.z/FLOAT_WORLD_ONE);
	DisplayText(X,Y,temporary);
	Y += LineSpacing;
	sprintf(temporary, "Polygon = %8d",world_view->origin_polygon_index);
	DisplayText(X,Y,temporary);
	Y += LineSpacing;
	short Angle = world_view->yaw;
	if (Angle > HALF_CIRCLE) Angle -= FULL_CIRCLE;
	sprintf(temporary, "Yaw     = %8.3f",AngleConvert*Angle);
	DisplayText(X,Y,temporary);
	Y += LineSpacing;
	Angle = world_view->pitch;
	if (Angle > HALF_CIRCLE) Angle -= FULL_CIRCLE;
	sprintf(temporary, "Pitch   = %8.3f",AngleConvert*Angle);
	DisplayText(X,Y,temporary);
	
	// Pop
#ifdef mac
	RGBForeColor(&rgb_black);
	SetPort(old_port);
#endif*/
}

#if defined(mac)
static void DisplayInputLine(GrafPtr port, short offWidth, short offHeight)
#elif defined(SDL)
static void DisplayInputLine(SDL_Surface *s)
#endif
{
/*  if (Console::instance()->input_active() && 
      !Console::instance()->displayBuffer().empty()) {
    FontSpecifier& Font = GetOnScreenFont();
    
#if defined(mac)
  GrafPtr old_port;
  GetPort (&old_port);
  SetPort(port);
  Font.Use();
  Rect portRect;
  GetPortBounds(port, &portRect);
  short X0 = offWidth==-1?portRect.left:portRect.left+offWidth;
  short Y0 = offHeight==-1?portRect.bottom:portRect.top + offHeight;
#elif defined(SDL)
  DisplayTextDest = s;
  DisplayTextFont = Font.Info;
  DisplayTextStyle = Font.Style;
  short X0 = 0;
  short Y0 = s->h;
#endif

  short Offset = Font.LineSpacing / 3;
  short X = X0 + Offset;
  short Y = Y0 - Offset;
  DisplayText(X, Y, Console::instance()->displayBuffer().c_str());

#if defined(mac)
  RGBForeColor(&rgb_black);
  SetPort(old_port);
#endif
  }*/
}

#if defined(mac)
static void DisplayMessages(GrafPtr port, short offWidth, short offHeight)
#elif defined(SDL)
static void DisplayMessages(SDL_Surface *s)
#endif
{	
/*	FontSpecifier& Font = GetOnScreenFont();
	
#if defined(mac)
	// Push
	GrafPtr old_port;
	GetPort(&old_port);
	SetPort(port);
	Font.Use();
	Rect portRect;
	GetPortBounds(port, &portRect);
	short X0 = portRect.left+offWidth;
	short Y0 = portRect.top+offHeight;
#elif defined(SDL)
	DisplayTextDest = s;
	DisplayTextFont = Font.Info;
	DisplayTextStyle = Font.Style;
	short X0 = 0;
	short Y0 = 0;
#endif
	
	short LineSpacing = Font.LineSpacing;
	short X = X0 + LineSpacing/3;
	short Y = Y0 + LineSpacing;
	if (ShowPosition) Y += 6*LineSpacing;	// Make room for the position data
	/* SB *
	for(int i = 0; i < MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS; ++i) {
		if(ScriptHUDElements[i].text[0]) {
			short x2 = X, sk, ysk = 0;
			/* Yes, I KNOW this is the same i as above. I know what I'm doing. *
			for(i = 0; i < MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS; ++i) {
				if(!ScriptHUDElements[i].text[0]) continue;
				sk = SCRIPT_HUD_ELEMENT_SPACING;
				if(ScriptHUDElements[i].isicon) {
					ysk = 2;
#ifdef HAVE_OPENGL
					if(OGL_IsActive() && ((OGL_MapActive || !world_view->overhead_map_active) && !world_view->terminal_mode_active)) {
						GLuint tex;
						glPushAttrib(GL_ALL_ATTRIB_BITS);
						glEnable(GL_TEXTURE_2D);
						glDisable(GL_CULL_FACE);
						glEnable(GL_BLEND);
						glDisable(GL_ALPHA_TEST);
						glMatrixMode(GL_MODELVIEW);
						glPushMatrix();
						glLoadIdentity();
						glGenTextures(1, &tex);
						glTranslatef(x2-0.5f,Y+4.5f,0);
						glRasterPos2d(0, 0);
						glBindTexture(GL_TEXTURE_2D, tex);
#ifdef ALEPHONE_LITTLE_ENDIAN
						glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, ScriptHUDElements[i].icon);
#else
						glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ScriptHUDElements[i].icon);
#endif
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
						glColor3f(1,1,1);
						glBegin(GL_TRIANGLE_FAN);
						glTexCoord2f(0.0f, 0.0f);
						glVertex2f(0.5f, -15.5f);
						glTexCoord2f(1.0f, 0.0f);
						glVertex2f(16.5f, -15.5f);
						glTexCoord2f(1.0f, 1.0f);
						glVertex2f(16.5f, 0.5f);
						glTexCoord2f(0.0f, 1.0f);
						glVertex2f(0.5f, 0.5f);
						glEnd();
						/*glDrawPixels(16, 16, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ScriptHUDElements[i].icon);*
						glDeleteTextures(1, &tex);
						glPopMatrix();
						glPopAttrib();				
					}
					else 
#endif 
					{
#if defined(mac)
						struct PixMap** map = NewPixMap();
						Rect target;
						(*map)->baseAddr = (char *) ScriptHUDElements[i].icon;
						(*map)->rowBytes = 64 | (1 << 15);
						(*map)->bounds.top = 0;
						(*map)->bounds.left = 0;
						(*map)->bounds.bottom = 16;
						(*map)->bounds.right = 16;
						(*map)->packType = 1;
						(*map)->packSize = 1024;
						(*map)->pixelType = RGBDirect;
						(*map)->pixelSize = 32;
						(*map)->cmpCount = 3;
						(*map)->cmpSize = 8;
						(*map)->pmTable = NULL;
						target.top = Y - 11;
						target.left = x2;
						target.bottom = Y + 5;
						target.right = x2 + 16;
						RGBForeColor(&rgb_black);
						RGBBackColor(&rgb_white);
						CopyBits((BitMap*)*map, GetPortBitMapForCopyBits(port),
										 &(*map)->bounds, &target, srcCopy, NULL);
						DisposePixMap(map);
#elif defined(SDL)
						SDL_Surface* srf;
						SDL_Rect rect;
						rect.x = x2;
						rect.y = Y - 11;
						rect.w = rect.h = 16;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
						srf = SDL_CreateRGBSurfaceFrom(ScriptHUDElements[i].icon, 16, 16, 32, 64, 0xFF<<24, 0xFF<<16, 0xFF<<8, 0);
#else
						srf = SDL_CreateRGBSurfaceFrom(ScriptHUDElements[i].icon, 16, 16, 32, 64, 0xFF<<16, 0xFF<<8, 0xFF, 0);
#endif
						SDL_BlitSurface(srf, NULL, s, &rect);
						SDL_FreeSurface(srf);
#endif
					}
					x2 += 20;
					sk -= 20;
				}
#if defined(mac)
				RGBColor color;
				_get_interface_color(ScriptHUDElements[i].color+_computer_interface_text_color, &color);
				DisplayText(x2,Y + (ScriptHUDElements[i].isicon ? 2 : 0),ScriptHUDElements[i].text, color.red >> 8, color.green >> 8, color.blue >> 8);
#elif defined(SDL)
				SDL_Color color;
				_get_interface_color(ScriptHUDElements[i].color+_computer_interface_text_color, &color);
				DisplayText(x2,Y + (ScriptHUDElements[i].isicon ? 2 : 0),ScriptHUDElements[i].text, color.r, color.g, color.b);
#endif
				x2 += sk;
			}
			Y += LineSpacing + ysk;
			break;
		}
	}
	/* /SB *
	//	for (int k=0; k<NumScreenMessages; k++)
	for (int k = NumScreenMessages - 1; k >= 0; k--)
	{
	  int Which = (MostRecentMessage+NumScreenMessages-k) % NumScreenMessages;
		while (Which < 0)
			Which += NumScreenMessages;
		ScreenMessage& Message = Messages[Which];
		if (Message.TimeRemaining <= 0) continue;
		Message.TimeRemaining--;
		
		DisplayText(X,Y,Message.Text);
		Y += LineSpacing;
	}

	// Pop
#ifdef mac
	RGBForeColor(&rgb_black);
	SetPort(old_port);
#endif*/
}


static void set_overhead_map_status( /* it has changed, this is the new status */
	bool status)
{
	world_view->overhead_map_active= status;
}

static void set_terminal_status( /* It has changed, this is the new state.. */
	bool status)
{
/*	bool restore_effect= false;
	short effect = 0, phase = 0;
	
	if(!status)
	{
		if(world_view->effect==_render_effect_fold_out)
		{
			effect= world_view->effect;
			phase= world_view->effect_phase;
			restore_effect= true;
		}
	}
	world_view->terminal_mode_active= status;
	
	if(restore_effect)
	{
		world_view->effect= effect;
		world_view->effect_phase= phase;
	}

	/* Dirty the view.. *
	dirty_terminal_view(current_player_index);*/
}

// For getting and setting tunnel-vision mode
/*bool GetTunnelVision() {return world_view->tunnel_vision_active;}
bool SetTunnelVision(bool TunnelVisionOn)
{
	// LP: simplifying tunnel-vision-activation/deactivation behavior
	world_view->tunnel_vision_active = TunnelVisionOn;
	start_tunnel_vision_effect(TunnelVisionOn);
	return world_view->tunnel_vision_active;
}

// This is for requesting the drawing of the Heads-Up Display;
// this is done because its drawing is now done when the main display is drawn
/*void RequestDrawingHUD()
{
	HUD_RenderRequest = true;
}
*/
// ZZZ: I feel bad doing this, but ... not sure what best way to handle it is.
// #ifdef __MWERKS__
// using std::vsnprintf;
// #endif

// LP addition: display message on the screen;
// this really puts the current message into a buffer
// Code cribbed from csstrings
/*void screen_printf(const char *format, ...)
{
	MostRecentMessage = (MostRecentMessage + 1) % NumScreenMessages;
	while (MostRecentMessage < 0)
		MostRecentMessage += NumScreenMessages;
	ScreenMessage& Message = Messages[MostRecentMessage];
	
	Message.TimeRemaining = 7*TICKS_PER_SECOND;

	va_list list;

	va_start(list,format);
	// ZZZ: [v]sprintf is evil, generally: hard to guarantee you don't overflow target buffer
	// using [v]snprintf instead
	vsnprintf(Message.Text,sizeof(Message.Text),format,list);
	va_end(list);
}
*/
#endif
