diff options
Diffstat (limited to 'backends/sdl')
| -rw-r--r-- | backends/sdl/fb2opengl.h | 521 | ||||
| -rw-r--r-- | backends/sdl/sdl_gl.cpp | 696 | 
2 files changed, 0 insertions, 1217 deletions
| diff --git a/backends/sdl/fb2opengl.h b/backends/sdl/fb2opengl.h deleted file mode 100644 index daf6091b13..0000000000 --- a/backends/sdl/fb2opengl.h +++ /dev/null @@ -1,521 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001  Ludvig Strigeus - * Copyright (C) 2001-2003 The ScummVM project - * - * 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. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. - * - */ - -// FrameBuffer renderer in an OpenGL texture -// Andre Souza <asouza_luke@yahoo.com.br> - -#include <SDL.h> -#include <SDL_opengl.h> -//#include <GL/gl.h>	NOTE! Before anybody comments out SDL_opengl.h and enables this again, talk to Fingolfin first! GL/gl.h is NOT portable! -#include <stdlib.h> -#include <string.h> - -// FLAGS  -#define FB2GL_FS 1      // FULLSCREEN -#define FB2GL_RGBA 2    // Use RGBA (else use palette) -#define FB2GL_NO_320 4     // Don't use 320x256 texture, rather emulate with a 256x256 plus a 64x256 texture -#define FB2GL_AUDIO 8   // Activate SDL Audio -#define FB2GL_PITCH 16  // On fb2l_update, use pitch (else bytes per pixel) -#define FB2GL_EXPAND 32 // Create a RGB fb with the color lookup table -#define FB2GL_16BIT 64  // 16 BIT Color Depth - -// This extension isn't defined in OpenGL 1.1 -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 -#endif - -class FB2GL { -	private: -		SDL_Surface *screen; -		// Framebuffer for 8 bpp -		unsigned char palettedFrameBuffer1[256*320]; -		unsigned char *palettedFrameBuffer2; -//		unsigned char palettedFrameBuffer1[256][256]; -//		unsigned char palettedFrameBuffer2[256][64]; -		// Framebuffer for RGBA -		unsigned char RGBAFrameBuffer1[256*320*4]; -		unsigned char *RGBAFrameBuffer2; -//		unsigned char RGBAFrameBuffer1[256][256][4]; -//		unsigned char RGBAFrameBuffer2[256][64][4]; -		// Texture(s) -		GLuint texture1; -		GLuint texture2; -		// Display list -		GLuint displayList; -		// Color Table (256 colors, RGB) -		char colorTable[256][3]; -		char tempColorTable[256][3]; // Support for OpenGL 1.1 -		char flags; -		void makeTextures(); -		void makeDisplayList(int xf, int yf); - -	public: -		 -		FB2GL() {  -			flags = 0; -			screen = NULL; -			 -			palettedFrameBuffer2 = palettedFrameBuffer1 + 256*256; -			RGBAFrameBuffer2 = RGBAFrameBuffer1 + 256*256*4; -		} -		 -		SDL_Surface *getScreen() { -		  return screen;  -		}; -		 -		void setScreen(SDL_Surface *s) { -		  screen = s; -		}; -		 -		int init(int width, int height, int xfix, int yfix, char _flags); -		void update(void *fb, int width, int height, int pitch, int xskip, int yskip); -		void palette(int index, int r, int g, int b); -		void setPalette(int first, int ncolors); -		void blit16(SDL_Surface *fb, int num_rect, SDL_Rect *rectlist, int xskip, int yskip); -		void display(); -		void setBilinearMode(bool bilinear); -}; - -void FB2GL::setBilinearMode(bool bilinear) { -	const GLuint mode = bilinear ? GL_LINEAR : GL_NEAREST; -	glBindTexture(GL_TEXTURE_2D, texture1); -	// No borders -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); -	// Bilinear filter -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode); -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode); - -	if (flags & FB2GL_NO_320) { -		glBindTexture(GL_TEXTURE_2D, texture2); -		// No borders -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); -		// Bilinear filter -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode); -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode); -	} -} - -void FB2GL::makeTextures() { -	glGenTextures(0,&texture1); -	glBindTexture(GL_TEXTURE_2D,texture1); - -	// No borders -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - -	// Bilinear filtering -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - -	GLuint mode; -	const GLvoid *buffer1, *buffer2; - -	if (flags & FB2GL_RGBA) { -		mode = GL_RGBA; -		buffer1 = RGBAFrameBuffer1; -		buffer2 = RGBAFrameBuffer2; -	} else { -		mode = GL_COLOR_INDEX; -		buffer1 = palettedFrameBuffer1; -		buffer2 = palettedFrameBuffer2; -	} - -	if (flags & FB2GL_NO_320) { -		glTexImage2D(GL_TEXTURE_2D, 0, mode, 256, 256, 0, mode, GL_UNSIGNED_BYTE, buffer1); - -		glGenTextures(1, &texture2); -		glBindTexture(GL_TEXTURE_2D, texture2); - -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - -		// Bilinear filtering -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - -		glTexImage2D(GL_TEXTURE_2D, 0, mode, 64, 256, 0, mode, GL_UNSIGNED_BYTE, buffer2); -	} else { -		glTexImage2D(GL_TEXTURE_2D, 0, mode, 320, 256, 0, mode, GL_UNSIGNED_BYTE, buffer1); -	} -} - - -void FB2GL::makeDisplayList(int xf, int yf) { -	GLfloat xfix = xf / 128.0f; // 128 = 256/2 (half texture => 0.0 to 1.0) -	GLfloat yfix = yf / 128.0f; -	GLfloat texture1_end;	// End of 256x256 texture (from -1.0 to 1.0) - -	if (flags & FB2GL_NO_320) { -		// Game screen width = 320 -		// GL coordinates (-1.0 <= x <= 1.0, -1.0 <= y <= 1.0) -		// X axis center: GL => 0.0, Game => 320/2 = 160 -		// GL texture1 width = 256 (texture2 width = 64. 256 + 64 = 320) -		// 160 = 320/2 (half width). 256 - 160 = 96  -		texture1_end = 96.0f / 160.0f; // between 0.0 (center) and 1.0 -		// Note: wrong value may cause black vertical line (gap  -		// between texture1 and texture2 in the X axis) -	} -	else { -		texture1_end = 1.0f; -	} -	 -	if (glIsList(displayList))  -		glDeleteLists(displayList, 1); - -	displayList = glGenLists(1); -	glNewList(displayList, GL_COMPILE); - -	glEnable(GL_TEXTURE_2D); - -	glBindTexture(GL_TEXTURE_2D, texture1); - -	glBegin(GL_QUADS); -	// lower left -	glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f - yfix); -	// upper left -	glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, 1.0f); -	// upper right -	glTexCoord2f(1.0f, 0.0f); glVertex2f(texture1_end + xfix, 1.0f); -	// lower right -	glTexCoord2f(1.0f, 1.0f); glVertex2f(texture1_end + xfix, -1.0f - yfix); -	glEnd(); - -	if (flags & FB2GL_NO_320) { -		// 64x256 (texture2) -		glBindTexture(GL_TEXTURE_2D, texture2); - -		glBegin(GL_QUADS); -		// lower left	 -		glTexCoord2f(0.0f, 1.0f); glVertex2f(texture1_end + xfix, -1.0f - yfix); -		// upper left -		glTexCoord2f(0.0f, 0.0f); glVertex2f(texture1_end + xfix, 1.0f); -		// upper right -		glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f + xfix, 1.0f); -		// lower right -		glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f + xfix, -1.0f - yfix); -		glEnd(); -	} - -	glDisable(GL_TEXTURE_2D); - -	glEndList(); -} - -int FB2GL::init(int width, int height, int xfix, int yfix, char _flags) { -	char gl_ext[4096]; -	gl_ext[0]='\0'; - -	flags = _flags; - -	// Fullscreen? -	if (!screen) { -		screen = SDL_SetVideoMode(width, height, (flags & FB2GL_16BIT ? 16: 0), -				SDL_HWPALETTE | SDL_HWSURFACE | SDL_OPENGL | SDL_GL_DOUBLEBUFFER | -				(flags & FB2GL_FS? SDL_FULLSCREEN: 0)); -	} - -//	warning("Screen BitsPerPixel: %d\n",screen->format->BitsPerPixel); - -	if (!screen) { -		warning("Couldn't start video res %dx%d", width, height); -		return 0; -	} - -/* -	if (!(flags & FB2GL_RGBA)) { // Check for Paletted Texture Extension  -		 -		strcpy(gl_ext, (char *)glGetString(GL_EXTENSIONS)); -	fprintf(stderr,"gl_ext= %s\n",gl_ext); - -		if ( strstr( gl_ext , "GL_EXT_paletted_texture") ) -			glEnable(GL_EXT_paletted_texture); -		else { -			fprintf(stderr,"Your OpenGL version doesn't support paletted texture\n"); -			return 0; -		} -	} -*/ - -	if (width>0 && height>0)  -		makeTextures(); -	makeDisplayList(xfix, yfix); - -	return 1; -} - -void FB2GL::display() -{ -	glCallList(displayList); -	SDL_GL_SwapBuffers(); -} - -void FB2GL::update(void *fb, int w, int h, int pitch, int xskip, int yskip) { -	unsigned char *tempFrameBuffer = (unsigned char *)fb; -	int x, y, scr_pitch, _byte; - -	if (flags & FB2GL_PITCH) { -		scr_pitch = pitch; -		_byte = 0; -	} else { -		scr_pitch = w * pitch; -		_byte = pitch; // Bytes perl pixel (for RGBA mode) -	} - -	if (flags & FB2GL_RGBA) { -		 -		if (flags & FB2GL_EXPAND) { // Expand the 8 bit fb into a RGB fb -	 -			for (y = yskip; y < h; y++) { -				for (x = xskip; x < w; x++) { -					if (!(flags & FB2GL_NO_320)) { -						RGBAFrameBuffer1[y*320*4 + x*4 + 0] = colorTable[*(tempFrameBuffer+x)][0]; -						RGBAFrameBuffer1[y*320*4 + x*4 + 1] = colorTable[*(tempFrameBuffer+x)][1];  -						RGBAFrameBuffer1[y*320*4 + x*4 + 2] = colorTable[*(tempFrameBuffer+x)][2];  -						RGBAFrameBuffer1[y*320*4 + x*4 + 3] = 255; -					} else if (x < 256) {  -						RGBAFrameBuffer1[y*256*4 + x*4 + 0] = colorTable[*(tempFrameBuffer+x)][0]; -						RGBAFrameBuffer1[y*256*4 + x*4 + 1] = colorTable[*(tempFrameBuffer+x)][1];  -						RGBAFrameBuffer1[y*256*4 + x*4 + 2] = colorTable[*(tempFrameBuffer+x)][2];  -						RGBAFrameBuffer1[y*256*4 + x*4 + 3] = 255; -					} else { -						RGBAFrameBuffer2[y*64*4 + (x-256)*4 + 0] = colorTable[*(tempFrameBuffer+x)][0];  -						RGBAFrameBuffer2[y*64*4 + (x-256)*4 + 1] = colorTable[*(tempFrameBuffer+x)][1];  -						RGBAFrameBuffer2[y*64*4 + (x-256)*4 + 2] = colorTable[*(tempFrameBuffer+x)][2];  -						RGBAFrameBuffer2[y*64*4 + (x-256)*4 + 3] = 255; -					} -				} -				tempFrameBuffer += scr_pitch; // Next row (like y++) -			} -		} else { // No expansion -			for (y = yskip; y < h; y++) { -				for (x = xskip; x < w; x++) { -					if (!(flags & FB2GL_NO_320)) { -						RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 0] = *(tempFrameBuffer+(x*_byte));  -						RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 1] = *(tempFrameBuffer+(x*_byte)+1);  -						RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 2] = *(tempFrameBuffer+(x*_byte)+2);  -					} else if (x < 256) {  -						RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 0] = *(tempFrameBuffer+(x*_byte));  -						RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 1] = *(tempFrameBuffer+(x*_byte)+1);  -						RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 2] = *(tempFrameBuffer+(x*_byte)+2);  -					} else { -						RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 0] = *(tempFrameBuffer+(x*_byte));  -						RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 1] = *(tempFrameBuffer+(x*_byte)+1);  -						RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 2] = *(tempFrameBuffer+(x*_byte)+2);  -					} -				} -				tempFrameBuffer += scr_pitch; // Next row (like y++) -			} -		} - -		if (flags & FB2GL_NO_320) { -			// Update 256x256 texture -			glBindTexture(GL_TEXTURE_2D, texture1); -			glFlush(); -			glTexSubImage2D(GL_TEXTURE_2D, 0, xskip, yskip,  -				256-xskip, 256-yskip, GL_RGBA, -				GL_UNSIGNED_BYTE, RGBAFrameBuffer1); - -			// Update 64x256 texture -			glBindTexture(GL_TEXTURE_2D, texture2); -			glFlush(); -			glTexSubImage2D(GL_TEXTURE_2D, 0, xskip, yskip, -			    64-xskip, 256-yskip, GL_RGBA, -			    GL_UNSIGNED_BYTE, RGBAFrameBuffer2); -		} else { -			// Update 320x256 texture -			glBindTexture(GL_TEXTURE_2D, texture1); -			glFlush(); -			glTexSubImage2D(GL_TEXTURE_2D, 0, xskip, yskip,  -			    320-xskip, 256-yskip, GL_RGBA, -			    GL_UNSIGNED_BYTE, RGBAFrameBuffer1); -		} - -	} else { // non RGBA (paletted) - -		for (y=0; y<h; y++) -			for (x=0; x<w; x++) { -				if (!(flags & FB2GL_NO_320)) { -					palettedFrameBuffer1[y * 320 + x] = *(tempFrameBuffer + y*scr_pitch + x); -				} else if (x<256) {  -					palettedFrameBuffer1[y * 256 + x] = *(tempFrameBuffer + y*scr_pitch + x); -				} else {  -					palettedFrameBuffer2[y * 64 + (x - 256)] = *(tempFrameBuffer + y*scr_pitch + x); -				} -			} - -		if (flags & FB2GL_NO_320) { -			// Update 256x256 texture -			glBindTexture(GL_TEXTURE_2D, texture1); -			glTexSubImage2D(GL_TEXTURE_2D, 0, xskip, yskip,  -				256-xskip, 256-yskip, GL_COLOR_INDEX,  -				GL_UNSIGNED_BYTE, palettedFrameBuffer1); -			 -			// Update 64x256 texture -			glBindTexture(GL_TEXTURE_2D, texture2); -			glTexSubImage2D(GL_TEXTURE_2D, 0, xskip, yskip,  -			    64-xskip, 256-yskip, GL_COLOR_INDEX,  -			    GL_UNSIGNED_BYTE, palettedFrameBuffer2); -		} else { -			// Update 320x256 texture -			glBindTexture(GL_TEXTURE_2D, texture1); -			glTexSubImage2D(GL_TEXTURE_2D, 0, xskip, yskip,  -				320-xskip, 256-yskip, GL_COLOR_INDEX,  -				GL_UNSIGNED_BYTE, palettedFrameBuffer1); -		} - -	} - -	display(); -} - -void FB2GL::blit16(SDL_Surface *fb, int num_rect, SDL_Rect *rect, int xskip, int yskip) { -	int x, y, i; -	int rx, ry, rw, rh; // rect[i].x, .y, .w, .h  -	// (0 <= rx <= 320) and (0 <= ry <= 240).  -	// Note: rx may be larger than texture1 width (256). -	int xend=0, yend=0; // (x + width) and (y + height) -	int pitch = fb->pitch/2; // 16 bit pointer access (not char *) -	 -	// Width of the rectangle draw in texture1. (256 - rx) > 0 -	unsigned int tex1_w = 0; -	// Width of the rectangle draw in texture2. (xend - 256) > 0 -	unsigned int tex2_w = 0; -	// Rectangle's x coordinate in texture2. (rx - 256) > 0 -	unsigned int tex2_x = 0; -	 -	for (i=0; i<num_rect; i++) { -		tex1_w = tex2_w = tex2_x = 0; -		rx = rect[i].x; -		ry = rect[i].y; -		rw = rect[i].w; -		rh = rect[i].h; -		xend = rx + rw; -		yend = ry + rh; -		if (xend > fb->w) continue; -		if (yend > fb->h) continue; - -		if (rx < 256) { // Begins before the end of texture1 -			if (xend >= 256) { // Ends after texture1 -			  tex2_w = xend - 256; //Rectangle width on texture2 -			  tex1_w = rw - tex2_w; // Width left for texture1 -			} else -				tex1_w = rw;  // This rectangle is inside texture1 -		} else { -			tex2_w = rw;       // This rectangle is inside texture2 -			tex2_x = rx - 256; // Relative x coordinate on texture2 -		} - -		// Note: if (tex1_w == 0) then there is no rectangle to draw  -		// in texture1. The same is true for tex2_w. - -		for (y = ry; y < yend; y++) { -			for (x = rx; x < xend; x++) { -			 -				if (tex1_w && x < 256) {  -					int pos = (x-rx+(y-ry)*tex1_w)*4; // (x + (y*pitch)) * RGBAsize -					SDL_GetRGB( -						((Uint16 *)fb->pixels)[x+y*(pitch)],  -						fb->format, -						&RGBAFrameBuffer1[pos], -						&RGBAFrameBuffer1[pos+1], -						&RGBAFrameBuffer1[pos+2] -					); -				} else if (tex2_w && x >= 256) { -					int rx2 = rx < 256? 256: rx; -					int pos = (x-rx2+(y-ry)*tex2_w)*4; // (x + (y*pitch)) * RGBAsize -					SDL_GetRGB( -						((Uint16 *)fb->pixels)[x+y*(pitch)],  -						fb->format, -						&RGBAFrameBuffer2[pos], -						&RGBAFrameBuffer2[pos+1], -						&RGBAFrameBuffer2[pos+2] -					); -				} -			} -		} - -		if (tex1_w > 0) { -			// Update 256x256 texture -			glBindTexture(GL_TEXTURE_2D, texture1); -			glFlush(); -			glTexSubImage2D(GL_TEXTURE_2D, 0,  -			    rx + xskip, -			    ry + yskip,  -			    tex1_w, rh, GL_RGBA, -			    GL_UNSIGNED_BYTE, RGBAFrameBuffer1); -		} -		if (tex2_w > 0) { // What was left for this texture -			// Update 64x256 texture -			glBindTexture(GL_TEXTURE_2D, texture2); -			glFlush(); -			glTexSubImage2D(GL_TEXTURE_2D, 0,  -			    tex2_x + xskip,  -			    ry + yskip,  -			    tex2_w, rh, GL_RGBA, -			    GL_UNSIGNED_BYTE, RGBAFrameBuffer2); -		} -	} -} - -void FB2GL::palette(int i, int r, int g, int b) { -	if (flags & FB2GL_EXPAND) { -		tempColorTable[i][0] = r; -		tempColorTable[i][1] = g; -		tempColorTable[i][2] = b; -	} else { // Paletted texture -		colorTable[i][0] = r; -		colorTable[i][1] = g; -		colorTable[i][2] = b; -	} -} - -void FB2GL::setPalette(int first, int n) { -	char temp[256][3]; -	int i; -  -	if (flags & FB2GL_EXPAND) { -		for (i = first; i < n; i++) { -			colorTable[i][0] = tempColorTable[i][0]; -			colorTable[i][1] = tempColorTable[i][1]; -			colorTable[i][2] = tempColorTable[i][2]; -		} -	} else { // Paletted texture -		glBindTexture(GL_TEXTURE_2D, texture1); -		glGetColorTable(GL_TEXTURE_2D, GL_RGB, GL_UNSIGNED_BYTE, &temp); -	 -		for (i = first; i < n; i++) { -			temp[i][0] = colorTable[i][0]; -			temp[i][1] = colorTable[i][1]; -			temp[i][2] = colorTable[i][2]; -		} -	 -		glColorTable(GL_TEXTURE_2D, GL_RGB, 256, GL_RGB,  -		    GL_UNSIGNED_BYTE, &temp); - -		if (flags & FB2GL_NO_320) { -			glBindTexture(GL_TEXTURE_2D, texture2); -			glColorTable(GL_TEXTURE_2D, GL_RGB, 256, GL_RGB,  -			    GL_UNSIGNED_BYTE, &temp); -		} - -	} -} diff --git a/backends/sdl/sdl_gl.cpp b/backends/sdl/sdl_gl.cpp deleted file mode 100644 index a6eed42ea6..0000000000 --- a/backends/sdl/sdl_gl.cpp +++ /dev/null @@ -1,696 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001  Ludvig Strigeus - * Copyright (C) 2001-2003 The ScummVM project - * - * 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. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. - * - * $Header$ - * - */ - -#include "sdl-common.h" -#include "common/scaler.h" -#include "common/util.h" - -#ifdef WIN32 -int glColorTable(int, int, int, int, int, void *) { return 0; } -int glGetColorTable(int, int, int, void *) { return 0; } -#endif - -#include "fb2opengl.h" - -class OSystem_SDL_OpenGL : public OSystem_SDL_Common { -public: -	OSystem_SDL_OpenGL(); - -	// Update the dirty areas of the screen -	void update_screen(); - -	// Set a parameter -	uint32 property(int param, Property *value); - -	// Get the next event. -	// Returns true if an event was retrieved.	 -	//bool poll_event(Event *event); - -protected: -	FB2GL fb2gl; -	int _glFlags; -	int _glScreenStart; -	bool _glBilinearFilter; -	bool _usingOpenGL; -	SDL_Surface *tmpSurface; // Used for black rectangles blitting  -	SDL_Rect tmpBlackRect;   // Bottom black border -	SDL_Rect _glWindow;      // Only uses w and h (for window resizing) -	int _glBottomOfTexture; -	int _glBorderHeight;     // Used if using black borders - -	SDL_Surface *_hwscreen;  // hardware screen (=> _usingOpenGL == false) - -	ScalerProc *_scaler_proc; -	 -	virtual void load_gfx_mode(); -	virtual void unload_gfx_mode(); -	virtual bool save_screenshot(const char *filename); -	void hotswap_gfx_mode(); -}; - -OSystem_SDL_Common *OSystem_SDL_Common::create_intern() { -	return new OSystem_SDL_OpenGL(); -} - -OSystem_SDL_OpenGL::OSystem_SDL_OpenGL() -  : _hwscreen(0), _scaler_proc(0) -{ -  _glScreenStart = 0;  -  _glBilinearFilter = false; -  _usingOpenGL = false; // false => Switch to filters used in the sdl.cpp version -  _glBottomOfTexture = 256; // height is always 256 -  _glBorderHeight = 0; // Forces _glScreenStart to always be 0 -  // 640x480 resolution -  _glWindow.w = 640; -  _glWindow.h = 480; -} - -void OSystem_SDL_OpenGL::load_gfx_mode() { -	uint32 Rmask, Gmask, Bmask, Amask; -	// I have to force 16 bit color depth with 565 ordering -	// SDL_SetVideoMode sometimes doesn't accept your color depth definition -	Rmask = 0xF800; // 5 -	Gmask = 0x07E0; // 6 -	Bmask = 0x001F; // 5 -	Amask = 0; - -	_forceFull = true; -	_mode_flags |= DF_UPDATE_EXPAND_1_PIXEL; - -	_tmpscreen = NULL; -	_tmpScreenWidth = (_screenWidth + 3); - -	switch(_mode) { -	case GFX_BILINEAR: -		_usingOpenGL = true; -		_mode = GFX_NORMAL; -		_scaleFactor = 1; -		_scaler_proc = Normal1x; -		break; - -	case GFX_NORMAL: -		_scaleFactor = 1; -		_scaler_proc = Normal1x; -		break; -	case GFX_DOUBLESIZE: -		_scaleFactor = 2; -		_scaler_proc = Normal2x; -		break; -	case GFX_TRIPLESIZE: -		_scaleFactor = 3; -		_scaler_proc = Normal3x; -		break; - -	case GFX_2XSAI: -		_scaleFactor = 2; -		_scaler_proc = _2xSaI; -		break; -	case GFX_SUPER2XSAI: -		_scaleFactor = 2; -		_scaler_proc = Super2xSaI; -		break; -	case GFX_SUPEREAGLE: -		_scaleFactor = 2; -		_scaler_proc = SuperEagle; -		break; -	case GFX_ADVMAME2X: -		_scaleFactor = 2; -		_scaler_proc = AdvMame2x; -		break; -	case GFX_ADVMAME3X: -		_scaleFactor = 3; -		_scaler_proc = AdvMame3x; -		break; -	case GFX_HQ2X: -		_scaleFactor = 2; -		_scaler_proc = HQ2x; -		break; -	case GFX_HQ3X: -		_scaleFactor = 3; -		_scaler_proc = HQ3x; -		break; -	case GFX_TV2X: -		_scaleFactor = 2; -		_scaler_proc = TV2x; -		break; -	case GFX_DOTMATRIX: -		_scaleFactor = 2; -		_scaler_proc = DotMatrix; -		break; - -	default: -		error("unknown gfx mode %d", _mode); -	} -	 -	if (_mode != GFX_NORMAL) { -		_usingOpenGL = false; -	} - -	// -	// Create the surface that contains the 8 bit game data -	// -	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0); -	if (_screen == NULL) -		error("_screen failed"); - -	// -	// Create the surface that contains the scaled graphics in 16 bit mode -	// -	if (_usingOpenGL) { -	   -		_glFlags = FB2GL_NO_320 | FB2GL_RGBA | FB2GL_16BIT; -		if (_full_screen) { -			_glFlags |= FB2GL_FS; -			_glScreenStart = 0; -		} -		 -		// Note: Our GL screen is vertically stretched (yfix = 15). -		// That makes visible only 320x240 of the GL screen. -		// 320x240 visible in GL screen => yfix = 15 -		// 320x200 visible in GL screen => yfix = 72 -		int yfix = 15; -		_glBorderHeight = 0; -		if (_screenHeight == 200) { -		    // If we are not using borders, we want 320x200 visible -		    yfix = _glScreenStart? 15: 72; -		    // 20 (top) + 200 (height) + 20 (bottom) = 240 -		    _glBorderHeight = 20; -		} -		// _glWindow defines the resolution -		fb2gl.init(_glWindow.w, _glWindow.h, 0, yfix, _glFlags); -		 -	} else { // SDL backend -	   -		_hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16,  -		_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE -		); -		if (_hwscreen == NULL) { -			warning("SDL_SetVideoMode says we can't switch to that mode"); -			quit(); -		} - -		// Distinguish 555 and 565 mode -		if (_hwscreen->format->Rmask == 0x7C00) -			InitScalers(555); -		else -			InitScalers(565); -	} - -	// -	// Create the surface used for the graphics in 16 bit before scaling, and also the overlay -	// - -	// Need some extra bytes around when using 2xSaI -	uint16 *tmp_screen = (uint16 *)calloc(_tmpScreenWidth * (_screenHeight + 3),sizeof(uint16)); - -	if (_usingOpenGL) { -		_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen, -						_tmpScreenWidth,  -						_screenHeight + 3,  -						16,  -						_tmpScreenWidth * 2, -						Rmask, -						Gmask, -						Bmask, -						Amask); - -		tmpBlackRect.x = 0; -		tmpBlackRect.y = 0; -		tmpBlackRect.w = _screenWidth; -		tmpBlackRect.h = 256-_screenHeight-_glScreenStart; - -		if (!_adjustAspectRatio) { -			// Disable code for now, since it causes crash if OpenGL is used from command line -/* -			// Don't use the whole screen (black borders) -			fb2gl.init(0, 0, 0, 15, _glFlags); -			_glScreenStart = _glBorderHeight; - -			// Top black border -			SDL_Rect blackrect = { -			  0,  -			  0, // _glScreenStart,  -			  _screenWidth,  -			  _newShakePos + _glScreenStart -			}; -	 -			SDL_FillRect(tmpSurface, &blackrect, 0); -			fb2gl.blit16(tmpSurface, 1, &blackrect, 0, 0); -		 -			// Bottom black border -			int _glBottomOfGameScreen = _screenHeight +  -			  _glScreenStart + _currentShakePos;  - -			tmpBlackRect.h = _glBottomOfTexture -  -			  _glBottomOfGameScreen; -			 -			SDL_FillRect(tmpSurface, &tmpBlackRect, 0); -			fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0, -			  _glBottomOfGameScreen); -*/ -		} else { -			// Use the whole screen -			fb2gl.init(0, 0, 0, 72, _glFlags); -			_glScreenStart = 0; -		} -	} else { // SDL backend -		_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen, -						_tmpScreenWidth,  -						_screenHeight + 3,  -						16,  -						_tmpScreenWidth * 2, -						_hwscreen->format->Rmask, -						_hwscreen->format->Gmask, -						_hwscreen->format->Bmask, -						_hwscreen->format->Amask); -	} - -	tmpSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth,  -						// 320x256 texture (black end) -						256-_screenHeight-_glScreenStart, -						16, -						Rmask, -						Gmask, -						Bmask, -						Amask); -	 -	if (_tmpscreen == NULL) -		error("_tmpscreen failed"); - -	// keyboard cursor control, some other better place for it? -	km.x_max = _screenWidth * _scaleFactor - 1; -	km.y_max = _screenHeight * _scaleFactor - 1; -	km.delay_time = 25; -	km.last_time = 0; -} - -void OSystem_SDL_OpenGL::unload_gfx_mode() { -   -	if (_screen) { -		SDL_FreeSurface(_screen); -		_screen = NULL;  -	} -	if (_hwscreen) { -		SDL_FreeSurface(_hwscreen); -		_hwscreen = NULL;  -	} -	if (_tmpscreen) { -		free((uint16 *)_tmpscreen->pixels); -		SDL_FreeSurface(_tmpscreen); -		_tmpscreen = NULL; -	} -} - -void OSystem_SDL_OpenGL::hotswap_gfx_mode() { -	if (!_screen) -		return; - -	// Keep around the old _screen & _tmpscreen so we can restore the screen data -	// after the mode switch. -	SDL_Surface *old_screen = _screen; -	SDL_Surface *old_tmpscreen = _tmpscreen; - -	// Release the HW screen surface -	if (fb2gl.getScreen()) { // _usingOpenGL was true -		SDL_FreeSurface(fb2gl.getScreen()); -		fb2gl.setScreen(NULL); -	} -	if (_hwscreen) { -		SDL_FreeSurface(_hwscreen); -		_hwscreen = NULL; -	} - -	// Setup the new GFX mode -	load_gfx_mode(); - -	// reset palette -	SDL_SetColors(_screen, _currentPalette, 0, 256); - -	// Restore old screen content -	SDL_BlitSurface(old_screen, NULL, _screen, NULL); -	SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL); -	 -	// Free the old surfaces -	SDL_FreeSurface(old_screen); -	free(old_tmpscreen->pixels); -	SDL_FreeSurface(old_tmpscreen); - -	// Blit everything to the screen -	update_screen(); -	 -	// Make sure that an EVENT_SCREEN_CHANGED gets sent later -	_modeChanged = true; -} - -void OSystem_SDL_OpenGL::update_screen() { - -	Common::StackLock lock(_graphicsMutex, this);	// Lock the mutex until this function ends - -	// If the shake position changed, fill the dirty area with blackness -	if (_currentShakePos != _newShakePos) { -		if (_usingOpenGL) { -			// Top black border -			SDL_Rect blackrect = { -			  0,  -			  0, // _glScreenStart,  -			  _screenWidth,  -			  _newShakePos + _glScreenStart -			}; -		 -			SDL_FillRect(tmpSurface, &blackrect, 0); -			fb2gl.blit16(tmpSurface, 1, &blackrect, 0, 0); -		} else { // SDL backend -			SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor}; - -			if (_adjustAspectRatio) -				blackrect.h = real2Aspect(blackrect.h - 1) + 1; - -			SDL_FillRect(_hwscreen, &blackrect, 0); -		} - -		_currentShakePos = _newShakePos; - -		_forceFull = true; -	} - -	// Make sure the mouse is drawn, if it should be drawn. -	draw_mouse(); -	 -	// Check whether the palette was changed in the meantime and update the -	// screen surface accordingly.  -	if (_paletteDirtyEnd != 0) { -		SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,  -			_paletteDirtyStart, -			_paletteDirtyEnd - _paletteDirtyStart); -		 -		_paletteDirtyEnd = 0; - -		_forceFull = true; -	} - -	// Force a full redraw if requested -	if (_forceFull) { -		_num_dirty_rects = 1; - -		_dirty_rect_list[0].x = 0; -		_dirty_rect_list[0].y = 0; -		_dirty_rect_list[0].w = _screenWidth; -		_dirty_rect_list[0].h = _screenHeight; -	} - -	// Only draw anything if necessary -	if (_num_dirty_rects > 0) { -	 -		SDL_Rect *r;  -		SDL_Rect dst; -		uint32 srcPitch, dstPitch; -		SDL_Rect *last_rect = _dirty_rect_list + _num_dirty_rects; - -		 -		if (_usingOpenGL) { -		 -			if (!_overlayVisible) { -				for (r = _dirty_rect_list; r != last_rect; ++r) { -					dst = *r; -					dst.x++;	// Shift rect by one since 2xSai needs to acces the data around -					dst.y++;	// any pixel to scale it, and we want to avoid mem access crashes. -					if (SDL_BlitSurface(_screen, r, _tmpscreen, &dst) != 0) -						error("SDL_BlitSurface failed: %s", SDL_GetError()); -				} -			} -			 -			// Almost the same thing as SDL_UpdateRects -			fb2gl.blit16( -			    _tmpscreen,  -			    _num_dirty_rects,  -			    _dirty_rect_list,  -			    0, -			    _currentShakePos + _glScreenStart -			); - -			int _glBottomOfGameScreen = _screenHeight +  -			  _glScreenStart + _currentShakePos;  - -			// Bottom black border height -			tmpBlackRect.h = _glBottomOfTexture - _glBottomOfGameScreen; -			if (_adjustAspectRatio && tmpBlackRect.h > 0) { -				SDL_FillRect(tmpSurface, &tmpBlackRect, 0); -				fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0, -				  _glBottomOfGameScreen); -			} - -			fb2gl.display(); -		} else { // SDL backend -			 -			if (_scaler_proc == Normal1x && !_adjustAspectRatio) { -				SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen; -				for (r = _dirty_rect_list; r != last_rect; ++r) { -					dst = *r; -					 -					if (_overlayVisible) { -						// FIXME: I don't understand why this is necessary... -						dst.x--; -						dst.y--; -					} -					dst.y += _currentShakePos; -					if (SDL_BlitSurface(target, r, _hwscreen, &dst) != 0) -						error("SDL_BlitSurface failed: %s", SDL_GetError()); -				} -			} else { -				if (!_overlayVisible) { -					for (r = _dirty_rect_list; r != last_rect; ++r) { -						dst = *r; -						dst.x++;	// Shift rect by one since 2xSai needs to acces the data around -						dst.y++;	// any pixel to scale it, and we want to avoid mem access crashes. -						if (SDL_BlitSurface(_screen, r, _tmpscreen, &dst) != 0) -							error("SDL_BlitSurface failed: %s", SDL_GetError()); -					} -				} -	 -				SDL_LockSurface(_tmpscreen); -				SDL_LockSurface(_hwscreen); -			 -				srcPitch = _tmpscreen->pitch; -				dstPitch = _hwscreen->pitch; -			 -				for (r = _dirty_rect_list; r != last_rect; ++r) { -					register int dst_y = r->y + _currentShakePos; -					register int dst_h = 0; -					register int orig_dst_y = 0; - -					if (dst_y < _screenHeight) { -						dst_h = r->h; -						if (dst_h > _screenHeight - dst_y) -							dst_h = _screenHeight - dst_y; -			 -							dst_y *= _scaleFactor; -			 -							if (_adjustAspectRatio) { -								orig_dst_y = dst_y; -								dst_y = real2Aspect(dst_y); -							} - -							_scaler_proc((byte *)_tmpscreen->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, -							(byte *)_hwscreen->pixels + r->x * 2 * _scaleFactor + dst_y * dstPitch, dstPitch, r->w, dst_h); -					} -				 -					r->x *= _scaleFactor; -					r->y = dst_y; -					r->w *= _scaleFactor; -					r->h = dst_h * _scaleFactor; - -					if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight) -						r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y); -				} -			 -				SDL_UnlockSurface(_tmpscreen); -				SDL_UnlockSurface(_hwscreen); -			} -			 -			// Readjust the dirty rect list in case we are doing a full update. -			// This is necessary if shaking is active. -			if (_forceFull) { -				_dirty_rect_list[0].y = 0; -				_dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor; -			} -			 -			// Finally, blit all our changes to the screen -			SDL_UpdateRects(_hwscreen, _num_dirty_rects, _dirty_rect_list); -		} // END OF "SDL backend" -	} // if (num_dirty_rects > 0) ... - -	_num_dirty_rects = 0; -	_forceFull = false; -} - -/* -bool OSystem_SDL_OpenGL::poll_event(Event *event) { -	SDL_Event ev; -	ev.type = 0; - - -	SDL_PeepEvents(&ev, 1, SDL_GETEVENT, SDL_VIDEORESIZEMASK); - -	if (_usingOpenGL && ev.type == SDL_VIDEORESIZE) { -	      int w = ev.resize.w;  -	      int h = ev.resize.h; -	      glViewport(0, 0, (GLsizei)w, (GLsizei)h); -	      glMatrixMode(GL_PROJECTION); -	      glLoadIdentity(); -	      glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); -	      _glWindow.w = w; -	      _glWindow.h = h; -	} - -	return OSystem_SDL_Common::poll_event(event); -} -*/ - -uint32 OSystem_SDL_OpenGL::property(int param, Property *value) { - -	Common::StackLock lock(_graphicsMutex, this); // Lock the mutex until this function ends - -	if (param == PROP_TOGGLE_FULLSCREEN) { -		if (!_usingOpenGL) -			assert(_hwscreen != 0); -		_full_screen ^= true; -#ifdef MACOSX -		// On OS X, SDL_WM_ToggleFullScreen is currently not implemented. Worse, -		// it still always returns -1. So we simply don't call it at all and -		// use hotswap_gfx_mode() directly to switch to fullscreen mode. -		hotswap_gfx_mode(); -#else -		SDL_Surface *_tmpScreen; -		if (_usingOpenGL) { -			_tmpScreen = fb2gl.getScreen(); -		}  -		else { // SDL backend -			_tmpScreen = _hwscreen; -		} - -		if (!SDL_WM_ToggleFullScreen(_tmpScreen)) { -			// if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode -			hotswap_gfx_mode(); -		} -#endif - -		return 1; -	} else if (param == PROP_TOGGLE_ASPECT_RATIO) { - -		if (_usingOpenGL) { -			_adjustAspectRatio ^= true; -			if (!_adjustAspectRatio) { -				// Don't use the whole screen (black borders) -				fb2gl.init(0, 0, 0, 15, _glFlags); -				_glScreenStart = _glBorderHeight; - -				// Top black border -				SDL_Rect blackrect = { -				  0,  -				  0, // _glScreenStart,  -				  _screenWidth,  -				  _newShakePos + _glScreenStart -				}; -		 -				SDL_FillRect(tmpSurface, &blackrect, 0); -				fb2gl.blit16(tmpSurface, 1, &blackrect, 0, 0); -				 -				// Bottom black border -				int _glBottomOfGameScreen = _screenHeight +  -				  _glScreenStart + _currentShakePos;  - -				tmpBlackRect.h = _glBottomOfTexture -  -				  _glBottomOfGameScreen; -				 -				SDL_FillRect(tmpSurface, &tmpBlackRect, 0); -				fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0, -				  _glBottomOfGameScreen); -			} else { -				// Use the whole screen -				fb2gl.init(0, 0, 0, 72, _glFlags); -				_glScreenStart = 0; -			} - -			SDL_Rect redraw = {0, 0, _screenWidth, _screenHeight}; -			fb2gl.blit16(_tmpscreen, 1, &redraw, 0, _glScreenStart); -			fb2gl.display(); -		} else { -			if (_screenHeight == 200) { -				assert(_hwscreen != 0); -				_adjustAspectRatio ^= true; -				hotswap_gfx_mode(); -			} -		} - -	} else if (param == PROP_SET_GFX_MODE) { -		if (value->gfx_mode == GFX_BILINEAR) { // OpenGL mode -			if (!_usingOpenGL) { -				_usingOpenGL = true; -				_mode = GFX_NORMAL; -				_scaleFactor = 1; -				_scaler_proc = Normal1x; -				hotswap_gfx_mode(); -			} -		} -	   -		switch(value->gfx_mode) { -			case GFX_BILINEAR: // Bilinear Filtering (on/off) -				_glBilinearFilter ^= true; -				fb2gl.setBilinearMode(_glBilinearFilter); -				break; -			default: // SDL backend -				if (value->gfx_mode > 11)	// FIXME! HACK, hard coded threshold, not good -					return 0; - -				_mode = value->gfx_mode; - -				if (_usingOpenGL) { -					_glBilinearFilter = false; -					_usingOpenGL = false; -				} -				 -				hotswap_gfx_mode(); -		}; - -/*		if (_usingOpenGL) { -			SDL_Rect redraw = {0, 0, _screenWidth, _screenHeight}; -			fb2gl.blit16(_tmpscreen, 1, &redraw, 0, _glScreenStart); -			fb2gl.display(); -		}*/ - -		return 1; -	} - -	return OSystem_SDL_Common::property(param, value); -} - -bool OSystem_SDL_OpenGL::save_screenshot(const char *filename) { -	// FIXME: I don't know how to do this yet. -	if (_usingOpenGL) -		return false; - -	Common::StackLock lock(_graphicsMutex, this);	// Lock the mutex until this function ends - -	assert(_hwscreen != NULL); -	SDL_SaveBMP(_hwscreen, filename); -	return true; -} | 
