2020-01-01 21:29:24 +01:00
|
|
|
#ifndef GRAPHICS_H
|
|
|
|
#define GRAPHICS_H
|
|
|
|
|
2020-01-31 19:25:37 +01:00
|
|
|
#include <map>
|
2020-01-01 21:29:24 +01:00
|
|
|
#include <string>
|
2020-07-19 21:43:29 +02:00
|
|
|
#include <vector>
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
#include "Game.h"
|
2020-07-19 21:43:29 +02:00
|
|
|
#include "GraphicsResources.h"
|
|
|
|
#include "Textbox.h"
|
2020-11-03 00:05:24 +01:00
|
|
|
#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
|
|
|
|
};
|
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
enum ImageNames
|
|
|
|
{
|
|
|
|
IMAGE_LEVELCOMPLETE,
|
|
|
|
IMAGE_MINIMAP,
|
|
|
|
IMAGE_COVERED,
|
|
|
|
IMAGE_ELEPHANT,
|
|
|
|
IMAGE_GAMECOMPLETE,
|
|
|
|
IMAGE_FLIPLEVELCOMPLETE,
|
|
|
|
IMAGE_FLIPGAMECOMPLETE,
|
|
|
|
IMAGE_SITE,
|
|
|
|
IMAGE_SITE2,
|
|
|
|
IMAGE_SITE3,
|
|
|
|
IMAGE_ENDING,
|
|
|
|
IMAGE_SITE4,
|
|
|
|
IMAGE_CUSTOMMINIMAP,
|
|
|
|
NUM_IMAGES
|
|
|
|
};
|
|
|
|
|
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
|
|
|
#define FADEMODE_IS_FADING(mode) ((mode) != FADE_NONE && (mode) != FADE_FULLY_BLACK)
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
class Graphics
|
|
|
|
{
|
|
|
|
public:
|
2021-09-07 03:56:39 +02:00
|
|
|
void init(void);
|
|
|
|
void destroy(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
void create_buffers(void);
|
2021-09-07 03:56:39 +02:00
|
|
|
void destroy_buffers(void);
|
2021-02-16 01:16:52 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
GraphicsResources grphx;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-04-06 01:45:40 +02:00
|
|
|
SDL_Color huetilegetcol();
|
2023-01-02 01:36:43 +01:00
|
|
|
SDL_Color bigchunkygetcol(int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-05-22 19:24:36 +02:00
|
|
|
void drawgravityline(int t, int x, int y, int w, int h);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawcoloredtile(int x, int y, int t, int r, int g, int b);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
void drawmenu(int cr, int cg, int cb, enum Menu::MenuName menu);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void processfade(void);
|
|
|
|
void setfade(const int amount);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawfade(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2024-02-01 20:02:06 +01:00
|
|
|
void setlinegap(int);
|
2024-01-17 20:26:52 +01:00
|
|
|
int getlinegap(void);
|
2021-09-07 03:56:39 +02:00
|
|
|
void createtextboxreal(
|
|
|
|
const std::string& t,
|
2023-03-18 23:11:49 +01:00
|
|
|
int xp, int yp,
|
|
|
|
int r, int g, int b,
|
2021-09-07 03:56:39 +02:00
|
|
|
bool flipme
|
|
|
|
);
|
|
|
|
void createtextbox(
|
|
|
|
const std::string& t,
|
2023-03-18 23:11:49 +01:00
|
|
|
int xp, int yp,
|
|
|
|
SDL_Color color
|
|
|
|
);
|
|
|
|
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,
|
|
|
|
SDL_Color color
|
2021-09-07 03:56:39 +02:00
|
|
|
);
|
|
|
|
void createtextboxflipme(
|
|
|
|
const std::string& t,
|
2023-03-18 23:11:49 +01:00
|
|
|
int xp, int yp,
|
|
|
|
int r, int g, int b
|
2021-09-07 03:56:39 +02:00
|
|
|
);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void textboxcenterx(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
int textboxwidth(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void textboxmoveto(int xo);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void textboxcentery(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
void textboxpad(size_t left_pad, size_t right_pad);
|
|
|
|
|
|
|
|
void textboxpadtowidth(size_t new_w);
|
|
|
|
|
2023-03-18 23:24:14 +01:00
|
|
|
void textboxcentertext(void);
|
2022-12-30 22:57:24 +01:00
|
|
|
|
2023-01-13 05:11:39 +01:00
|
|
|
void textboxprintflags(uint32_t flags);
|
|
|
|
|
2023-03-18 22:31:13 +01:00
|
|
|
void textboxbuttons(void);
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
|
|
|
|
void textboxcrewmateposition(const TextboxCrewmatePosition* crewmate_position);
|
|
|
|
|
|
|
|
void textboxoriginalcontext(const TextboxOriginalContext* original_context);
|
Save special text box state using functions
This adds a way to save the text box state of the crew remaining, ACTION
prompt, etc. text boxes by just letting there be a function that is
called to retranslate the text box when needed.
It also adds a way to ignore translating a text box and to leave it
alone, in case there's actually no text in the text box, which is the
case with Level Complete and Game Complete.
Both ways are now in an enum, TextboxTranslate. The former is
TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The
existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE,
since it's only used for cutscene scripts.
Here's a quick guide to the three ways of creating a text box now.
- TEXTTRANSLATE_NONE: You must call
graphics.textboxoriginalcontextauto() to save the existing text to the
original context of the text box, as that will be copied back to the
text box after the text of the text box is updated due to not having a
translation.
- TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and
overrides the spacing (padding and text centering). Shouldn't need to
be used outside of scriptclass.
- TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a
single parameter, a pointer to the textboxclass object to be modified.
General advice when retranslating text is to clear the `lines` vector
and then push_back the retranslated text. The function is also solely
responsible for spacing.
In most cases, you will also need to call
graphics.textboxapplyposition() or graphics.textboxadjust() afterwards.
(Some text boxes shouldn't use graphics.textboxadjust() as they are
within the 10-pixel inner border around the screen that
textboxclass::adjust tries to push the text box out of.)
This commit doesn't fix every text box just yet, though. But it fixes
the Level Complete, Game Complete, crew remaining, and ACTION prompt
text boxes, for a start.
2024-01-21 05:27:31 +01:00
|
|
|
void textboxoriginalcontextauto(void);
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
|
|
|
|
void textboxcase(char text_case);
|
|
|
|
|
Save special text box state using functions
This adds a way to save the text box state of the crew remaining, ACTION
prompt, etc. text boxes by just letting there be a function that is
called to retranslate the text box when needed.
It also adds a way to ignore translating a text box and to leave it
alone, in case there's actually no text in the text box, which is the
case with Level Complete and Game Complete.
Both ways are now in an enum, TextboxTranslate. The former is
TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The
existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE,
since it's only used for cutscene scripts.
Here's a quick guide to the three ways of creating a text box now.
- TEXTTRANSLATE_NONE: You must call
graphics.textboxoriginalcontextauto() to save the existing text to the
original context of the text box, as that will be copied back to the
text box after the text of the text box is updated due to not having a
translation.
- TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and
overrides the spacing (padding and text centering). Shouldn't need to
be used outside of scriptclass.
- TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a
single parameter, a pointer to the textboxclass object to be modified.
General advice when retranslating text is to clear the `lines` vector
and then push_back the retranslated text. The function is also solely
responsible for spacing.
In most cases, you will also need to call
graphics.textboxapplyposition() or graphics.textboxadjust() afterwards.
(Some text boxes shouldn't use graphics.textboxadjust() as they are
within the 10-pixel inner border around the screen that
textboxclass::adjust tries to push the text box out of.)
This commit doesn't fix every text box just yet, though. But it fixes
the Level Complete, Game Complete, crew remaining, and ACTION prompt
text boxes, for a start.
2024-01-21 05:27:31 +01:00
|
|
|
void textboxtranslate(TextboxTranslate translate, TextboxFunction function);
|
2023-03-18 22:31:13 +01:00
|
|
|
|
2024-01-21 20:04:00 +01:00
|
|
|
void textboxcommsrelay(const char* text);
|
2022-12-30 22:57:24 +01:00
|
|
|
|
Save special text box state using functions
This adds a way to save the text box state of the crew remaining, ACTION
prompt, etc. text boxes by just letting there be a function that is
called to retranslate the text box when needed.
It also adds a way to ignore translating a text box and to leave it
alone, in case there's actually no text in the text box, which is the
case with Level Complete and Game Complete.
Both ways are now in an enum, TextboxTranslate. The former is
TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The
existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE,
since it's only used for cutscene scripts.
Here's a quick guide to the three ways of creating a text box now.
- TEXTTRANSLATE_NONE: You must call
graphics.textboxoriginalcontextauto() to save the existing text to the
original context of the text box, as that will be copied back to the
text box after the text of the text box is updated due to not having a
translation.
- TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and
overrides the spacing (padding and text centering). Shouldn't need to
be used outside of scriptclass.
- TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a
single parameter, a pointer to the textboxclass object to be modified.
General advice when retranslating text is to clear the `lines` vector
and then push_back the retranslated text. The function is also solely
responsible for spacing.
In most cases, you will also need to call
graphics.textboxapplyposition() or graphics.textboxadjust() afterwards.
(Some text boxes shouldn't use graphics.textboxadjust() as they are
within the 10-pixel inner border around the screen that
textboxclass::adjust tries to push the text box out of.)
This commit doesn't fix every text box just yet, though. But it fixes
the Level Complete, Game Complete, crew remaining, and ACTION prompt
text boxes, for a start.
2024-01-21 05:27:31 +01:00
|
|
|
void textboxapplyposition(void);
|
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void addline(const std::string& t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2022-11-30 18:56:44 +01:00
|
|
|
void setlarge(bool large);
|
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void textboxtimer(int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-08-06 00:34:15 +02:00
|
|
|
void addsprite(int x, int y, int tile, int col);
|
|
|
|
|
2023-08-20 19:11:44 +02:00
|
|
|
void setimage(TextboxImage image);
|
|
|
|
|
2024-01-21 21:39:15 +01:00
|
|
|
void textboxindex(int index);
|
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void textboxremove(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void textboxremovefast(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void textboxactive(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02: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
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawcrewman(int x, int y, int t, bool act, bool noshift =false);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
int crewcolour(const int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void cutscenebars(void);
|
|
|
|
void cutscenebarstimer(void);
|
|
|
|
void setbars(const int position);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawpartimage(int t, int xp, int yp, int wp, int hp);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawimage(int t, int xp, int yp, bool cent=false);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-02 05:16:08 +01:00
|
|
|
void drawimagecol(int t, int xp, int yp, SDL_Color ct, bool cent= false);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
void draw_texture(SDL_Texture* image, int x, int y);
|
|
|
|
|
|
|
|
void draw_texture_part(SDL_Texture* image, int x, int y, int x2, int y2, int w, int h, int scalex, int scaley);
|
|
|
|
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height, int scalex, int scaley);
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height);
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height, int r, int g, int b, int a, int scalex, int scaley);
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height, int r, int g, int b, int a);
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height, int r, int g, int b, int scalex, int scaley);
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height, int r, int g, int b);
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height, SDL_Color color, int scalex, int scaley);
|
|
|
|
void draw_grid_tile(SDL_Texture* texture, int t, int x, int y, int width, int height, SDL_Color color);
|
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void updatetextboxes(void);
|
2023-03-30 01:28:49 +02:00
|
|
|
const char* textbox_line(char* buffer, size_t buffer_len, size_t textbox_i, size_t line_i);
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawgui(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
void draw_sprite(int x, int y, int t, int r, int g, int b);
|
|
|
|
void draw_sprite(int x, int y, int t, SDL_Color color);
|
|
|
|
|
2023-06-04 01:00:30 +02:00
|
|
|
void draw_flipsprite(int x, int y, int t, SDL_Color color);
|
|
|
|
|
2023-03-04 01:02:53 +01:00
|
|
|
void scroll_texture(SDL_Texture* texture, SDL_Texture* temp, int x, int y);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02: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
|
|
|
|
Add support for string cases in strings.xml (gendered Rescued/Missing)
I wanted to not complicate the system with different string cases (like
cgettext) if possible, and I have been able to keep the main strings a
simple English=Translation mapping thus far, but apparently strings
like "Rescued!" (which are one string in English), have to be
translated for the correct gender in some languages. So this was a good
time to add support for string cases anyway.
It's a number that can be given to a string to specify the specific
case it's used, to disambiguate identical English keys. In the case of
"Rescued!" and "Missing...", male versions of the string are case 1,
female versions are case 2, and Viridian being missing is case 3. Of
course, if a language doesn't need to use different variants, it can
simply fill in the same string for the different cases.
If any other string needs to switch to different cases: distinguish
them in the English strings.xml with the case="N" attribute (N=1 and
higher), sync language files from the translator menu (existing
translations for the uncased string will simply be copied to all cases)
and change loc::gettext("...") to loc::gettext_case("...", 1),
loc::gettext_case("...", 2), etc.
2022-12-01 01:27:30 +01:00
|
|
|
void printcrewnamestatus(int x, int y, int t, bool rescued);
|
|
|
|
|
Replace "by" for level authors with happy face
"by {author}" is a string that will cause a lot of localization-related
problems, which then become much worse when different languages and
levels can also need different fonts:
- If the author name is set to something in English instead of a name,
then it'll come out a bit weird if your VVVVVV is set to a different
language: "de various people", "por various people", etc. It's the
same problem with Discord bots completing "playing" or "watching" in
their statuses.
- Translators can't always fit "by" in two letters, and level creators
have understandably always assumed, and will continue to assume, that
"by" is two letters. So if you have your VVVVVV set to a language that
translates "by" as something long, then:
| by Various People and Others |
...may suddenly show up as something like:
|thorer Various People and Othe|
- "by" and author may need mutually incompatible fonts. For example, a
Japanese level in a Korean VVVVVV needs to be displayed with "by" in
Korean characters and the author name with Japanese characters, which
would need some very special code since languages may want to add
text both before and after the name.
- It's very possible that some languages can't translate "by" without
knowing the gender of the name, and I know some languages even
inflect names in really interesting ways (adding and even replacing
letters in first names, surnames, and anything in between, depending
on gender and what else is in the sentence).
So to solve all of this, the "by" is now replaced by a 10x10 face from
sprites.png, like a :viridian: emote. See it as a kind of avatar next
to a username, to clarify and assert that this line is for the author's
name. It should be a fairly obvious/recognizable icon, it fixes all the
above problems, and it's a bonus that we now have more happy faces in
VVVVVV.
2023-01-31 00:41:46 +01:00
|
|
|
void print_level_creator(
|
|
|
|
uint32_t print_flags,
|
|
|
|
int y,
|
|
|
|
const std::string& creator,
|
|
|
|
uint8_t r,
|
|
|
|
uint8_t g,
|
|
|
|
uint8_t b
|
|
|
|
);
|
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
int set_render_target(SDL_Texture* texture);
|
|
|
|
|
|
|
|
int set_texture_color_mod(SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b);
|
|
|
|
|
|
|
|
int set_texture_alpha_mod(SDL_Texture* texture, Uint8 alpha);
|
|
|
|
|
|
|
|
int query_texture(SDL_Texture* texture, Uint32* format, int* access, int* w, int* h);
|
|
|
|
|
|
|
|
int set_blendmode(SDL_BlendMode blendmode);
|
|
|
|
int set_blendmode(SDL_Texture* texture, SDL_BlendMode blendmode);
|
|
|
|
|
|
|
|
int clear(int r, int g, int b, int a);
|
2023-03-18 23:24:14 +01:00
|
|
|
int clear(void);
|
2023-01-07 19:28:07 +01:00
|
|
|
|
Add support for translatable sprites
Language folders can now have a graphics folder, with these files:
- sprites.png and flipsprites.png: spritesheets which contain
translated versions of the word enemies and checkpoints
- spritesmask.xml: an XML file containing all the sprites that should
be copied from the translated sprites and flipsprites images to
the original sprites/flipsprites.
This means that the translated spritesheets don't have to contain ALL
sprites - they only have to contain the translated ones. When loading
them, the game assembles a combined spritesheet with translated sprites
replacing English ones as needed, and this sheet is used to visually
substitute the normal sprites at rendering time.
It's important to note that even if 32x32 enemies have pixel-perfect
hitboxes, this is only a visual change. This has been discussed several
times on Discord - basically we don't want to give people unfair
advantages or disadvantages because of their language setting, or
change existing gameplay and speedruns tactics, which may depend on the
exact pixel arrangements of the enemies. Therefore, the hitboxes are
still based on the English sprites. This should be basically
unnoticeable for casual players, especially with some thought from
translators and artists, but there will be an option in the speedrunner
menu to display the original sprites all the time.
I removed the `VVV_freefunc(SDL_FreeSurface, *tilesheet)` in
make_array() in Graphics.cpp, which frees grphx.im_sprites_surf and
grphx.im_flipsprites_surf. Since GraphicsResources::destroy() already
frees these, it looks like the only purpose the one in make_array()
serves is to do it earlier. But now we need them again later (when
switching languages) so let's just not free them early.
2023-09-27 03:53:36 +02:00
|
|
|
bool substitute(SDL_Texture** texture);
|
|
|
|
void post_substitute(SDL_Texture* subst);
|
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
int copy_texture(SDL_Texture* texture, const SDL_Rect* src, const SDL_Rect* dest);
|
|
|
|
int copy_texture(SDL_Texture* texture, const SDL_Rect* src, const SDL_Rect* dest, double angle, const SDL_Point* center, SDL_RendererFlip flip);
|
|
|
|
|
|
|
|
int set_color(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
|
|
|
int set_color(Uint8 r, Uint8 g, Uint8 b);
|
|
|
|
int set_color(SDL_Color color);
|
|
|
|
|
2023-05-22 19:24:36 +02:00
|
|
|
int fill_rect(const SDL_Rect* rect);
|
2023-01-07 19:28:07 +01:00
|
|
|
int fill_rect(const SDL_Rect* rect, int r, int g, int b, int a);
|
|
|
|
int fill_rect(int x, int y, int w, int h, int r, int g, int b, int a);
|
|
|
|
int fill_rect(int x, int y, int w, int h, int r, int g, int b);
|
|
|
|
int fill_rect(const SDL_Rect* rect, int r, int g, int b);
|
|
|
|
int fill_rect(int r, int g, int b);
|
|
|
|
int fill_rect(const SDL_Rect* rect, SDL_Color color);
|
|
|
|
int fill_rect(int x, int y, int w, int h, SDL_Color color);
|
|
|
|
int fill_rect(SDL_Color color);
|
|
|
|
|
2023-05-22 19:24:36 +02:00
|
|
|
int draw_rect(const SDL_Rect* rect);
|
2023-03-02 07:45:22 +01:00
|
|
|
int draw_rect(const SDL_Rect* rect, int r, int g, int b, int a);
|
|
|
|
int draw_rect(int x, int y, int w, int h, int r, int g, int b, int a);
|
|
|
|
int draw_rect(int x, int y, int w, int h, int r, int g, int b);
|
|
|
|
int draw_rect(const SDL_Rect* rect, int r, int g, int b);
|
|
|
|
int draw_rect(const SDL_Rect* rect, SDL_Color color);
|
|
|
|
int draw_rect(int x, int y, int w, int h, SDL_Color color);
|
|
|
|
|
2023-05-22 19:24:36 +02:00
|
|
|
int draw_line(int x, int y, int x2, int y2);
|
|
|
|
|
|
|
|
int draw_points(const SDL_Point* points, int count);
|
|
|
|
int draw_points(const SDL_Point* points, int count, int r, int g, int b);
|
|
|
|
|
2022-12-31 01:48:27 +01:00
|
|
|
void map_tab(int opt, const char* text, bool selected = false);
|
2020-06-21 03:33:55 +02:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void map_option(int opt, int num_opts, const std::string& text, bool selected = false);
|
2020-06-23 00:23:15 +02:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawspritesetcol(int x, int y, int t, int c);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void flashlight(void);
|
|
|
|
void screenshake(void);
|
|
|
|
void updatescreenshake(void);
|
2020-04-29 02:29:59 +02:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
int screenshake_x;
|
|
|
|
int screenshake_y;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2024-01-29 01:04:02 +01:00
|
|
|
void draw_window_background(void);
|
|
|
|
|
|
|
|
void get_stretch_info(SDL_Rect* rect);
|
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void render(void);
|
|
|
|
void renderwithscreeneffects(void);
|
|
|
|
void renderfixedpre(void);
|
|
|
|
void renderfixedpost(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2024-01-09 19:55:00 +01:00
|
|
|
void draw_screenshot_border(void);
|
|
|
|
|
2023-01-29 08:32:14 +01:00
|
|
|
bool Hitest(SDL_Surface* surface1, SDL_Point p1, SDL_Surface* surface2, SDL_Point p2);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawentities(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawentity(const int i, const int yoff);
|
2020-11-01 05:38:15 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawtrophytext(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-02 01:36:43 +01:00
|
|
|
void drawtele(int x, int y, int t, SDL_Color c);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-02 01:36:43 +01:00
|
|
|
SDL_Color getRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
2020-02-10 03:23:12 +01:00
|
|
|
|
2023-01-02 01:36:43 +01:00
|
|
|
SDL_Color getRGB(Uint8 r, Uint8 g, Uint8 b);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-02 01:36:43 +01:00
|
|
|
SDL_Color RGBf(int r, int g, int b);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawbackground(int t);
|
|
|
|
void updatebackground(int t);
|
2023-08-23 19:51:11 +02:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool shouldrecoloroneway(const int tilenum, const bool mounted);
|
2023-08-23 19:51:11 +02:00
|
|
|
|
2023-03-02 07:45:22 +01:00
|
|
|
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);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawmap(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawtowermap(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawtowerspikes(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool onscreen(int t);
|
2020-06-12 02:56:12 +02:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool reloadresources(void);
|
Use levelDirError for graphics errors too
This will actually do several things:
(1) Make the tile size checks apply to the appropriate graphics files
once again.
(2) Make the game print a fallback error message if the error message
hasn't been set on the levelDirError error screen.
(3) Use levelDirError for graphics errors too.
(4) Make the error message for tile size checks failing specify both
width and height, not just a square dimension.
(5) Make the error messages mentioned above translatable.
It turns out that (1) didn't happen after #923 was merged, since #923
removed needing to process a tilesheet into a vector of surfaces for all
graphics files except sprites.png and flipsprites.png. Thus, the game
ended up only checking the correct tile sizes for those files only.
In the process of fixing this, I also got rid of the PROCESS_TILESHEET
macros and turned them into two different functions: One to make the
array, and one to check the tile size of the tilesheet.
I also did (2) just in case FILESYSTEM_levelDirHasError() returns false
even though we know we have an error.
And (3) is needed so things are unified and we have one user-facing
error message system when users load levels. To facilitate this, I
removed the title string, since it's really not needed.
Unfortunately, (1) doesn't apply to font.png again, but that's because
of the new font stuff and I'm not sure what Dav999 has in store for
error checking. But that's also why I did (4), because it looks like
tile sizes in font.png files can be different (i.e. non-square).
2023-05-18 02:00:33 +02:00
|
|
|
bool checktexturesize(
|
|
|
|
const char* filename, SDL_Texture* texture,
|
|
|
|
int tilewidth, int tileheight
|
|
|
|
);
|
2023-08-23 19:51:11 +02:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool tiles1_mounted;
|
|
|
|
bool tiles2_mounted;
|
|
|
|
bool minimap_mounted;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
bool gamecomplete_mounted;
|
|
|
|
bool levelcomplete_mounted;
|
|
|
|
bool flipgamecomplete_mounted;
|
|
|
|
bool fliplevelcomplete_mounted;
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void menuoffrender(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawtowerbackground(const TowerBG& bg_obj);
|
|
|
|
void updatetowerbackground(TowerBG& bg_obj);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-02 05:16:08 +01:00
|
|
|
SDL_Color getcol(int t);
|
2021-09-07 03:56:39 +02:00
|
|
|
void drawfinalmap(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
int rcol;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
int m;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
std::vector <SDL_Surface*> sprites_surf;
|
|
|
|
std::vector <SDL_Surface*> flipsprites_surf;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-07 19:28:07 +01:00
|
|
|
SDL_Texture* images[NUM_IMAGES];
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool flipmode;
|
|
|
|
bool setflipmode;
|
|
|
|
bool notextoutline;
|
2023-01-07 19:28:07 +01:00
|
|
|
|
|
|
|
SDL_Texture* gameTexture;
|
2023-03-21 01:05:57 +01:00
|
|
|
SDL_Texture* tempShakeTexture;
|
2023-01-07 19:28:07 +01:00
|
|
|
SDL_Texture* gameplayTexture;
|
|
|
|
SDL_Texture* menuTexture;
|
|
|
|
SDL_Texture* ghostTexture;
|
|
|
|
SDL_Texture* backgroundTexture;
|
|
|
|
SDL_Texture* foregroundTexture;
|
2023-03-04 01:02:53 +01:00
|
|
|
SDL_Texture* tempScrollingTexture;
|
2024-01-09 20:29:50 +01:00
|
|
|
SDL_Surface* tempScreenshot;
|
2024-01-08 02:56:26 +01:00
|
|
|
SDL_Surface* tempScreenshot2x;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
TowerBG towerbg;
|
|
|
|
TowerBG titlebg;
|
2020-11-03 00:05:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
SDL_Rect tiles_rect;
|
|
|
|
SDL_Rect sprites_rect;
|
|
|
|
SDL_Rect tele_rect;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
SDL_Rect footerrect;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
int linestate, linedelay;
|
|
|
|
int backoffset;
|
|
|
|
bool backgrounddrawn, foregrounddrawn;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
int menuoffset;
|
|
|
|
int oldmenuoffset;
|
|
|
|
bool resumegamemode;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02: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;
|
2021-09-07 03:56:39 +02:00
|
|
|
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
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool trinketcolset;
|
|
|
|
int trinketr, trinketg, trinketb;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-13 06:02:15 +02:00
|
|
|
std::vector <textboxclass> textboxes;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool showcutscenebars;
|
|
|
|
int cutscenebarspos;
|
|
|
|
int oldcutscenebarspos;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
static const int numstars = 50;
|
|
|
|
SDL_Rect stars[numstars];
|
|
|
|
int starsspeed[numstars];
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
static const int numbackboxes = 18;
|
|
|
|
int spcol, spcoldel;
|
|
|
|
SDL_Rect backboxes[numbackboxes];
|
|
|
|
int backboxvx[numbackboxes];
|
|
|
|
int backboxvy[numbackboxes];
|
2023-05-22 20:37:00 +02:00
|
|
|
float backboxmult;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-02 01:36:43 +01:00
|
|
|
int warpskip;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 03:56:39 +02:00
|
|
|
bool translucentroomname;
|
2020-01-29 08:17:13 +01:00
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
#ifndef GAME_DEFINITION
|
2021-09-07 03:56:39 +02:00
|
|
|
float inline lerp(const float v0, const float v1)
|
|
|
|
{
|
2022-12-30 22:57:24 +01:00
|
|
|
if (game.physics_frozen())
|
|
|
|
{
|
|
|
|
return v1;
|
|
|
|
}
|
2021-09-07 03:56:39 +02:00
|
|
|
return v0 + alpha * (v1 - v0);
|
|
|
|
}
|
2022-12-30 22:57:24 +01:00
|
|
|
#endif
|
2021-09-07 03:56:39 +02:00
|
|
|
float alpha;
|
|
|
|
|
2023-01-02 01:36:43 +01:00
|
|
|
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;
|
2021-09-07 03:56:39 +02:00
|
|
|
int col_tr;
|
|
|
|
int col_tg;
|
|
|
|
int col_tb;
|
|
|
|
void updatetitlecolours(void);
|
|
|
|
|
|
|
|
bool kludgeswnlinewidth;
|
|
|
|
|
2023-01-02 01:36:43 +01:00
|
|
|
SDL_Color crewcolourreal(int t);
|
2021-09-07 03:56:39 +02:00
|
|
|
|
2023-01-13 05:11:39 +01:00
|
|
|
void render_roomname(uint32_t font_flag, const char* roomname, int r, int g, int b);
|
2024-01-09 21:50:54 +01:00
|
|
|
|
|
|
|
void print_roomtext(int x, int y, const char* text, bool rtl);
|
2020-01-01 21:29:24 +01:00
|
|
|
};
|
|
|
|
|
2020-09-28 04:15:06 +02: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;
|
2020-09-28 04:15:06 +02:00
|
|
|
#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 */
|