1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-02 19:13:31 +02:00
VVVVVV/desktop_version/src/Graphics.h

396 lines
9.5 KiB
C
Raw Normal View History

2020-01-01 21:29:24 +01:00
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include <map>
2020-01-01 21:29:24 +01:00
#include <string>
#include <vector>
2020-01-01 21:29:24 +01:00
#include "Game.h"
#include "GraphicsResources.h"
#include "Maths.h"
#include "Textbox.h"
#include "TowerBG.h"
2020-01-01 21:29:24 +01:00
Enumify all fade modes This removes the magic numbers previously used for controlling the fade mode, which are really not readable at all unless you already know what they mean. 0: FADE_NONE 1: FADE_FULLY_BLACK 2: FADE_START_FADEOUT 3: FADE_FADING_OUT 4: FADE_START_FADEIN 5: FADE_FADING_IN There is also the macro FADEMODE_IS_FADING, which indicates when the intention is to only check if the game is fading right now, which wasn't clearly conveyed previously. I also took the opportunity to clean up the style of any lines I touched. This included rewriting if-else chains into case-switches, turning one-liner if-then statements into proper blocks, fixing up comments, and even commenting the `fademode == FADE_NONE` on the tower spike checks (which, it was previously undocumented why that check was there, but I think I know why it's there). As for type safety, we already get some by transforming the variable types into the enum. Assignment is prohibited without a cast. But, apparently, comparison is perfectly legal and won't even give so much as a warning. To work around this and make absolutely sure I made all existing comparisons now use the enum, I temporarily changed it to be an `enum class`, which is a C++11 feature that makes it so all comparisons are illegal. Unfortunately, it scopes them in a namespace with the same name as a class, so I had to temporarily define macros to make sure my existing code worked. I also had to temporarily up the standard in CMakeLists.txt to get it to compile. But after all that was done, I found the rest of the places where a comparison to an integer was used, and fixed them.
2022-04-25 09:57:47 +02:00
enum FadeBars
{
FADE_NONE,
FADE_FULLY_BLACK,
FADE_START_FADEOUT,
FADE_FADING_OUT,
FADE_START_FADEIN,
FADE_FADING_IN
};
#define FADEMODE_IS_FADING(mode) ((mode) != FADE_NONE && (mode) != FADE_FULLY_BLACK)
2020-01-01 21:29:24 +01:00
class Graphics
{
public:
void init(void);
void destroy(void);
2020-01-01 21:29:24 +01:00
void create_buffers(const SDL_PixelFormat* fmt);
void destroy_buffers(void);
GraphicsResources grphx;
2020-01-01 21:29:24 +01:00
int bfontlen(uint32_t ch);
int font_idx(uint32_t ch);
bool Makebfont(void);
2020-01-01 21:29:24 +01:00
void drawhuetile(int x, int y, int t);
void huetilesetcol(int t);
SDL_Color bigchunkygetcol(int t);
2020-01-01 21:29:24 +01:00
void drawgravityline(int t);
2020-01-01 21:29:24 +01:00
bool MakeTileArray(void);
2020-01-01 21:29:24 +01:00
bool MakeSpriteArray(void);
2020-01-01 21:29:24 +01:00
bool maketelearray(void);
2020-01-01 21:29:24 +01:00
void drawcoloredtile(int x, int y, int t, int r, int g, int b);
2020-01-01 21:29:24 +01:00
void drawmenu(int cr, int cg, int cb, enum Menu::MenuName menu);
2020-01-01 21:29:24 +01:00
void processfade(void);
void setfade(const int amount);
2020-01-01 21:29:24 +01:00
void drawfade(void);
2020-01-01 21:29:24 +01:00
void setwarprect(int a, int b, int c, int d);
2020-01-01 21:29:24 +01:00
void createtextboxreal(
const std::string& t,
int xp,
int yp,
int r,
int g,
int b,
bool flipme
);
void createtextbox(
const std::string& t,
int xp,
int yp,
int r,
int g,
int b
);
void createtextboxflipme(
const std::string& t,
int xp,
int yp,
int r,
int g,
int b
);
2020-01-01 21:29:24 +01:00
void textboxcenterx(void);
2020-01-01 21:29:24 +01:00
int textboxwidth(void);
2020-01-01 21:29:24 +01:00
void textboxmoveto(int xo);
2020-01-01 21:29:24 +01:00
void textboxcentery(void);
2020-01-01 21:29:24 +01:00
int textboxwrap(int pad);
void textboxpad(size_t left_pad, size_t right_pad);
void textboxpadtowidth(size_t new_w);
void textboxcentertext();
void textboxcommsrelay();
void textboxadjust(void);
2020-01-01 21:29:24 +01:00
void addline(const std::string& t);
2020-01-01 21:29:24 +01:00
void textboxtimer(int t);
2020-01-01 21:29:24 +01:00
void textboxremove(void);
2020-01-01 21:29:24 +01:00
void textboxremovefast(void);
2020-01-01 21:29:24 +01:00
void textboxactive(void);
2020-01-01 21:29:24 +01:00
void drawtextbox(int x, int y, int w, int h, int r, int g, int b);
2020-01-01 21:29:24 +01:00
void drawpixeltextbox(int x, int y, int w, int h, int r, int g, int b);
2020-01-01 21:29:24 +01:00
void drawcrewman(int x, int y, int t, bool act, bool noshift =false);
2020-01-01 21:29:24 +01:00
int crewcolour(const int t);
2020-01-01 21:29:24 +01:00
void cutscenebars(void);
void cutscenebarstimer(void);
void setbars(const int position);
2020-01-01 21:29:24 +01:00
void drawpartimage(int t, int xp, int yp, int wp, int hp);
2020-01-01 21:29:24 +01:00
void drawimage(int t, int xp, int yp, bool cent=false);
2020-01-01 21:29:24 +01:00
void drawimagecol(int t, int xp, int yp, bool cent= false);
2020-01-01 21:29:24 +01:00
void updatetextboxes(void);
void drawgui(void);
2020-01-01 21:29:24 +01:00
void drawsprite(int x, int y, int t, int r, int g, int b);
void drawsprite(int x, int y, int t, SDL_Color color);
2020-01-01 21:29:24 +01:00
void printcrewname(int x, int y, int t);
void printcrewnamedark(int x, int y, int t);
2020-01-01 21:29:24 +01:00
void printcrewnamestatus(int x, int y, int t, bool rescued);
void map_tab(int opt, const char* text, bool selected = false);
void map_option(int opt, int num_opts, const std::string& text, bool selected = false);
void do_print(int x, int y, const std::string& text, int r, int g, int b, int a, int scale);
void Print(int _x, int _y, const std::string& _s, int r, int g, int b, bool cen = false);
2020-01-01 21:29:24 +01:00
void PrintAlpha(int _x, int _y, const std::string& _s, int r, int g, int b, int a, bool cen = false);
bool next_wrap(size_t* start, size_t* len, const char* str, int maxwidth);
bool next_wrap_s(char buffer[], size_t buffer_size, size_t* start, const char* str, int maxwidth);
int PrintWrap(int x, int y, std::string s, int r, int g, int b, bool cen = false, int linespacing = -1, int maxwidth = -1);
void bprint(int x, int y, const std::string& t, int r, int g, int b, bool cen = false);
2020-01-01 21:29:24 +01:00
void bprintalpha(int x, int y, const std::string& t, int r, int g, int b, int a, bool cen = false);
int len(const std::string& t);
std::string string_wordwrap(const std::string& s, int maxwidth, short *lines = NULL);
std::string string_wordwrap_balanced(const std::string& s, int maxwidth);
std::string string_unwordwrap(const std::string& s);
void bigprint( int _x, int _y, const std::string& _s, int r, int g, int b, bool cen = false, int sc = 2 );
void bigbprint(int x, int y, const std::string& s, int r, int g, int b, bool cen = false, int sc = 2);
void drawspritesetcol(int x, int y, int t, int c);
2020-01-01 21:29:24 +01:00
void flashlight(void);
void screenshake(void);
void updatescreenshake(void);
int screenshake_x;
int screenshake_y;
2020-01-01 21:29:24 +01:00
void render(void);
void renderwithscreeneffects(void);
void renderfixedpre(void);
void renderfixedpost(void);
2020-01-01 21:29:24 +01:00
bool Hitest(SDL_Surface* surface1, point p1, SDL_Surface* surface2, point p2);
2020-01-01 21:29:24 +01:00
void drawentities(void);
2020-01-01 21:29:24 +01:00
void drawentity(const int i, const int yoff);
void drawtrophytext(void);
2020-01-01 21:29:24 +01:00
void bigrprint(int x, int y, const std::string& t, int r, int g, int b, bool cen = false, float sc = 2);
void bigbrprint(int x, int y, const std::string& t, int r, int g, int b, bool cen = false, float sc = 2);
2020-01-01 21:29:24 +01:00
void drawtele(int x, int y, int t, SDL_Color c);
2020-01-01 21:29:24 +01:00
SDL_Color getRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL_Color getRGB(Uint8 r, Uint8 g, Uint8 b);
2020-01-01 21:29:24 +01:00
SDL_Color RGBf(int r, int g, int b);
2020-01-01 21:29:24 +01:00
void setcolreal(SDL_Color color);
2020-01-01 21:29:24 +01:00
void drawbackground(int t);
void updatebackground(int t);
#ifndef NO_CUSTOM_LEVELS
bool shouldrecoloroneway(const int tilenum, const bool mounted);
#endif
void drawtile3( int x, int y, int t, int off, int height_subtract = 0 );
void drawtile2( int x, int y, int t );
void drawtile( int x, int y, int t );
void drawtowertile( int x, int y, int t );
void drawtowertile3( int x, int y, int t, TowerBG& bg_obj );
2020-01-01 21:29:24 +01:00
void drawmap(void);
2020-01-01 21:29:24 +01:00
void drawforetile(int x, int y, int t);
2020-01-01 21:29:24 +01:00
void drawforetile2(int x, int y, int t);
2020-01-01 21:29:24 +01:00
void drawforetile3(int x, int y, int t, int off);
2020-01-01 21:29:24 +01:00
void drawrect(int x, int y, int w, int h, int r, int g, int b);
2020-01-01 21:29:24 +01:00
void drawtowermap(void);
2020-01-01 21:29:24 +01:00
void drawtowerspikes(void);
2020-01-01 21:29:24 +01:00
bool onscreen(int t);
bool reloadresources(void);
#ifndef NO_CUSTOM_LEVELS
bool tiles1_mounted;
bool tiles2_mounted;
bool minimap_mounted;
#endif
2020-01-01 21:29:24 +01:00
bool gamecomplete_mounted;
bool levelcomplete_mounted;
bool flipgamecomplete_mounted;
bool fliplevelcomplete_mounted;
2020-01-01 21:29:24 +01:00
void menuoffrender(void);
2020-01-01 21:29:24 +01:00
void drawtowerbackground(const TowerBG& bg_obj);
void updatetowerbackground(TowerBG& bg_obj);
2020-01-01 21:29:24 +01:00
void setcol(int t);
void drawfinalmap(void);
2020-01-01 21:29:24 +01:00
SDL_Color ct;
2020-01-01 21:29:24 +01:00
int rcol;
2020-01-01 21:29:24 +01:00
int m;
2020-01-01 21:29:24 +01:00
std::vector <SDL_Surface*> images;
2020-01-01 21:29:24 +01:00
std::vector <SDL_Surface*> tele;
std::vector <SDL_Surface*> tiles;
std::vector <SDL_Surface*> tiles2;
std::vector <SDL_Surface*> tiles3;
std::vector <SDL_Surface*> entcolours;
std::vector <SDL_Surface*> sprites;
std::vector <SDL_Surface*> flipsprites;
std::vector <SDL_Surface*> bfont;
std::vector <SDL_Surface*> flipbfont;
2020-01-01 21:29:24 +01:00
bool flipmode;
bool setflipmode;
bool notextoutline;
//buffer objects. //TODO refactor buffer objects
SDL_Surface* backBuffer;
SDL_Surface* menubuffer;
SDL_Surface* foregroundBuffer;
SDL_Surface* tempBuffer;
SDL_Surface* warpbuffer;
SDL_Surface* warpbuffer_lerp;
2020-01-01 21:29:24 +01:00
TowerBG towerbg;
TowerBG titlebg;
SDL_Rect tiles_rect;
SDL_Rect sprites_rect;
SDL_Rect line_rect;
SDL_Rect tele_rect;
SDL_Rect towerbuffer_rect;
2020-01-01 21:29:24 +01:00
SDL_Rect prect;
SDL_Rect footerrect;
SDL_Surface* footerbuffer;
2020-01-01 21:29:24 +01:00
int linestate, linedelay;
int backoffset;
bool backgrounddrawn, foregrounddrawn;
2020-01-01 21:29:24 +01:00
int menuoffset;
int oldmenuoffset;
bool resumegamemode;
2020-01-01 21:29:24 +01:00
SDL_Rect warprect;
2020-01-01 21:29:24 +01:00
int crewframe;
int crewframedelay;
2020-01-01 21:29:24 +01:00
Enumify all fade modes This removes the magic numbers previously used for controlling the fade mode, which are really not readable at all unless you already know what they mean. 0: FADE_NONE 1: FADE_FULLY_BLACK 2: FADE_START_FADEOUT 3: FADE_FADING_OUT 4: FADE_START_FADEIN 5: FADE_FADING_IN There is also the macro FADEMODE_IS_FADING, which indicates when the intention is to only check if the game is fading right now, which wasn't clearly conveyed previously. I also took the opportunity to clean up the style of any lines I touched. This included rewriting if-else chains into case-switches, turning one-liner if-then statements into proper blocks, fixing up comments, and even commenting the `fademode == FADE_NONE` on the tower spike checks (which, it was previously undocumented why that check was there, but I think I know why it's there). As for type safety, we already get some by transforming the variable types into the enum. Assignment is prohibited without a cast. But, apparently, comparison is perfectly legal and won't even give so much as a warning. To work around this and make absolutely sure I made all existing comparisons now use the enum, I temporarily changed it to be an `enum class`, which is a C++11 feature that makes it so all comparisons are illegal. Unfortunately, it scopes them in a namespace with the same name as a class, so I had to temporarily define macros to make sure my existing code worked. I also had to temporarily up the standard in CMakeLists.txt to get it to compile. But after all that was done, I found the rest of the places where a comparison to an integer was used, and fixed them.
2022-04-25 09:57:47 +02:00
enum FadeBars fademode;
int fadeamount;
int oldfadeamount;
int fadebars[15];
Enumify all fade modes This removes the magic numbers previously used for controlling the fade mode, which are really not readable at all unless you already know what they mean. 0: FADE_NONE 1: FADE_FULLY_BLACK 2: FADE_START_FADEOUT 3: FADE_FADING_OUT 4: FADE_START_FADEIN 5: FADE_FADING_IN There is also the macro FADEMODE_IS_FADING, which indicates when the intention is to only check if the game is fading right now, which wasn't clearly conveyed previously. I also took the opportunity to clean up the style of any lines I touched. This included rewriting if-else chains into case-switches, turning one-liner if-then statements into proper blocks, fixing up comments, and even commenting the `fademode == FADE_NONE` on the tower spike checks (which, it was previously undocumented why that check was there, but I think I know why it's there). As for type safety, we already get some by transforming the variable types into the enum. Assignment is prohibited without a cast. But, apparently, comparison is perfectly legal and won't even give so much as a warning. To work around this and make absolutely sure I made all existing comparisons now use the enum, I temporarily changed it to be an `enum class`, which is a C++11 feature that makes it so all comparisons are illegal. Unfortunately, it scopes them in a namespace with the same name as a class, so I had to temporarily define macros to make sure my existing code worked. I also had to temporarily up the standard in CMakeLists.txt to get it to compile. But after all that was done, I found the rest of the places where a comparison to an integer was used, and fixed them.
2022-04-25 09:57:47 +02:00
enum FadeBars ingame_fademode;
2020-01-01 21:29:24 +01:00
bool trinketcolset;
int trinketr, trinketg, trinketb;
2020-01-01 21:29:24 +01:00
std::vector <textboxclass> textboxes;
2020-01-01 21:29:24 +01:00
bool showcutscenebars;
int cutscenebarspos;
int oldcutscenebarspos;
2020-01-01 21:29:24 +01:00
static const int numstars = 50;
SDL_Rect stars[numstars];
int starsspeed[numstars];
2020-01-01 21:29:24 +01:00
static const int numbackboxes = 18;
int spcol, spcoldel;
SDL_Rect backboxes[numbackboxes];
int backboxvx[numbackboxes];
int backboxvy[numbackboxes];
float backboxint[numbackboxes];
2020-01-01 21:29:24 +01:00
int warpskip;
SDL_Color warpfcol;
SDL_Color warpbcol;
2020-01-01 21:29:24 +01:00
bool translucentroomname;
std::map<int, int> font_positions;
SDL_Surface* ghostbuffer;
#ifndef GAME_DEFINITION
float inline lerp(const float v0, const float v1)
{
if (game.physics_frozen())
{
return v1;
}
return v0 + alpha * (v1 - v0);
}
#endif
float alpha;
SDL_Color col_crewred;
SDL_Color col_crewyellow;
SDL_Color col_crewgreen;
SDL_Color col_crewcyan;
SDL_Color col_crewblue;
SDL_Color col_crewpurple; //actually pink
SDL_Color col_crewinactive;
SDL_Color col_clock;
SDL_Color col_trinket;
int col_tr;
int col_tg;
int col_tb;
void updatetitlecolours(void);
bool kludgeswnlinewidth;
SDL_Color crewcolourreal(int t);
void render_roomname(const char* roomname, int r, int g, int b);
char error[128];
char error_title[128]; /* for SDL_ShowSimpleMessageBox */
2020-01-01 21:29:24 +01:00
};
#ifndef GRAPHICS_DEFINITION
Allow using help/graphics/music/game/key/map/obj everywhere This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and `obj` essentially static global objects that can be used everywhere. This is useful in case we ever need to add a new function in the future, so we don't have to bother with passing a new argument in which means we have to pass a new argument in to the function that calls that function which means having to pass a new argument into the function that calls THAT function, etc. which is a real headache when working on fan mods of the source code. Note that this changes NONE of the existing function signatures, it merely just makes those variables accessible everywhere in the same way `script` and `ed` are. Also note that some classes had to be initialized after the filesystem was initialized, but C++ would keep initializing them before the filesystem got initialized, because I *had* to put them at the top of `main.cpp`, or else they wouldn't be global variables. The only way to work around this was to use entityclass's initialization style (which I'm pretty sure entityclass of all things doesn't need to be initialized this way), where you actually initialize the class in an `init()` function, and so then you do `graphics.init()` after the filesystem initialization, AFTER doing `Graphics graphics` up at the top. I've had to do this for `graphics` (but only because its child GraphicsResources `grphx` needs to be initialized this way), `music`, and `game`. I don't think this will affect anything. Other than that, `help`, `key`, and `map` are still using the C++-intended method of having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
extern Graphics graphics;
#endif
Allow using help/graphics/music/game/key/map/obj everywhere This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and `obj` essentially static global objects that can be used everywhere. This is useful in case we ever need to add a new function in the future, so we don't have to bother with passing a new argument in which means we have to pass a new argument in to the function that calls that function which means having to pass a new argument into the function that calls THAT function, etc. which is a real headache when working on fan mods of the source code. Note that this changes NONE of the existing function signatures, it merely just makes those variables accessible everywhere in the same way `script` and `ed` are. Also note that some classes had to be initialized after the filesystem was initialized, but C++ would keep initializing them before the filesystem got initialized, because I *had* to put them at the top of `main.cpp`, or else they wouldn't be global variables. The only way to work around this was to use entityclass's initialization style (which I'm pretty sure entityclass of all things doesn't need to be initialized this way), where you actually initialize the class in an `init()` function, and so then you do `graphics.init()` after the filesystem initialization, AFTER doing `Graphics graphics` up at the top. I've had to do this for `graphics` (but only because its child GraphicsResources `grphx` needs to be initialized this way), `music`, and `game`. I don't think this will affect anything. Other than that, `help`, `key`, and `map` are still using the C++-intended method of having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
2020-01-01 21:29:24 +01:00
#endif /* GRAPHICS_H */