diff --git a/src/opengl.c b/src/opengl.c index 7240184..f82eaa1 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -320,13 +320,17 @@ SDL_Surface* gl_prepareSurface(SDL_Surface* surface) { return surface; } -/* - * Return the texture id. - * Stores real sizes in rw/rh (from POT padding). +/** + * @brief Load a surface into an opengl texture. + * @param surface Surface to load into a texture. + * @param[out] rw Real width of the texture. + * @param[out] rh Real height of the texture. + * @return The opengl texture id. */ static GLuint gl_loadSurface(SDL_Surface* surface, int *rw, int* rh) { GLuint texture; + /* Prepare the surface. */ surface = gl_prepareSurface(surface); if(rw != NULL) (*rw) = surface->w; if(rh != NULL) (*rh) = surface->h; @@ -337,8 +341,13 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int *rw, int* rh) { /* Filtering, LINEAR is better for scaling, nearest looks nicer, LINEAR */ /* also seems to create a bit of artifacts around the edges. */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + if(gl_screen.scale != 1.) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } /* Always wrap just in case. */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -358,7 +367,11 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int *rw, int* rh) { return texture; } -/* Load the SDL_Surface to an openGL texture. */ +/** + * @brief Load the SDL_Surface to a glTexture. + * @param surface Surface to load. + * @return The glTexture for surface. + */ glTexture* gl_loadImage(SDL_Surface* surface) { int rw, rh; @@ -382,7 +395,13 @@ glTexture* gl_loadImage(SDL_Surface* surface) { return texture; } -/* Load the image if not already done. */ +/** + * @brief Load an image as a texture. + * + * May not necessarily load the image but use one of it's already open. + * @param path Image to load. + * @return Texture loaded from image. + */ glTexture* gl_newImage(const char* path) { glTexList* cur, *last; @@ -414,11 +433,15 @@ glTexture* gl_newImage(const char* path) { return cur->tex; } -/* Load the image as an opengl texture directly. */ +/** + * @brief Only loads the image, does not add to stack unlike gl_newImage. + * @param path Image to load. + * @return Texture loaded from image. + */ static glTexture* gl_loadNewImage(const char* path) { SDL_Surface* tmp, *surface; glTexture* t; - uint8_t* trans = NULL; + uint8_t* trans; uint32_t filesize; char* buf; @@ -463,7 +486,13 @@ static glTexture* gl_loadNewImage(const char* path) { return t; } -/* Load the texture immediately, but also set is as a sprite. */ +/** + * @brief Load the texture immediately, but also set it as a sprite. + * @param path Image to load. + * @param sx Number of X sprites in image. + * @param sy Number of Y sprites in image. + * @return Texture loaded. + */ glTexture* gl_newSprite(const char* path, const int sx, const int sy) { glTexture* texture; if((texture = gl_newImage(path)) == NULL) @@ -480,7 +509,10 @@ glTexture* gl_newSprite(const char* path, const int sx, const int sy) { return texture; } -/* Free the texture. */ +/** + * @brief Free a texture. + * @param texture Texture to free. + */ void gl_freeTexture(glTexture* texture) { glTexList* cur, *last; @@ -530,12 +562,27 @@ void gl_freeTexture(glTexture* texture) { gl_checkErr(); } -/* Return true if pixel at pos (x,y) is transparent. */ +/** + * @brief Check to see if a pixel is transparent in a texture. + * @param t Texture to check for transparency. + * @param x X position of the pixel. + * @param y Y position of the pixel. + * @return 1 if the pixel is transparent or 0 if it isn't. + */ int gl_isTrans(const glTexture* t, const int x, const int y) { return !(t->trans[(y*(int)(t->w)+x)/8] & (1<<((y*(int)(t->w)+x)%8))); } -/* Set x and y to be the appropriate sprite for glTexture using dir. */ +/** + * @brief Set x and y to be the appropriate sprite for glTexture using dir. + * + * Very slow, try to cache if possible, like the pilots do instead of using + * in O(n^2) or worse functions. + * @param[out] x X sprite to use. + * @param[out] y Y sprite to use. + * @param t Texture to get sprite from. + * @param dir Direction to get sprite from. + */ void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) { int s, sx, sy; @@ -563,6 +610,15 @@ void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) { /* BLITTING! */ /* ================ */ +/** + * @brief Blits a texture. + * @param texture Texture to blit. + * @param x X position of the texture on the screen. + * @param y Y position of the texture on the screen. + * @param tx X position within the texture. + * @param ty Y position within the texture. + * @param c Colour to use (modifies texture colour). + */ static void gl_blitTexture(const glTexture* texture, const double x, const double y, const double tx, const double ty, const glColour* c) { @@ -598,7 +654,15 @@ static void gl_blitTexture(const glTexture* texture, gl_checkErr(); } -/* Blit the sprite at given position. */ +/** + * @brief Blits a sprite, position is relative to the player. + * @param texture Sprite to blit. + * @param bx X position of the texture relative to the player. + * @param by Y position of the texture relative to the player. + * @param sx X position of the sprite to use. + * @param sy Y position of the sprite to use. + * @param c Colour to use (modifies texture colour). + */ void gl_blitSprite(const glTexture* sprite, const double bx, const double by, const int sx, const int sy, const glColour* c) { @@ -621,7 +685,15 @@ void gl_blitSprite(const glTexture* sprite, const double bx, const double by, gl_blitTexture(sprite, x, y, tx, ty, c); } -/* Blit the sprite at pos (blits absolute position). */ +/** + * @brief Blits a sprite, position is in absolute screen coordinates. + * @param texture Sprite to blit. + * @param bx X position of the texture in screen coordinates. + * @param by Y position of the texture in screen coordinates. + * @param sx X position of the sprite to use. + * @param sy Y position of the sprite to use. + * @param c Colour to use (modifies texture colour). + */ void gl_blitStaticSprite(const glTexture* sprite, const double bx, const double by, const int sx, const int sy, const glColour* c) { @@ -638,7 +710,14 @@ void gl_blitStaticSprite(const glTexture* sprite, const double bx, gl_blitTexture(sprite, x, y, tx, ty, c); } -/* Like gl_blitStatic but scales to size. */ +/** + * @brief Blit a texture scaling it. + * @param bx X position of the texture in screen coordinates. + * @param by Y position of the texture in screen coordinates. + * @param bw Width to scale to. + * @param bh Height to scale to. + * @param c Colour to use (modifies texture colour). + */ void gl_blitScale(const glTexture* texture, const double bx, const double by, const double bw, const double bh, const glColour* c) { @@ -681,7 +760,13 @@ void gl_blitScale(const glTexture* texture, gl_checkErr(); } -/* Just straight out blit the thing at position. */ +/** + * @brief Blits a texture to a position + * @param texture Texture to blit. + * @param bx X position of the texture in screen coordinates. + * @param by Y position of the texture in screen coordinates. + * @param c Colour to use (modifies texture colour). + */ void gl_blitStatic(const glTexture* texture, const double bx, const double by, const glColour* c) { double x, y; @@ -694,12 +779,23 @@ void gl_blitStatic(const glTexture* texture, const double bx, const double by, gl_blitTexture(texture, x, y, 0, 0, c); } -/* Bind our precious camera to a vector. */ -void gl_bindCamera(const Vec2* pos) { - gl_camera = (Vec2*)pos; +/** + * @brief Bind the camera to a vector. + * + * All stuff displayed with relative functions will be affected by the camera's + * position. Does not affect stuff in screen coordinates. + * @param pos Vector to use as camera. + */ +void gl_bindCamera(Vec2* pos) { + gl_camera = pos; } -/* Draw circles. */ +/** + * @brief Draws a circle. + * @param cx X position of the center in screen coordinates. + * @param cy Y position of the center in screen coordinates. + * @param r Radius of the circle. + */ void gl_drawCircle(const double cx, const double cy, const double r) { double x, y, p; @@ -746,11 +842,23 @@ void gl_drawCircle(const double cx, const double cy, const double r) { gl_checkErr(); } -/* Draw a cirlce in a rect. */ +/** + * @brief Only displays the pixel if it's in the screen. + */ #define PIXEL(x,y) \ if((x>rx) && (y>ry) && (x= SCREEN_H)) { + gl_screen.scale = (double)gl_screen.h / 640.; + /* Must keep the proportion the same for the screen. */ gl_screen.w = (gl_screen.w * 640) / SCREEN_H; gl_screen.rw = (gl_screen.rw * SCREEN_H) / 640; gl_screen.h = 640; } + /* Handle setting the default viewport. */ gl_defViewport(); /* Finishing touches. */ @@ -1070,7 +1185,9 @@ int gl_init(void) { return 0; } -/* Reset viewport to default. */ +/** + * @brief Reset viewport to default. + */ void gl_defViewport(void) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -1081,8 +1198,8 @@ void gl_defViewport(void) { -1., /* Near. */ 1.); /* Far. */ /* Take into account possible scaling. */ - glScaled((double)gl_screen.w / (double)gl_screen.rw, - (double)gl_screen.h / (double)gl_screen.rh, 1.); + if(gl_screen.scale != 1.) + glScaled(gl_screen.scale, gl_screen.scale, 1.); } /** diff --git a/src/opengl.h b/src/opengl.h index 17d22ea..583d64c 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -42,6 +42,7 @@ typedef struct glInfo_ { int h; /**< Window viewport height. */ int rw; /**< Real window width. */ int rh; /**< Real window height. */ + double scale; /**< Scale factor. */ int depth; /**< Depth in bpp. */ int r; /**< Amount of red bits. */ int g; /**< Amount of green bits. */ @@ -117,7 +118,7 @@ void gl_blitStatic(const glTexture* texture, const double bx, const double by, const glColour* c); /* Bind the camera to a vector. */ -void gl_bindCamera(const Vec2* pos); +void gl_bindCamera(Vec2* pos); /* Circle drawing. */ void gl_drawCircle(const double x, const double y, const double r);