diff options
| -rw-r--r-- | backends/sdl/fb2opengl.h | 85 | ||||
| -rw-r--r-- | backends/sdl/sdl_gl.cpp | 78 | 
2 files changed, 109 insertions, 54 deletions
| diff --git a/backends/sdl/fb2opengl.h b/backends/sdl/fb2opengl.h index 51bfd47490..690773dd8b 100644 --- a/backends/sdl/fb2opengl.h +++ b/backends/sdl/fb2opengl.h @@ -96,11 +96,19 @@ class FB2GL {  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);  	} @@ -110,6 +118,7 @@ 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); @@ -151,14 +160,23 @@ void FB2GL::makeTextures() {  void FB2GL::makeDisplayList(int xf, int yf) { -	float xfix = xf / 128.0f; // 128 = 256/2 (half texture => 0.0 to 1.0) -	float yfix = yf / 128.0f; -	float texend;	// End of 256x256 (from -1.0 to 1.0) - -	if (flags & FB2GL_NO_320) -		texend = 96.0f / 160.0f; // 160=320/2 (== 0.0), 256-160=96. -	else -		texend = 1.0f; +	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); @@ -171,28 +189,28 @@ void FB2GL::makeDisplayList(int xf, int yf) {  	glBindTexture(GL_TEXTURE_2D, texture1);  	glBegin(GL_QUADS); -	// upper left -	glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f - yfix);  	// 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); -	// lower right -	glTexCoord2f(1.0f, 0.0f); glVertex2f(texend + xfix, 1.0f);  	// upper right -	glTexCoord2f(1.0f, 1.0f); glVertex2f(texend + xfix, -1.0f - yfix); +	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  +		// 64x256 (texture2)  		glBindTexture(GL_TEXTURE_2D, texture2);  		glBegin(GL_QUADS); -		// upper left -		glTexCoord2f(0.0f, 1.0f); glVertex2f(texend + xfix, -1.0f - yfix);  		// lower left	 -		glTexCoord2f(0.0f, 0.0f); glVertex2f(texend + xfix, 1.0f); -		// lower right -		glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f + xfix, 1.0f); +		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();  	} @@ -252,14 +270,14 @@ void FB2GL::display()  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; +	int x, y, scr_pitch, _byte;  	if (flags & FB2GL_PITCH) {  		scr_pitch = pitch; -		byte = 0; +		_byte = 0;  	} else {  		scr_pitch = w * pitch; -		byte = pitch; // Bytes perl pixel (for RGBA mode) +		_byte = pitch; // Bytes perl pixel (for RGBA mode)  	}  	if (flags & FB2GL_RGBA) { @@ -291,17 +309,17 @@ void FB2GL::update(void *fb, int w, int h, int pitch, int xskip, int yskip) {  			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);  +						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);  +						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);  +						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++) @@ -412,7 +430,7 @@ void FB2GL::blit16(SDL_Surface *fb, int num_rect, SDL_Rect *rect, int xskip, int  		for (y = ry; y < yend; y++) {  			for (x = rx; x < xend; x++) { -				if (x < 256 && tex1_w) {  +				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)],  @@ -421,7 +439,7 @@ void FB2GL::blit16(SDL_Surface *fb, int num_rect, SDL_Rect *rect, int xskip, int  						&RGBAFrameBuffer1[pos+1],  						&RGBAFrameBuffer1[pos+2]  					); -				} else if (x >= 256 && tex2_w) { +				} 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( @@ -500,5 +518,4 @@ void FB2GL::setPalette(int first, int n) {  		}  	} -  } diff --git a/backends/sdl/sdl_gl.cpp b/backends/sdl/sdl_gl.cpp index 1652046190..22fb1f10f2 100644 --- a/backends/sdl/sdl_gl.cpp +++ b/backends/sdl/sdl_gl.cpp @@ -56,9 +56,10 @@ protected:  	bool _glBilinearFilter;  	bool _usingOpenGL;  	SDL_Surface *tmpSurface; // Used for black rectangles blitting  -	SDL_Rect tmpBlackRect;   // Black rectangle at end of the GL screen +	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) @@ -77,9 +78,10 @@ OSystem_SDL_OpenGL::OSystem_SDL_OpenGL()    : _hwscreen(0), _scaler_proc(0)  {    _glScreenStart = 0;  -  _glBilinearFilter = true; +  _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; @@ -167,7 +169,7 @@ void OSystem_SDL_OpenGL::load_gfx_mode() {  	case GFX_NORMAL:  normal_mode:; -		_scaleFactor = _usingOpenGL ? 2 : 1; +		_scaleFactor = 1; //_usingOpenGL ? 2 : 1;  		_scaler_proc = Normal1x;  		break;  	default: @@ -177,9 +179,10 @@ normal_mode:;  		_scaler_proc = Normal1x;  	} -	if (_mode != GFX_NORMAL) +	if (_mode != GFX_NORMAL) {  	  _usingOpenGL = false; -	 +	} +    	//  	// Create the surface that contains the 8 bit game data  	// @@ -197,9 +200,21 @@ normal_mode:;  			_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, _glScreenStart? 15: 70,  -		    _glFlags); +		fb2gl.init(_glWindow.w, _glWindow.h, 0, yfix, _glFlags);  	} else { // SDL backend @@ -337,9 +352,10 @@ void OSystem_SDL_OpenGL::update_screen() {  	// If the shake position changed, fill the dirty area with blackness  	if (_currentShakePos != _newShakePos) {  		if (_usingOpenGL) { +			// Top black border  			SDL_Rect blackrect = {  			  0,  -			  _glScreenStart,  +			  0, // _glScreenStart,   			  _screenWidth,   			  _newShakePos + _glScreenStart  			}; @@ -416,7 +432,7 @@ void OSystem_SDL_OpenGL::update_screen() {  			// Bottom black border height  			tmpBlackRect.h = _glBottomOfTexture - _glBottomOfGameScreen; -			if (!(_full_screen) && (tmpBlackRect.h > 0)) { +			if (_adjustAspectRatio && tmpBlackRect.h > 0) {  				SDL_FillRect(tmpSurface, &tmpBlackRect, 0);  				fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0,  				  _glBottomOfGameScreen); @@ -562,17 +578,36 @@ uint32 OSystem_SDL_OpenGL::property(int param, Property *value) {  			if (_adjustAspectRatio) {  				// Don't use the whole screen (black borders)  				fb2gl.init(0, 0, 0, 15, _glFlags); -				_glScreenStart = 20; +				_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, 0); +				fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0, +				  _glBottomOfGameScreen);  			} else {  				// Use the whole screen -				fb2gl.init(0, 0, 0, 70, _glFlags); +				fb2gl.init(0, 0, 0, 72, _glFlags);  				_glScreenStart = 0;  			} -			SDL_Rect full = {0, 0, _screenWidth, _screenHeight}; -			fb2gl.blit16(_tmpscreen, 1, &full, 0, _glScreenStart); +			SDL_Rect redraw = {0, 0, _screenWidth, _screenHeight}; +			fb2gl.blit16(_tmpscreen, 1, &redraw, 0, _glScreenStart);  			fb2gl.display();  		} else {  			if (_screenHeight == 200) { @@ -587,6 +622,8 @@ uint32 OSystem_SDL_OpenGL::property(int param, Property *value) {  			if (!_usingOpenGL) {  				_usingOpenGL = true;  				_mode = GFX_NORMAL; +				_scaleFactor = 1; +				_scaler_proc = Normal1x;  				hotswap_gfx_mode();  			}  		} @@ -602,21 +639,22 @@ uint32 OSystem_SDL_OpenGL::property(int param, Property *value) {  				_mode = value->gfx_mode; -				if (_usingOpenGL) +				if (_usingOpenGL) { +					_glBilinearFilter = false;  					_usingOpenGL = false; +				}  				hotswap_gfx_mode();  		}; -		if (_usingOpenGL) { -			SDL_Rect full = {0, 0, _screenWidth, _screenHeight}; -			fb2gl.blit16(_tmpscreen, 1, &full, 0, _glScreenStart); +/*		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);  } - | 
