Move from surfaces to the SDL render system

Ever since VVVVVV was initially ported to C++ in 2.0, it has used surfaces from SDL. The downside is, that's all software rendering. This commit moves most things off of surfaces, and all into GPU, by using textures and SDL_Renderer.

Pixel-perfect collision has been kept by keeping a copy of sprites as surfaces. There's plans for pixel-perfect collision to use masks instead of reading pixel data directly, but that's out of scope for this commit.

- `graphics.reloadresources()` is now called later in `main`, because textures cannot be created without a renderer.

- This commit also removes a bunch of surface functions which are no longer needed.

- This also recaches target textures in certain places for d3d9.

- graphics.images was converted to a fixed-size array.

- fillbox and fillboxabs use SDL_RenderDrawRect instead of drawing an outline using four filled rectangles

- Update my name in the credits
This commit is contained in:
AllyTally 2023-01-07 14:28:07 -04:00 committed by Misa Elizabeth Kai
parent 556e3a110a
commit 19b2a317f1
24 changed files with 1446 additions and 1387 deletions

View File

@ -3,9 +3,9 @@ Contributors
(Ordered alphabetically by first name.)
* Alexandra Fox
* AlexApps99 (@AlexApps99)
* Allison Fleischer (AllisonFleischer)
* AllyTally (@AllyTally)
* Brian Callahan (@ibara)
* Charlie Bruce (@charliebruce)
* Christoph Böhmwalder (@chrboe)

View File

@ -85,9 +85,9 @@ static const char* patrons[] = {
/* CONTRIBUTORS.txt, again listed alphabetically (according to `sort`) by first name
* Misa is special; she gets to be listed in C++ credits alongside Ethan */
static const char* githubfriends[] = {
"Alexandra Fox",
"AlexApps99",
"Allison Fleischer",
"AllyTally",
"Brian Callahan",
"Charlie Bruce",
"Christoph Böhmwalder",

View File

@ -21,6 +21,7 @@
#include "Localization.h"
#include "LocalizationStorage.h"
#include "Map.h"
#include "Screen.h"
#include "Script.h"
#include "UtilityClass.h"
#include "Vlogging.h"
@ -1539,7 +1540,11 @@ void customlevelclass::generatecustomminimap(void)
map.custommmxsize = 240 - (map.custommmxoff * 2);
map.custommmysize = 180 - (map.custommmyoff * 2);
FillRect(graphics.images[12], graphics.getRGB(0, 0, 0));
// Start drawing the minimap
SDL_Texture* target = SDL_GetRenderTarget(gameScreen.m_renderer);
graphics.set_render_target(graphics.images[IMAGE_CUSTOMMINIMAP]);
graphics.clear();
// Scan over the map size
for (int j2 = 0; j2 < mapheight; j2++)
@ -1587,12 +1592,10 @@ void customlevelclass::generatecustomminimap(void)
if (tile >= 1)
{
// Fill in this pixel
FillRect(
graphics.images[12],
graphics.fill_rect(
(i2 * 12 * map.customzoom) + i,
(j2 * 9 * map.customzoom) + j,
1,
1,
1, 1,
graphics.getRGB(tm, tm, tm)
);
}
@ -1600,6 +1603,8 @@ void customlevelclass::generatecustomminimap(void)
}
}
}
graphics.set_render_target(target);
}
// Return a graphics-ready color based off of the given tileset and tilecol

View File

@ -22,6 +22,7 @@
#include "Script.h"
#include "UtilityClass.h"
#include "VFormat.h"
#include "Vlogging.h"
editorclass::editorclass(void)
{
@ -281,18 +282,28 @@ static int edentat( int xp, int yp )
static void fillbox(const int x, const int y, const int x2, const int y2, const SDL_Color color)
{
FillRect(graphics.backBuffer, x, y, x2-x, 1, color);
FillRect(graphics.backBuffer, x, y2-1, x2-x, 1, color);
FillRect(graphics.backBuffer, x, y, 1, y2-y, color);
FillRect(graphics.backBuffer, x2-1, y, 1, y2-y, color);
graphics.set_color(color);
const SDL_Rect rect = {x, y, x2 - x, y2 - y};
const int result = SDL_RenderDrawRect(gameScreen.m_renderer, &rect);
if (result != 0)
{
WHINE_ONCE_ARGS(("Could not render rectangle outline: %s", SDL_GetError()));
}
}
static void fillboxabs(const int x, const int y, const int x2, const int y2, const SDL_Color color)
{
FillRect(graphics.backBuffer, x, y, x2, 1, color);
FillRect(graphics.backBuffer, x, y+y2-1, x2, 1, color);
FillRect(graphics.backBuffer, x, y, 1, y2, color);
FillRect(graphics.backBuffer, x+x2-1, y, 1, y2, color);
graphics.set_color(color);
const SDL_Rect rect = {x, y, x2, y2};
const int result = SDL_RenderDrawRect(gameScreen.m_renderer, &rect);
if (result != 0)
{
WHINE_ONCE_ARGS(("Could not render rectangle outline: %s", SDL_GetError()));
}
}
@ -492,8 +503,8 @@ void editorrender(void)
const RoomProperty* const room = cl.getroomprop(ed.levx, ed.levy);
//Draw grid
graphics.clear();
ClearSurface(graphics.backBuffer);
for(int j=0; j<30; j++)
{
for(int i=0; i<40; i++)
@ -566,12 +577,12 @@ void editorrender(void)
//left edge
if(ed.freewrap((ed.levx*40)-1,j+(ed.levy*30))==1)
{
FillRect(graphics.backBuffer, 0,j*8, 2,8, graphics.getRGB(255 - help.glow, 255, 255));
graphics.fill_rect(0,j*8, 2,8, graphics.getRGB(255 - help.glow, 255, 255));
}
//right edge
if(ed.freewrap((ed.levx*40)+40,j+(ed.levy*30))==1)
{
FillRect(graphics.backBuffer, 318,j*8, 2,8, graphics.getRGB(255 - help.glow, 255, 255));
graphics.fill_rect(318,j*8, 2,8, graphics.getRGB(255 - help.glow, 255, 255));
}
}
@ -579,12 +590,12 @@ void editorrender(void)
{
if(ed.freewrap((ed.levx*40)+i,(ed.levy*30)-1)==1)
{
FillRect(graphics.backBuffer, i*8,0, 8,2, graphics.getRGB(255 - help.glow, 255, 255));
graphics.fill_rect(i*8,0, 8,2, graphics.getRGB(255 - help.glow, 255, 255));
}
if(ed.freewrap((ed.levx*40)+i,30+(ed.levy*30))==1)
{
FillRect(graphics.backBuffer, i*8,238, 8,2, graphics.getRGB(255 - help.glow, 255, 255));
graphics.fill_rect(i*8,238, 8,2, graphics.getRGB(255 - help.glow, 255, 255));
}
}
@ -595,7 +606,6 @@ void editorrender(void)
// Special case for drawing gray entities
bool custom_gray = room->tileset == 3 && room->tilecol == 6;
const SDL_Color gray_ct = {255, 255, 255, 255};
// Draw entities backward to remain accurate with ingame
for (int i = customentities.size() - 1; i >= 0; i--)
@ -613,7 +623,7 @@ void editorrender(void)
{
ed.entcolreal = graphics.getcol(18);
}
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),ed.getenemyframe(room->enemytype),ed.entcolreal);
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),ed.getenemyframe(room->enemytype),ed.entcolreal);
if(customentities[i].p1==0) graphics.Print((customentities[i].x*8)- (ed.levx*40*8)+4,(customentities[i].y*8)- (ed.levy*30*8)+4, "V", 255, 255, 255 - help.glow, false);
if(customentities[i].p1==1) graphics.Print((customentities[i].x*8)- (ed.levx*40*8)+4,(customentities[i].y*8)- (ed.levy*30*8)+4, "^", 255, 255, 255 - help.glow, false);
if(customentities[i].p1==2) graphics.Print((customentities[i].x*8)- (ed.levx*40*8)+4,(customentities[i].y*8)- (ed.levy*30*8)+4, "<", 255, 255, 255 - help.glow, false);
@ -621,18 +631,13 @@ void editorrender(void)
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,16,graphics.getRGB(255,164,255));
break;
case 2: //Threadmills & platforms
if (!INBOUNDS_VEC(obj.customplatformtile, graphics.entcolours))
{
continue;
}
tpoint.x = (customentities[i].x*8)- (ed.levx*40*8);
tpoint.y = (customentities[i].y*8)- (ed.levy*30*8);
drawRect = graphics.tiles_rect;
drawRect.x += tpoint.x;
drawRect.y += tpoint.y;
for (int j = 0; j < 4; j++) {
if (custom_gray) BlitSurfaceTinted(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect, gray_ct);
else BlitSurfaceStandard(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect);
graphics.draw_grid_tile(custom_gray ? graphics.grphx.im_entcolours_tint : graphics.grphx.im_entcolours, obj.customplatformtile, drawRect.x, drawRect.y, 8, 8);
drawRect.x += 8;
}
@ -664,8 +669,7 @@ void editorrender(void)
drawRect.x += tpoint.x;
drawRect.y += tpoint.y;
for (int j = 0; j < 4; j++) {
if (custom_gray) BlitSurfaceTinted(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect, gray_ct);
else BlitSurfaceStandard(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect);
graphics.draw_grid_tile(custom_gray ? graphics.grphx.im_entcolours_tint : graphics.grphx.im_entcolours, obj.customplatformtile, drawRect.x, drawRect.y, 8, 8);
drawRect.x += 8;
}
}
@ -682,18 +686,13 @@ void editorrender(void)
}
break;
case 3: //Disappearing Platform
if (!INBOUNDS_VEC(obj.customplatformtile, graphics.entcolours))
{
continue;
}
tpoint.x = (customentities[i].x*8)- (ed.levx*40*8);
tpoint.y = (customentities[i].y*8)- (ed.levy*30*8);
drawRect = graphics.tiles_rect;
drawRect.x += tpoint.x;
drawRect.y += tpoint.y;
for (int j = 0; j < 4; j++) {
if (custom_gray) BlitSurfaceTinted(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect, gray_ct);
else BlitSurfaceStandard(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect);
graphics.draw_grid_tile(custom_gray ? graphics.grphx.im_entcolours_tint : graphics.grphx.im_entcolours, obj.customplatformtile, drawRect.x, drawRect.y, 8, 8);
drawRect.x += 8;
}
@ -701,11 +700,11 @@ void editorrender(void)
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),32,8,graphics.getRGB(255,255,255));
break;
case 9: //Shiny Trinket
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),22,196,196,196);
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),22,196,196,196);
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,16,graphics.getRGB(255, 164, 164));
break;
case 10: //Checkpoints
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),20 + customentities[i].p1,196,196,196);
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),20 + customentities[i].p1,196,196,196);
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,16,graphics.getRGB(255, 164, 164));
break;
case 11: //Gravity lines
@ -714,7 +713,7 @@ void editorrender(void)
int tx = customentities[i].p2;
int tx2 = tx + customentities[i].p3/8;
int ty = customentities[i].y % 30;
FillRect(graphics.backBuffer, (tx*8),(ty*8)+4, (tx2-tx)*8,1, graphics.getRGB(194,194,194));
graphics.fill_rect((tx*8),(ty*8)+4, (tx2-tx)*8,1, graphics.getRGB(194,194,194));
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),8,8,graphics.getRGB(164,255,164));
}
else //Vertical
@ -722,12 +721,12 @@ void editorrender(void)
int tx = customentities[i].x % 40;
int ty = customentities[i].p2;
int ty2 = ty + customentities[i].p3/8;
FillRect(graphics.backBuffer, (tx*8)+3,(ty*8), 1,(ty2-ty)*8, graphics.getRGB(194,194,194));
graphics.fill_rect((tx*8)+3,(ty*8), 1,(ty2-ty)*8, graphics.getRGB(194,194,194));
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),8,8,graphics.getRGB(164,255,164));
}
break;
case 13://Warp tokens
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),18+(ed.entframe%2),196,196,196);
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),18+(ed.entframe%2),196,196,196);
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,16,graphics.getRGB(255, 164, 164));
if (i == edent_under_cursor)
{
@ -740,18 +739,18 @@ void editorrender(void)
}
break;
case 15: //Crewmates
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8)-4,(customentities[i].y*8)- (ed.levy*30*8),144,graphics.crewcolourreal(customentities[i].p1));
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8)-4,(customentities[i].y*8)- (ed.levy*30*8),144,graphics.crewcolourreal(customentities[i].p1));
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,24,graphics.getRGB(164,164,164));
break;
case 16: //Start
{
if(customentities[i].p1==0) //Left
{
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8)-4,(customentities[i].y*8)- (ed.levy*30*8),0,graphics.col_crewcyan);
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8)-4,(customentities[i].y*8)- (ed.levy*30*8),0,graphics.col_crewcyan);
}
else if(customentities[i].p1==1)
{
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8)-4,(customentities[i].y*8)- (ed.levy*30*8),3,graphics.col_crewcyan);
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8)-4,(customentities[i].y*8)- (ed.levy*30*8),3,graphics.col_crewcyan);
}
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,24,graphics.getRGB(255, 255, 164));
short labelcol = ed.entframe<2 ? 255 : 196;
@ -790,7 +789,7 @@ void editorrender(void)
usethistile = 0; // Flipped;
usethisy -= 8;
}
graphics.drawsprite((customentities[i].x*8)- (ed.levx*40*8), usethisy + 8, usethistile + 16, 96,96,96);
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8), usethisy + 8, usethistile + 16, 96,96,96);
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,24,graphics.getRGB(164,164,164));
if (i == edent_under_cursor)
{
@ -862,7 +861,7 @@ void editorrender(void)
{
if (customentities[i].p1 / 40 == ed.levx && customentities[i].p2 / 30 == ed.levy)
{
graphics.drawsprite((customentities[i].p1*8)- (ed.levx*40*8),(customentities[i].p2*8)- (ed.levy*30*8),18+(ed.entframe%2),64,64,64);
graphics.draw_sprite((customentities[i].p1*8)- (ed.levx*40*8),(customentities[i].p2*8)- (ed.levy*30*8),18+(ed.entframe%2),64,64,64);
fillboxabs((customentities[i].p1*8)- (ed.levx*40*8),(customentities[i].p2*8)- (ed.levy*30*8),16,16,graphics.getRGB(96, 64, 64));
if(ed.tilex+(ed.levx*40)==customentities[i].p1 && ed.tiley+(ed.levy*30)==customentities[i].p2)
{
@ -922,11 +921,12 @@ void editorrender(void)
//Draw ghosts (spooky!)
if (game.ghostsenabled) {
ClearSurface(graphics.ghostbuffer);
graphics.set_render_target(graphics.ghostTexture);
graphics.set_blendmode(graphics.ghostTexture, SDL_BLENDMODE_BLEND);
graphics.clear(0, 0, 0, 0);
for (int i = 0; i < (int)ed.ghosts.size(); i++) {
if (i <= ed.currentghosts) { // We don't want all of them to show up at once :)
if (ed.ghosts[i].rx != ed.levx || ed.ghosts[i].ry != ed.levy
|| !INBOUNDS_VEC(ed.ghosts[i].frame, graphics.sprites))
if (ed.ghosts[i].rx != ed.levx || ed.ghosts[i].ry != ed.levy)
continue;
point tpoint;
tpoint.x = ed.ghosts[i].x;
@ -937,10 +937,12 @@ void editorrender(void)
SDL_Rect drawRect = graphics.sprites_rect;
drawRect.x += tpoint.x;
drawRect.y += tpoint.y;
BlitSurfaceColoured(graphics.sprites[ed.ghosts[i].frame],NULL, graphics.ghostbuffer, &drawRect, ct);
graphics.draw_sprite(drawRect.x, drawRect.y, ed.ghosts[i].frame, ct);
}
}
SDL_BlitSurface(graphics.ghostbuffer, NULL, graphics.backBuffer, NULL);
graphics.set_render_target(graphics.gameTexture);
graphics.set_texture_alpha_mod(graphics.ghostTexture, 128);
graphics.copy_texture(graphics.ghostTexture, NULL, NULL);
}
//Draw Cursor
@ -1026,11 +1028,19 @@ void editorrender(void)
//Draw five lines of the editor
const int temp = ed.dmtile - (ed.dmtile % 40) - 80;
FillRect(graphics.backBuffer, 0,-t2,320,40, graphics.getRGB(0,0,0));
FillRect(graphics.backBuffer, 0,-t2+40,320,2, graphics.getRGB(255,255,255));
if(room->tileset==0)
graphics.fill_rect(0,-t2,320,40, graphics.getRGB(0,0,0));
graphics.fill_rect(0,-t2+40,320,2, graphics.getRGB(255,255,255));
int texturewidth;
int textureheight;
if (room->tileset == 0)
{
const int numtiles = (((int) graphics.tiles.size()) / 40) * 40;
if (graphics.query_texture(graphics.grphx.im_tiles, NULL, NULL, &texturewidth, &textureheight) != 0)
{
return;
}
const int numtiles = (int) (texturewidth / 8) * (textureheight / 8);
for(int i=0; i<40; i++)
{
@ -1043,7 +1053,11 @@ void editorrender(void)
}
else
{
const int numtiles = (((int) graphics.tiles2.size()) / 40) * 40;
if (graphics.query_texture(graphics.grphx.im_tiles2, NULL, NULL, &texturewidth, &textureheight) != 0)
{
return;
}
const int numtiles = (int) (texturewidth / 8) * (textureheight / 8);
for(int i=0; i<40; i++)
{
@ -1064,8 +1078,8 @@ void editorrender(void)
short labellen = 2 + graphics.len(loc::gettext("Tile:"));
graphics.bprint(2, 45-t2, loc::gettext("Tile:"), 196, 196, 255 - help.glow, false);
graphics.bprint(labellen+16, 45-t2, help.String(ed.dmtile), 196, 196, 255 - help.glow, false);
FillRect(graphics.backBuffer, labellen+2,44-t2,10,10, graphics.getRGB(255 - help.glow, 196, 196));
FillRect(graphics.backBuffer, labellen+3,45-t2,8,8, graphics.getRGB(0,0,0));
graphics.fill_rect(labellen+2,44-t2,10,10, graphics.getRGB(255 - help.glow, 196, 196));
graphics.fill_rect(labellen+3,45-t2,8,8, graphics.getRGB(0,0,0));
if(room->tileset==0)
{
@ -1081,8 +1095,8 @@ void editorrender(void)
short labellen = 2 + graphics.len(loc::gettext("Tile:"));
graphics.bprint(2, 12, loc::gettext("Tile:"), 196, 196, 255 - help.glow, false);
graphics.bprint(labellen+16, 12, help.String(ed.dmtile), 196, 196, 255 - help.glow, false);
FillRect(graphics.backBuffer, labellen+2,11,10,10, graphics.getRGB(255 - help.glow, 196, 196));
FillRect(graphics.backBuffer, labellen+3,12,8,8, graphics.getRGB(0,0,0));
graphics.fill_rect(labellen+2,11,10,10, graphics.getRGB(255 - help.glow, 196, 196));
graphics.fill_rect(labellen+3,12,8,8, graphics.getRGB(0,0,0));
if(room->tileset==0)
{
@ -1143,16 +1157,16 @@ void editorrender(void)
message = graphics.string_wordwrap(message, 312, &lines);
short textheight = 8*lines;
FillRect(graphics.backBuffer, 0,238-textheight,320,240, graphics.getRGB(32,32,32));
FillRect(graphics.backBuffer, 0,239-textheight,320,240, graphics.getRGB(0,0,0));
graphics.fill_rect(0,238-textheight,320,240, graphics.getRGB(32,32,32));
graphics.fill_rect(0,239-textheight,320,240, graphics.getRGB(0,0,0));
graphics.PrintWrap(4, 240-textheight, message, 255,255,255, false, 8, 312);
}
else if(ed.scripteditmod)
{
//Elaborate C64 BASIC menu goes here!
FillRect(graphics.backBuffer, 0,0,320,240, graphics.getRGB(123, 111, 218));
FillRect(graphics.backBuffer, 14,16,292,208, graphics.getRGB(61, 48, 162));
graphics.fill_rect(0,0,320,240, graphics.getRGB(123, 111, 218));
graphics.fill_rect(14,16,292,208, graphics.getRGB(61, 48, 162));
switch(ed.scripthelppage)
{
case 0:
@ -1189,7 +1203,7 @@ void editorrender(void)
case 1:
{
//Current scriptname
FillRect(graphics.backBuffer, 14,226,292,12, graphics.getRGB(61, 48, 162));
graphics.fill_rect(14,226,292,12, graphics.getRGB(61, 48, 162));
char namebuffer[SCREEN_WIDTH_CHARS + 1];
vformat_buf(
namebuffer, sizeof(namebuffer),
@ -1223,7 +1237,7 @@ void editorrender(void)
}
else
{
ClearSurface(graphics.backBuffer);
graphics.clear();
}
int tr = graphics.titlebg.r - (help.glow / 4) - int(fRandom() * 4);
@ -1245,8 +1259,8 @@ void editorrender(void)
std::string wrapped = graphics.string_wordwrap(ed.textdesc, 312, &lines);
short textheight = 8*lines+8;
FillRect(graphics.backBuffer, 0, 238-textheight, 320, 240, graphics.getRGB(32, 32, 32));
FillRect(graphics.backBuffer, 0, 239-textheight, 320, 240, graphics.getRGB(0, 0, 0));
graphics.fill_rect(0, 238-textheight, 320, 240, graphics.getRGB(32, 32, 32));
graphics.fill_rect(0, 239-textheight, 320, 240, graphics.getRGB(0, 0, 0));
graphics.PrintWrap(4, 240-textheight, wrapped, 255, 255, 255, false, 8, 312);
std::string input = key.keybuffer;
if (ed.entframe < 2)
@ -1262,8 +1276,8 @@ void editorrender(void)
else if(ed.warpmod)
{
//placing warp token
FillRect(graphics.backBuffer, 0,221,320,240, graphics.getRGB(32,32,32));
FillRect(graphics.backBuffer, 0,222,320,240, graphics.getRGB(0,0,0));
graphics.fill_rect(0,221,320,240, graphics.getRGB(32,32,32));
graphics.fill_rect(0,222,320,240, graphics.getRGB(0,0,0));
graphics.Print(4, 224, loc::gettext("Left click to place warp destination"), 196, 196, 255 - help.glow, false);
graphics.Print(4, 232, loc::gettext("Right click to cancel"), 196, 196, 255 - help.glow, false);
}
@ -1271,8 +1285,8 @@ void editorrender(void)
{
if(ed.spacemod)
{
FillRect(graphics.backBuffer, 0,208,320,240, graphics.getRGB(32,32,32));
FillRect(graphics.backBuffer, 0,209,320,240, graphics.getRGB(0,0,0));
graphics.fill_rect(0,208,320,240, graphics.getRGB(32,32,32));
graphics.fill_rect(0,209,320,240, graphics.getRGB(0,0,0));
//Draw little icons for each thingy
int tx=6, ty=211, tg=32;
@ -1281,9 +1295,9 @@ void editorrender(void)
{
for(int i=0; i<10; i++)
{
FillRect(graphics.backBuffer, 4+(i*tg), 209,20,20,graphics.getRGB(32,32,32));
graphics.fill_rect(4+(i*tg), 209,20,20,graphics.getRGB(32,32,32));
}
FillRect(graphics.backBuffer, 4+(ed.drawmode*tg), 209,20,20,graphics.getRGB(64,64,64));
graphics.fill_rect(4+(ed.drawmode*tg), 209,20,20,graphics.getRGB(64,64,64));
//0:
graphics.drawtile(tx,ty,83);
graphics.drawtile(tx+8,ty,83);
@ -1300,10 +1314,10 @@ void editorrender(void)
graphics.drawtile(tx+4,ty+4,8);
//3:
tx+=tg;
graphics.drawsprite(tx,ty,22,196,196,196);
graphics.draw_sprite(tx,ty,22,196,196,196);
//4:
tx+=tg;
graphics.drawsprite(tx,ty,21,196,196,196);
graphics.draw_sprite(tx,ty,21,196,196,196);
//5:
tx+=tg;
graphics.drawtile(tx,ty+4,3);
@ -1318,10 +1332,10 @@ void editorrender(void)
graphics.drawtile(tx+8,ty+4,1);
//8:
tx+=tg;
graphics.drawsprite(tx,ty,78+ed.entframe,196,196,196);
graphics.draw_sprite(tx,ty,78+ed.entframe,196,196,196);
//9:
tx+=tg;
FillRect(graphics.backBuffer, tx+2,ty+8,12,1,graphics.getRGB(255,255,255));
graphics.fill_rect(tx+2,ty+8,12,1,graphics.getRGB(255,255,255));
for (int i = 0; i < 10; i++)
{
@ -1339,9 +1353,9 @@ void editorrender(void)
{
for(int i=0; i<7; i++)
{
FillRect(graphics.backBuffer, 4+(i*tg), 209,20,20,graphics.getRGB(32,32,32));
graphics.fill_rect(4+(i*tg), 209,20,20,graphics.getRGB(32,32,32));
}
FillRect(graphics.backBuffer, 4+((ed.drawmode-10)*tg), 209,20,20,graphics.getRGB(64,64,64));
graphics.fill_rect(4+((ed.drawmode-10)*tg), 209,20,20,graphics.getRGB(64,64,64));
//10:
graphics.Print(tx,ty,"A",196, 196, 255 - help.glow, false);
graphics.Print(tx+8,ty,"B",196, 196, 255 - help.glow, false);
@ -1349,22 +1363,22 @@ void editorrender(void)
graphics.Print(tx+8,ty+8,"D",196, 196, 255 - help.glow, false);
//11:
tx+=tg;
graphics.drawsprite(tx,ty,17,196,196,196);
graphics.draw_sprite(tx,ty,17,196,196,196);
//12:
tx+=tg;
fillboxabs(tx+4,ty+4,8,8,graphics.getRGB(96,96,96));
//13:
tx+=tg;
graphics.drawsprite(tx,ty,18+(ed.entframe%2),196,196,196);
graphics.draw_sprite(tx,ty,18+(ed.entframe%2),196,196,196);
//14:
tx+=tg;
FillRect(graphics.backBuffer, tx+6,ty+2,4,12,graphics.getRGB(255,255,255));
graphics.fill_rect(tx+6,ty+2,4,12,graphics.getRGB(255,255,255));
//15:
tx+=tg;
graphics.drawsprite(tx,ty,186,graphics.col_crewblue);
graphics.draw_sprite(tx,ty,186,graphics.col_crewblue);
//16:
tx+=tg;
graphics.drawsprite(tx,ty,184,graphics.col_crewcyan);
graphics.draw_sprite(tx,ty,184,graphics.col_crewcyan);
for (int i = 0; i < 7; i++)
{
@ -1446,30 +1460,27 @@ void editorrender(void)
break;
}
int toolnamelen = graphics.len(toolname);
FillRect(graphics.backBuffer, 0,197,toolnamelen+8,11, graphics.getRGB(32,32,32));
FillRect(graphics.backBuffer, 0,198,toolnamelen+7,10, graphics.getRGB(0,0,0));
graphics.fill_rect(0,197,toolnamelen+8,11, graphics.getRGB(32,32,32));
graphics.fill_rect(0,198,toolnamelen+7,10, graphics.getRGB(0,0,0));
graphics.bprint(2,199, toolname, 196, 196, 255 - help.glow);
FillRect(graphics.backBuffer, 260,197,80,11, graphics.getRGB(32,32,32));
FillRect(graphics.backBuffer, 261,198,80,10, graphics.getRGB(0,0,0));
graphics.fill_rect(260,197,80,11, graphics.getRGB(32,32,32));
graphics.fill_rect(261,198,80,10, graphics.getRGB(0,0,0));
graphics.bprint(268,199, "("+help.String(ed.levx+1)+","+help.String(ed.levy+1)+")",196, 196, 255 - help.glow, false);
}
else
{
//FillRect(graphics.backBuffer, 0,230,72,240, graphics.RGB(32,32,32));
//FillRect(graphics.backBuffer, 0,231,71,240, graphics.RGB(0,0,0));
//graphics.fill_rect(0,230,72,240, graphics.RGB(32,32,32));
//graphics.fill_rect(0,231,71,240, graphics.RGB(0,0,0));
if(room->roomname!="")
{
if (graphics.translucentroomname)
{
graphics.footerrect.y = 230+ed.roomnamehide;
SDL_BlitSurface(graphics.footerbuffer, NULL, graphics.backBuffer, &graphics.footerrect);
}
else
{
FillRect(graphics.backBuffer, 0,230+ed.roomnamehide,320,10, graphics.getRGB(0,0,0));
}
graphics.footerrect.y = 230 + ed.roomnamehide;
graphics.set_blendmode(SDL_BLENDMODE_BLEND);
graphics.fill_rect(&graphics.footerrect, graphics.getRGBA(0, 0, 0, graphics.translucentroomname ? 127 : 255));
graphics.set_blendmode(SDL_BLENDMODE_NONE);
graphics.bprint(5,231+ed.roomnamehide,room->roomname, 196, 196, 255 - help.glow, true);
graphics.bprint(4, 222, loc::gettext("SPACE ^ SHIFT ^"), 196, 196, 255 - help.glow, false);
graphics.bprint(268,222, "("+help.String(ed.levx+1)+","+help.String(ed.levy+1)+")",196, 196, 255 - help.glow, false);
@ -1505,12 +1516,12 @@ void editorrender(void)
}
fillboxabs(0, 117,menuwidth+17,140,graphics.getRGB(64,64,64));
FillRect(graphics.backBuffer, 0,118,menuwidth+16,140, graphics.getRGB(0,0,0));
graphics.fill_rect(0,118,menuwidth+16,140, graphics.getRGB(0,0,0));
for (size_t i = 0; i < SDL_arraysize(shiftmenuoptions); i++)
graphics.Print(4, 120+i*10, shiftmenuoptions[i], 164,164,164,false);
fillboxabs(220, 207,100,60,graphics.getRGB(64,64,64));
FillRect(graphics.backBuffer, 221,208,160,60, graphics.getRGB(0,0,0));
graphics.fill_rect(221,208,160,60, graphics.getRGB(0,0,0));
graphics.Print(224, 210, loc::gettext("S: Save Map"),164,164,164,false);
graphics.Print(224, 220, loc::gettext("L: Load Map"),164,164,164,false);
}
@ -1584,8 +1595,8 @@ void editorrender(void)
short banner_y = 120 - textheight/2 - 5;
float alpha = graphics.lerp(ed.oldnotedelay, ed.notedelay);
FillRect(graphics.backBuffer, 0, banner_y, 320, 10+textheight, graphics.getRGB(92,92,92));
FillRect(graphics.backBuffer, 0, banner_y+1, 320, 8+textheight, graphics.getRGB(0,0,0));
graphics.fill_rect(0, banner_y, 320, 10+textheight, graphics.getRGB(92,92,92));
graphics.fill_rect(0, banner_y+1, 320, 8+textheight, graphics.getRGB(0,0,0));
graphics.PrintWrap(0,banner_y+5, wrapped, 196-((45.0f-alpha)*4), 196-((45.0f-alpha)*4), 196-((45.0f-alpha)*4), true);
}
@ -1857,14 +1868,13 @@ static void editormenuactionpress(void)
break;
case 4:
//Load level
ed.settingsmod=false;
graphics.backgrounddrawn=false;
ed.settingsmod = false;
map.nexttowercolour();
ed.keydelay = 6;
ed.getlin(TEXT_LOAD, loc::gettext("Enter map filename to load:"), &(ed.filename));
game.mapheld=true;
graphics.backgrounddrawn=false;
game.mapheld = true;
graphics.backgrounddrawn = false;
break;
case 5:
//Save level
@ -1873,8 +1883,8 @@ static void editormenuactionpress(void)
ed.keydelay = 6;
ed.getlin(TEXT_SAVE, loc::gettext("Enter map filename to save as:"), &(ed.filename));
game.mapheld=true;
graphics.backgrounddrawn=false;
game.mapheld = true;
graphics.backgrounddrawn = false;
break;
case 6:
/* Game options */
@ -1938,14 +1948,15 @@ static void editormenuactionpress(void)
ed.keydelay = 6;
ed.getlin(TEXT_SAVE, loc::gettext("Enter map filename to save as:"), &(ed.filename));
game.mapheld=true;
graphics.backgrounddrawn=false;
game.mapheld = true;
graphics.backgrounddrawn = false;
break;
case 1:
//Quit without saving
music.playef(11);
music.fadeout();
graphics.fademode = FADE_START_FADEOUT;
graphics.backgrounddrawn = false;
break;
case 2:
//Go back to editor
@ -2076,7 +2087,6 @@ void editorinput(void)
{
ed.settingsmod = true;
}
graphics.backgrounddrawn=false;
if (ed.settingsmod)
{
@ -2540,15 +2550,26 @@ void editorinput(void)
else if (key.keymap[SDLK_LCTRL] || key.keymap[SDLK_RCTRL])
{
// Ctrl modifiers
int numtiles;
int texturewidth;
int textureheight;
if (cl.getroomprop(ed.levx, ed.levy)->tileset == 0)
{
numtiles = (((int) graphics.tiles.size()) / 40) * 40;
if (graphics.query_texture(graphics.grphx.im_tiles, NULL, NULL, &texturewidth, &textureheight) != 0)
{
return;
}
}
else
{
numtiles = (((int) graphics.tiles2.size()) / 40) * 40;
if (graphics.query_texture(graphics.grphx.im_tiles2, NULL, NULL, &texturewidth, &textureheight) != 0)
{
return;
}
}
const int numtiles = (int) (texturewidth / 8) * (textureheight / 8);
ed.dmtileeditor=10;
if(left_pressed)
{
@ -2583,13 +2604,11 @@ void editorinput(void)
if (key.keymap[SDLK_F1])
{
ed.switch_tileset(true);
graphics.backgrounddrawn = false;
ed.keydelay = 6;
}
if (key.keymap[SDLK_F2])
{
ed.switch_tilecol(true);
graphics.backgrounddrawn = false;
ed.keydelay = 6;
}
if (key.keymap[SDLK_F3])
@ -2600,7 +2619,6 @@ void editorinput(void)
if (key.keymap[SDLK_w])
{
ed.switch_warpdir(true);
graphics.backgrounddrawn = false;
ed.keydelay = 6;
}
@ -2659,13 +2677,11 @@ void editorinput(void)
if(key.keymap[SDLK_F1])
{
ed.switch_tileset(false);
graphics.backgrounddrawn = false;
ed.keydelay = 6;
}
if(key.keymap[SDLK_F2])
{
ed.switch_tilecol(false);
graphics.backgrounddrawn = false;
ed.keydelay = 6;
}
if(key.keymap[SDLK_F3])
@ -2703,11 +2719,11 @@ void editorinput(void)
cl.setroomdirectmode(ed.levx, ed.levy, 1);
ed.note=loc::gettext("Direct Mode Enabled");
}
graphics.backgrounddrawn=false;
graphics.backgrounddrawn = false;
ed.notedelay=45;
ed.updatetiles=true;
ed.keydelay=6;
ed.notedelay = 45;
ed.updatetiles = true;
ed.keydelay = 6;
}
if(key.keymap[SDLK_1]) ed.drawmode=0;
if(key.keymap[SDLK_2]) ed.drawmode=1;
@ -2730,7 +2746,6 @@ void editorinput(void)
if(key.keymap[SDLK_w])
{
ed.switch_warpdir(false);
graphics.backgrounddrawn = false;
ed.keydelay = 6;
}
if(key.keymap[SDLK_e])
@ -2848,7 +2863,6 @@ void editorinput(void)
}
music.haltdasmusik();
graphics.backgrounddrawn=false;
ed.returneditoralpha = 1000; // Let's start it higher than 255 since it gets clamped
ed.oldreturneditoralpha = 1000;
script.startgamemode(Start_EDITORPLAYTESTING);
@ -2891,45 +2905,45 @@ void editorinput(void)
if(up_pressed)
{
ed.keydelay=6;
graphics.backgrounddrawn=false;
ed.keydelay = 6;
ed.levy--;
ed.updatetiles=true;
ed.changeroom=true;
ed.updatetiles = true;
ed.changeroom = true;
graphics.backgrounddrawn = false;
}
else if(down_pressed)
{
ed.keydelay=6;
graphics.backgrounddrawn=false;
ed.keydelay = 6;
ed.levy++;
ed.updatetiles=true;
ed.changeroom=true;
ed.updatetiles = true;
ed.changeroom = true;
graphics.backgrounddrawn = false;
}
else if(left_pressed)
{
ed.keydelay=6;
graphics.backgrounddrawn=false;
ed.keydelay = 6;
ed.levx--;
ed.updatetiles=true;
ed.changeroom=true;
ed.updatetiles = true;
ed.changeroom = true;
graphics.backgrounddrawn = false;
}
else if(right_pressed)
{
ed.keydelay=6;
graphics.backgrounddrawn=false;
ed.keydelay = 6;
ed.levx++;
ed.updatetiles=true;
ed.changeroom=true;
ed.updatetiles = true;
ed.changeroom = true;
graphics.backgrounddrawn = false;
}
if(ed.levx<0) ed.levx+=cl.mapwidth;
if(ed.levx>= cl.mapwidth) ed.levx-=cl.mapwidth;
if(ed.levy<0) ed.levy+=cl.mapheight;
if(ed.levy>=cl.mapheight) ed.levy-=cl.mapheight;
if(key.keymap[SDLK_SPACE])
if (ed.levx < 0) ed.levx += cl.mapwidth;
if (ed.levx >= cl.mapwidth) ed.levx -= cl.mapwidth;
if (ed.levy < 0) ed.levy += cl.mapheight;
if (ed.levy >= cl.mapheight) ed.levy -= cl.mapheight;
if (key.keymap[SDLK_SPACE])
{
ed.spacemod = !ed.spacemod;
ed.keydelay=6;
ed.keydelay = 6;
}
}
@ -4248,6 +4262,8 @@ void editorclass::switch_tileset(const bool reversed)
note = buffer;
notedelay = 45;
updatetiles = true;
graphics.backgrounddrawn = false;
}
void editorclass::switch_tilecol(const bool reversed)
@ -4270,6 +4286,8 @@ void editorclass::switch_tilecol(const bool reversed)
notedelay = 45;
note = loc::gettext("Tileset Colour Changed");
updatetiles = true;
graphics.backgrounddrawn = false;
}
void editorclass::clamp_tilecol(const int rx, const int ry, const bool wrap)
@ -4381,6 +4399,8 @@ void editorclass::switch_warpdir(const bool reversed)
}
notedelay = 45;
graphics.backgrounddrawn = false;
}
#endif /* NO_CUSTOM_LEVELS and NO_EDITOR */

View File

@ -4785,7 +4785,8 @@ void entityclass::collisioncheck(int i, int j, bool scm /*= false*/)
colpoint2.y = entities[j].yp;
int drawframe1 = entities[i].collisiondrawframe;
int drawframe2 = entities[j].drawframe;
std::vector<SDL_Surface*>& spritesvec = graphics.flipmode ? graphics.flipsprites : graphics.sprites;
std::vector<SDL_Surface*>& spritesvec = graphics.flipmode ? graphics.flipsprites_surf : graphics.sprites_surf;
if (INBOUNDS_VEC(drawframe1, spritesvec) && INBOUNDS_VEC(drawframe2, spritesvec)
&& graphics.Hitest(spritesvec[drawframe1],
colpoint1, spritesvec[drawframe2], colpoint2))

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,24 @@ enum FadeBars
FADE_FADING_IN
};
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
};
#define FADEMODE_IS_FADING(mode) ((mode) != FADE_NONE && (mode) != FADE_FULLY_BLACK)
class Graphics
@ -29,7 +47,7 @@ public:
void init(void);
void destroy(void);
void create_buffers(const SDL_PixelFormat* fmt);
void create_buffers(void);
void destroy_buffers(void);
GraphicsResources grphx;
@ -39,18 +57,13 @@ public:
bool Makebfont(void);
void drawhuetile(int x, int y, int t, SDL_Color ct);
SDL_Color huetilegetcol(int t);
SDL_Color bigchunkygetcol(int t);
void drawgravityline(int t);
bool MakeTileArray(void);
bool MakeSpriteArray(void);
bool maketelearray(void);
void drawcoloredtile(int x, int y, int t, int r, int g, int b);
void drawmenu(int cr, int cg, int cb, enum Menu::MenuName menu);
@ -134,17 +147,63 @@ public:
void drawimagecol(int t, int xp, int yp, SDL_Color ct, bool cent= false);
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);
void updatetextboxes(void);
void drawgui(void);
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);
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);
void scroll_texture(SDL_Texture* texture, int x, int y);
void printcrewname(int x, int y, int t);
void printcrewnamedark(int x, int y, int t);
void printcrewnamestatus(int x, int y, int t, bool rescued);
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);
int clear();
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);
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(int r, int g, int b, int a);
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);
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);
@ -261,28 +320,22 @@ public:
int m;
std::vector <SDL_Surface*> images;
std::vector <SDL_Surface*> sprites_surf;
std::vector <SDL_Surface*> flipsprites_surf;
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;
SDL_Texture* images[NUM_IMAGES];
bool flipmode;
bool setflipmode;
bool notextoutline;
//buffer objects. //TODO refactor buffer objects
SDL_Surface* backBuffer;
SDL_Surface* menubuffer;
SDL_Surface* foregroundBuffer;
SDL_Surface* menuoffbuffer;
SDL_Surface* warpbuffer;
SDL_Surface* warpbuffer_lerp;
SDL_Texture* gameTexture;
SDL_Texture* tempTexture;
SDL_Texture* gameplayTexture;
SDL_Texture* menuTexture;
SDL_Texture* ghostTexture;
SDL_Texture* backgroundTexture;
SDL_Texture* foregroundTexture;
TowerBG towerbg;
TowerBG titlebg;
@ -291,11 +344,9 @@ public:
SDL_Rect sprites_rect;
SDL_Rect line_rect;
SDL_Rect tele_rect;
SDL_Rect towerbuffer_rect;
SDL_Rect prect;
SDL_Rect footerrect;
SDL_Surface* footerbuffer;
int linestate, linedelay;
int backoffset;
@ -340,8 +391,6 @@ public:
std::map<int, int> font_positions;
SDL_Surface* ghostbuffer;
#ifndef GAME_DEFINITION
float inline lerp(const float v0, const float v1)
{

View File

@ -2,7 +2,9 @@
#include "Alloc.h"
#include "FileSystemUtils.h"
#include "GraphicsUtil.h"
#include "Vlogging.h"
#include "Screen.h"
// Used to load PNG data
extern "C"
@ -17,19 +19,15 @@ extern "C"
extern const char* lodepng_error_text(unsigned code);
}
/* Don't declare `static`, this is used elsewhere */
SDL_Surface* LoadImage(const char *filename)
static SDL_Surface* LoadImageRaw(const char* filename, unsigned char** data)
{
//Temporary storage for the image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
unsigned char *data;
unsigned int width, height;
unsigned int error;
unsigned char *fileIn;
unsigned char* fileIn;
size_t length;
FILESYSTEM_loadAssetToMemory(filename, &fileIn, &length, false);
if (fileIn == NULL)
@ -37,7 +35,7 @@ SDL_Surface* LoadImage(const char *filename)
SDL_assert(0 && "Image file missing!");
return NULL;
}
error = lodepng_decode32(&data, &width, &height, fileIn, length);
error = lodepng_decode32(data, &width, &height, fileIn, length);
VVV_free(fileIn);
if (error != 0)
@ -47,7 +45,7 @@ SDL_Surface* LoadImage(const char *filename)
}
loadedImage = SDL_CreateRGBSurfaceWithFormatFrom(
data,
*data,
width,
height,
32,
@ -55,61 +53,260 @@ SDL_Surface* LoadImage(const char *filename)
SDL_PIXELFORMAT_ABGR8888
);
return loadedImage;
}
static SDL_Surface* LoadSurfaceFromRaw(SDL_Surface* loadedImage)
{
SDL_Surface* optimizedImage = SDL_ConvertSurfaceFormat(
loadedImage,
SDL_PIXELFORMAT_ARGB8888,
0
);
SDL_SetSurfaceBlendMode(optimizedImage, SDL_BLENDMODE_BLEND);
return optimizedImage;
}
/* Can't be static, used in Screen.h */
SDL_Surface* LoadImageSurface(const char* filename)
{
unsigned char* data;
SDL_Surface* loadedImage = LoadImageRaw(filename, &data);
SDL_Surface* optimizedImage = LoadSurfaceFromRaw(loadedImage);
if (loadedImage != NULL)
{
optimizedImage = SDL_ConvertSurfaceFormat(
loadedImage,
SDL_PIXELFORMAT_ARGB8888,
0
);
VVV_freefunc(SDL_FreeSurface, loadedImage);
VVV_free(data);
SDL_SetSurfaceBlendMode(optimizedImage, SDL_BLENDMODE_BLEND);
return optimizedImage;
}
else
VVV_free(data);
if (optimizedImage == NULL)
{
VVV_free(data);
vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr.");
}
return optimizedImage;
}
static SDL_Texture* LoadTextureFromRaw(const char* filename, SDL_Surface* loadedImage, const TextureLoadType loadtype)
{
if (loadedImage == NULL)
{
return NULL;
}
// Modify the surface with the load type.
// This could be done in LoadImageRaw, however currently, surfaces are only used for
// pixel perfect collision (which will be changed later) and the window icon.
switch (loadtype)
{
case TEX_WHITE:
SDL_LockSurface(loadedImage);
for (int y = 0; y < loadedImage->h; y++)
{
for (int x = 0; x < loadedImage->w; x++)
{
SDL_Color color = ReadPixel(loadedImage, x, y);
color.r = 255;
color.g = 255;
color.b = 255;
DrawPixel(loadedImage, x, y, color);
}
}
SDL_UnlockSurface(loadedImage);
break;
case TEX_GRAYSCALE:
SDL_LockSurface(loadedImage);
for (int y = 0; y < loadedImage->h; y++)
{
for (int x = 0; x < loadedImage->w; x++)
{
SDL_Color color = ReadPixel(loadedImage, x, y);
// Magic numbers used for grayscaling (eyes perceive certain colors brighter than others)
Uint8 r = color.r * 0.299;
Uint8 g = color.g * 0.587;
Uint8 b = color.b * 0.114;
const double gray = SDL_floor(r + g + b + 0.5);
color.r = gray;
color.g = gray;
color.b = gray;
DrawPixel(loadedImage, x, y, color);
}
}
SDL_UnlockSurface(loadedImage);
break;
default:
break;
}
//Create texture from surface pixels
SDL_Texture* texture = SDL_CreateTextureFromSurface(gameScreen.m_renderer, loadedImage);
if (texture == NULL)
{
vlog_error("Failed creating texture: %s. SDL error: %s\n", filename, SDL_GetError());
}
return texture;
}
static SDL_Texture* LoadImage(const char *filename, const TextureLoadType loadtype)
{
unsigned char* data;
SDL_Surface* loadedImage = LoadImageRaw(filename, &data);
SDL_Texture* texture = LoadTextureFromRaw(filename, loadedImage, loadtype);
if (loadedImage != NULL)
{
VVV_freefunc(SDL_FreeSurface, loadedImage);
}
VVV_free(data);
if (texture == NULL)
{
vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr.");
}
return texture;
}
static SDL_Texture* LoadImage(const char* filename)
{
return LoadImage(filename, TEX_COLOR);
}
/* Any unneeded variants can be NULL */
static void LoadVariants(const char* filename, SDL_Texture** colored, SDL_Texture** white, SDL_Texture** grayscale)
{
unsigned char* data;
SDL_Surface* loadedImage = LoadImageRaw(filename, &data);
if (colored != NULL)
{
*colored = LoadTextureFromRaw(filename, loadedImage, TEX_COLOR);
if (*colored == NULL)
{
vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr.");
}
}
if (grayscale != NULL)
{
*grayscale = LoadTextureFromRaw(filename, loadedImage, TEX_GRAYSCALE);
if (*grayscale == NULL)
{
vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr.");
}
}
if (white != NULL)
{
*white = LoadTextureFromRaw(filename, loadedImage, TEX_WHITE);
if (*white == NULL)
{
vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr.");
}
}
if (loadedImage != NULL)
{
VVV_freefunc(SDL_FreeSurface, loadedImage);
}
VVV_free(data);
}
/* The pointers `texture` and `surface` cannot be NULL */
static void LoadSprites(const char* filename, SDL_Texture** texture, SDL_Surface** surface)
{
unsigned char* data;
SDL_Surface* loadedImage = LoadImageRaw(filename, &data);
*texture = LoadTextureFromRaw(filename, loadedImage, TEX_WHITE);
if (*texture == NULL)
{
vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr.");
}
*surface = LoadSurfaceFromRaw(loadedImage);
if (*surface == NULL)
{
vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr.");
}
if (loadedImage != NULL)
{
VVV_freefunc(SDL_FreeSurface, loadedImage);
}
VVV_free(data);
}
void GraphicsResources::init(void)
{
im_tiles = LoadImage("graphics/tiles.png");
im_tiles2 = LoadImage("graphics/tiles2.png");
im_tiles3 = LoadImage("graphics/tiles3.png");
im_entcolours = LoadImage("graphics/entcolours.png");
im_sprites = LoadImage("graphics/sprites.png");
im_flipsprites = LoadImage("graphics/flipsprites.png");
im_bfont = LoadImage("graphics/font.png");
im_teleporter = LoadImage("graphics/teleporter.png");
LoadVariants("graphics/tiles.png", &im_tiles, &im_tiles_white, &im_tiles_tint);
LoadVariants("graphics/tiles2.png", &im_tiles2, NULL, &im_tiles2_tint);
LoadVariants("graphics/entcolours.png", &im_entcolours, NULL, &im_entcolours_tint);
im_image0 = LoadImage("graphics/levelcomplete.png");
im_image1 = LoadImage("graphics/minimap.png");
im_image2 = LoadImage("graphics/covered.png");
im_image3 = LoadImage("graphics/elephant.png");
im_image4 = LoadImage("graphics/gamecomplete.png");
im_image5 = LoadImage("graphics/fliplevelcomplete.png");
im_image6 = LoadImage("graphics/flipgamecomplete.png");
im_image7 = LoadImage("graphics/site.png");
im_image8 = LoadImage("graphics/site2.png");
im_image9 = LoadImage("graphics/site3.png");
im_image10 = LoadImage("graphics/ending.png");
im_image11 = LoadImage("graphics/site4.png");
im_image12 = LoadImage("graphics/minimap.png");
LoadSprites("graphics/sprites.png", &im_sprites, &im_sprites_surf);
LoadSprites("graphics/flipsprites.png", &im_flipsprites, &im_flipsprites_surf);
im_tiles3 = LoadImage("graphics/tiles3.png");
im_bfont = LoadImage("graphics/font.png", TEX_WHITE);
im_teleporter = LoadImage("graphics/teleporter.png", TEX_WHITE);
im_image0 = LoadImage("graphics/levelcomplete.png");
im_image1 = LoadImage("graphics/minimap.png");
im_image2 = LoadImage("graphics/covered.png");
im_image3 = LoadImage("graphics/elephant.png", TEX_WHITE);
im_image4 = LoadImage("graphics/gamecomplete.png");
im_image5 = LoadImage("graphics/fliplevelcomplete.png");
im_image6 = LoadImage("graphics/flipgamecomplete.png");
im_image7 = LoadImage("graphics/site.png", TEX_WHITE);
im_image8 = LoadImage("graphics/site2.png", TEX_WHITE);
im_image9 = LoadImage("graphics/site3.png", TEX_WHITE);
im_image10 = LoadImage("graphics/ending.png");
im_image11 = LoadImage("graphics/site4.png", TEX_WHITE);
im_image12 = SDL_CreateTexture(gameScreen.m_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 240, 180);
if (im_image12 == NULL)
{
vlog_error("Failed to create minimap texture: %s", SDL_GetError());
SDL_assert(0 && "Failed to create minimap texture! See stderr.");
return;
}
}
void GraphicsResources::destroy(void)
{
#define CLEAR(img) VVV_freefunc(SDL_FreeSurface, img)
#define CLEAR(img) VVV_freefunc(SDL_DestroyTexture, img)
CLEAR(im_tiles);
CLEAR(im_tiles_white);
CLEAR(im_tiles_tint);
CLEAR(im_tiles2);
CLEAR(im_tiles2_tint);
CLEAR(im_tiles3);
CLEAR(im_entcolours);
CLEAR(im_entcolours_tint);
CLEAR(im_sprites);
CLEAR(im_flipsprites);
CLEAR(im_bfont);
@ -129,4 +326,7 @@ void GraphicsResources::destroy(void)
CLEAR(im_image11);
CLEAR(im_image12);
#undef CLEAR
VVV_freefunc(SDL_FreeSurface, im_sprites_surf);
VVV_freefunc(SDL_FreeSurface, im_flipsprites_surf);
}

View File

@ -3,33 +3,47 @@
#include <SDL.h>
enum TextureLoadType
{
TEX_COLOR,
TEX_WHITE,
TEX_GRAYSCALE
};
class GraphicsResources
{
public:
void init(void);
void destroy(void);
SDL_Surface* im_tiles;
SDL_Surface* im_tiles2;
SDL_Surface* im_tiles3;
SDL_Surface* im_entcolours;
SDL_Surface* im_sprites;
SDL_Surface* im_flipsprites;
SDL_Surface* im_bfont;
SDL_Surface* im_teleporter;
SDL_Surface* im_image0;
SDL_Surface* im_image1;
SDL_Surface* im_image2;
SDL_Surface* im_image3;
SDL_Surface* im_image4;
SDL_Surface* im_image5;
SDL_Surface* im_image6;
SDL_Surface* im_image7;
SDL_Surface* im_image8;
SDL_Surface* im_image9;
SDL_Surface* im_image10;
SDL_Surface* im_image11;
SDL_Surface* im_image12;
SDL_Surface* im_sprites_surf;
SDL_Surface* im_flipsprites_surf;
SDL_Texture* im_tiles;
SDL_Texture* im_tiles_white;
SDL_Texture* im_tiles_tint;
SDL_Texture* im_tiles2;
SDL_Texture* im_tiles2_tint;
SDL_Texture* im_tiles3;
SDL_Texture* im_entcolours;
SDL_Texture* im_entcolours_tint;
SDL_Texture* im_sprites;
SDL_Texture* im_flipsprites;
SDL_Texture* im_bfont;
SDL_Texture* im_teleporter;
SDL_Texture* im_image0;
SDL_Texture* im_image1;
SDL_Texture* im_image2;
SDL_Texture* im_image3;
SDL_Texture* im_image4;
SDL_Texture* im_image5;
SDL_Texture* im_image6;
SDL_Texture* im_image7;
SDL_Texture* im_image8;
SDL_Texture* im_image9;
SDL_Texture* im_image10;
SDL_Texture* im_image11;
SDL_Texture* im_image12;
};
#endif /* GRAPHICSRESOURCES_H */

View File

@ -3,8 +3,12 @@
#include <stdlib.h>
#include "Alloc.h"
#include "Constants.h"
#include "Graphics.h"
#include "Maths.h"
#include "Screen.h"
#include "UtilityClass.h"
#include "Vlogging.h"
@ -52,20 +56,6 @@ static SDL_Surface* RecreateSurfaceWithDimensions(
return retval;
}
static SDL_Surface* RecreateSurface(SDL_Surface* surface)
{
if (surface == NULL)
{
return NULL;
}
return RecreateSurfaceWithDimensions(
surface,
surface->w,
surface->h
);
}
SDL_Surface* GetSubSurface( SDL_Surface* metaSurface, int x, int y, int width, int height )
{
// Create an SDL_Rect with the area of the _surface
@ -89,7 +79,7 @@ SDL_Surface* GetSubSurface( SDL_Surface* metaSurface, int x, int y, int width, i
return preSurface;
}
static void DrawPixel(SDL_Surface* surface, const int x, const int y, const SDL_Color color)
void DrawPixel(SDL_Surface* surface, const int x, const int y, const SDL_Color color)
{
const SDL_PixelFormat* fmt = surface->format;
const int bpp = fmt->BytesPerPixel;
@ -130,188 +120,6 @@ SDL_Color ReadPixel(const SDL_Surface* surface, const int x, const int y)
return color;
}
SDL_Surface * ScaleSurface( SDL_Surface *_surface, int Width, int Height, SDL_Surface * Dest )
{
if(!_surface || !Width || !Height)
return 0;
SDL_Surface *_ret;
if(Dest == NULL)
{
_ret = RecreateSurfaceWithDimensions(_surface, Width, Height);
if(_ret == NULL)
{
return NULL;
}
}
else
{
_ret = Dest;
}
SDL_BlitScaled(_surface, NULL, _ret, NULL);
return _ret;
}
SDL_Surface * FlipSurfaceVerticle(SDL_Surface* _src)
{
SDL_Surface * ret = RecreateSurface(_src);
if(ret == NULL)
{
return NULL;
}
for(Sint32 y = 0; y < _src->h; y++)
{
for(Sint32 x = 0; x < _src->w; x++)
{
DrawPixel(ret, x ,(_src->h-1) - y ,ReadPixel(_src, x, y));
}
}
return ret;
}
void BlitSurfaceStandard( SDL_Surface* _src, SDL_Rect* _srcRect, SDL_Surface* _dest, SDL_Rect* _destRect )
{
SDL_BlitSurface( _src, _srcRect, _dest, _destRect );
}
static void BlitSurfaceTransform(
SDL_Surface* src,
const SDL_Rect* src_rect,
SDL_Surface* dest,
SDL_Rect* dest_rect,
SDL_Color (*transform)(SDL_Color pixel, SDL_Color color),
const SDL_Color color
) {
if (src == NULL || dest == NULL || transform == NULL)
{
return;
}
if (color.a == 0)
{
return;
}
SDL_Rect orig_rect;
if (src_rect == NULL)
{
setRect(orig_rect, 0, 0, src->w, src->h);
}
else
{
orig_rect = *src_rect;
}
int blit_x;
int blit_y;
if (dest_rect == NULL)
{
blit_x = 0;
blit_y = 0;
}
else
{
blit_x = dest_rect->x;
blit_y = dest_rect->y;
}
/* FIXME: Find a way to do this without allocating... */
SDL_Surface* tempsurface = RecreateSurfaceWithDimensions(src, orig_rect.w, orig_rect.h);
if (tempsurface == NULL)
{
return;
}
SDL_SetSurfaceBlendMode(tempsurface, SDL_BLENDMODE_BLEND);
for (int x = 0; x < orig_rect.w; x++)
{
for (int y = 0; y < orig_rect.h; y++)
{
if (blit_x + x < 0 || blit_y + y < 0 ||
blit_x + x >= dest->w || blit_y + y >= dest->h)
{
continue;
}
const SDL_Color pixel = ReadPixel(src, orig_rect.x + x, orig_rect.y + y);
if (pixel.a == 0)
{
continue;
}
const SDL_Color result = transform(pixel, color);
DrawPixel(tempsurface, x, y, result);
}
}
SDL_Rect final_rect = {blit_x, blit_y, 0, 0};
SDL_BlitSurface(tempsurface, NULL, dest, &final_rect);
VVV_freefunc(SDL_FreeSurface, tempsurface);
}
static SDL_Color transform_color(const SDL_Color pixel, const SDL_Color color)
{
const float div1 = pixel.a / 255.0f;
const float div2 = color.a / 255.0f;
const Uint8 alpha = (div1 * div2) * 255.0f;
const SDL_Color result = {color.r, color.g, color.b, alpha};
return result;
}
void BlitSurfaceColoured(
SDL_Surface* src,
const SDL_Rect* src_rect,
SDL_Surface* dest,
SDL_Rect* dest_rect,
const SDL_Color color
) {
return BlitSurfaceTransform(
src, src_rect, dest, dest_rect, transform_color, color
);
}
static SDL_Color transform_tint(const SDL_Color pixel, const SDL_Color color)
{
double red = pixel.r * 0.299;
double green = pixel.g * 0.587;
double blue = pixel.b * 0.114;
const double gray = SDL_floor(red + green + blue + 0.5);
red = gray * color.r / 255.0;
green = gray * color.g / 255.0;
blue = gray * color.b / 255.0;
red = SDL_clamp(red, 0, 255);
green = SDL_clamp(green, 0, 255);
blue = SDL_clamp(blue, 0, 255);
const float div1 = pixel.a / 255.0f;
const float div2 = color.a / 255.0f;
const Uint8 alpha = (div1 * div2) * 255.0f;
const SDL_Color result = {(Uint8) red, (Uint8) green, (Uint8) blue, alpha};
return result;
}
void BlitSurfaceTinted(
SDL_Surface* src,
const SDL_Rect* src_rect,
SDL_Surface* dest,
SDL_Rect* dest_rect,
const SDL_Color color
) {
return BlitSurfaceTransform(
src, src_rect, dest, dest_rect, transform_tint, color
);
}
static int oldscrollamount = 0;
static int scrollamount = 0;
static bool isscrolling = 0;
@ -336,15 +144,40 @@ void UpdateFilter(void)
}
}
SDL_Surface* ApplyFilter(SDL_Surface* src)
void ApplyFilter(void)
{
SDL_Surface* ret = RecreateSurface(src);
// Copy the screen to a temporary surface
SDL_Surface* src = SDL_CreateRGBSurface(0, SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS, 32, 0, 0, 0, 0);
if (src == NULL)
{
return;
}
const int result = SDL_RenderReadPixels(gameScreen.m_renderer, NULL, 0, src->pixels, src->pitch);
if (result != 0)
{
SDL_FreeSurface(src);
WHINE_ONCE_ARGS(("Could not read pixels from renderer: %s", SDL_GetError()));
return;
}
Uint32 rawFormat;
if (graphics.query_texture(graphics.gameTexture, &rawFormat, NULL, NULL, NULL) != 0)
{
return;
}
SDL_PixelFormat* format = SDL_AllocFormat(rawFormat);
// Have a second surface to do work on
SDL_Surface* dest = SDL_CreateRGBSurface(0, SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS, 32, 0, 0, 0, 0);
const int red_offset = rand() % 4;
for (int x = 0; x < ret->w; x++)
for (int x = 0; x < src->w; x++)
{
for (int y = 0; y < ret->h; y++)
for (int y = 0; y < src->h; y++)
{
const int sampley = (y + (int) graphics.lerp(oldscrollamount, scrollamount)) % 240;
@ -389,137 +222,14 @@ SDL_Surface* ApplyFilter(SDL_Surface* src)
blue = SDL_max(blue - (distX + distY), 0);
const SDL_Color color = {red, green, blue, pixel.a};
DrawPixel(ret, x, y, color);
DrawPixel(dest, x, y, color);
}
}
return ret;
}
void FillRect( SDL_Surface* _surface, const int _x, const int _y, const int _w, const int _h, const int r, int g, int b )
{
SDL_Rect rect = {_x, _y, _w, _h};
Uint32 color = SDL_MapRGB(_surface->format, r, g, b);
SDL_FillRect(_surface, &rect, color);
}
void FillRect( SDL_Surface* _surface, const int r, int g, int b )
{
Uint32 color = SDL_MapRGB(_surface->format, r, g, b);
SDL_FillRect(_surface, NULL, color);
}
void FillRect( SDL_Surface* _surface, SDL_Rect& _rect, const int r, int g, int b )
{
Uint32 color = SDL_MapRGB(_surface->format, r, g, b);
SDL_FillRect(_surface, &_rect, color);
}
void FillRect(SDL_Surface* surface, const SDL_Rect rect, const SDL_Color color)
{
const Uint32 mapped = SDL_MapRGBA(surface->format, color.r, color.g, color.b, color.a);
SDL_FillRect(surface, &rect, mapped);
}
void FillRect(SDL_Surface* surface, const SDL_Color color)
{
const Uint32 mapped = SDL_MapRGBA(surface->format, color.r, color.g, color.b, color.a);
SDL_FillRect(surface, NULL, mapped);
}
void FillRect(SDL_Surface* surface, const int x, const int y, const int w, const int h, const SDL_Color color)
{
const SDL_Rect rect = {x, y, w, h};
const Uint32 mapped = SDL_MapRGBA(surface->format, color.r, color.g, color.b, color.a);
SDL_FillRect(surface, &rect, mapped);
}
void FillRect(SDL_Surface* surface, const int r, const int g, const int b, const int a)
{
const Uint32 mapped = SDL_MapRGBA(surface->format, r, g, b, a);
SDL_FillRect(surface, NULL, mapped);
}
void ClearSurface(SDL_Surface* surface)
{
SDL_FillRect(surface, NULL, 0x00000000);
}
void ScrollSurface( SDL_Surface* _src, int _pX, int _pY )
{
SDL_Surface* part1 = NULL;
SDL_Rect rect1;
SDL_Rect rect2;
//scrolling up;
if(_pY < 0)
{
setRect(rect2, 0, 0, _src->w, _src->h - _pY);
part1 = GetSubSurface(_src, rect2.x, rect2.y, rect2.w, rect2.h);
SDL_Rect destrect1;
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
setRect(destrect1, 0, _pY, _pX, _src->h);
SDL_BlitSurface (part1, NULL, _src, &destrect1);
}
else if(_pY > 0)
{
setRect(rect1, 0, 0, _src->w, _src->h - _pY);
part1 = GetSubSurface(_src, rect1.x, rect1.y, rect1.w, rect1.h);
SDL_Rect destrect1;
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
setRect(destrect1, _pX, _pY, _src->w, _src->h - _pY);
SDL_BlitSurface (part1, NULL, _src, &destrect1);
}
//Right
else if(_pX <= 0)
{
setRect(rect2, 0, 0, _src->w - _pX, _src->h );
part1 = GetSubSurface(_src, rect2.x, rect2.y, rect2.w, rect2.h);
SDL_Rect destrect1;
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
setRect(destrect1, _pX, 0, _src->w - _pX, _src->h);
SDL_BlitSurface (part1, NULL, _src, &destrect1);
}
else if(_pX > 0)
{
setRect(rect1, _pX, 0, _src->w - _pX, _src->h );
part1 = GetSubSurface(_src, rect1.x, rect1.y, rect1.w, rect1.h);
SDL_Rect destrect1;
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
setRect(destrect1, 0, 0, _src->w - _pX, _src->h);
SDL_BlitSurface (part1, NULL, _src, &destrect1);
}
//Cleanup temp surface
if (part1)
{
VVV_freefunc(SDL_FreeSurface, part1);
}
SDL_FreeFormat(format);
SDL_UpdateTexture(graphics.gameTexture, NULL, dest->pixels, dest->pitch);
SDL_FreeSurface(src);
SDL_FreeSurface(dest);
}

View File

@ -7,36 +7,11 @@ void setRect(SDL_Rect& _r, int x, int y, int w, int h);
SDL_Surface* GetSubSurface( SDL_Surface* metaSurface, int x, int y, int width, int height );
void DrawPixel(SDL_Surface* surface, int x, int y, SDL_Color color);
SDL_Color ReadPixel(const SDL_Surface* surface, int x, int y);
SDL_Surface * ScaleSurface( SDL_Surface *Surface, int Width, int Height, SDL_Surface * Dest = NULL );
void BlitSurfaceStandard( SDL_Surface* _src, SDL_Rect* _srcRect, SDL_Surface* _dest, SDL_Rect* _destRect );
void BlitSurfaceColoured(SDL_Surface* src, const SDL_Rect* src_rect, SDL_Surface* dest, SDL_Rect* dest_rect, SDL_Color color);
void BlitSurfaceTinted(SDL_Surface* src, const SDL_Rect* src_rect, SDL_Surface* dest, SDL_Rect* dest_rect, SDL_Color color);
void FillRect( SDL_Surface* surface, const int x, const int y, const int w, const int h, const int r, int g, int b );
void FillRect( SDL_Surface* surface, const int r, int g, int b );
void FillRect( SDL_Surface* surface, SDL_Rect& rect, const int r, int g, int b );
void FillRect(SDL_Surface* surface, SDL_Rect rect, SDL_Color color);
void FillRect(SDL_Surface* surface, SDL_Color color);
void FillRect(SDL_Surface* surface, int x, int y, int w, int h, SDL_Color color);
void FillRect(SDL_Surface* surface, int r, int g, int b, int a);
void ClearSurface(SDL_Surface* surface);
void ScrollSurface(SDL_Surface* _src, int pX, int py);
SDL_Surface * FlipSurfaceVerticle(SDL_Surface* _src);
void UpdateFilter(void);
SDL_Surface* ApplyFilter( SDL_Surface* _src );
void ApplyFilter(void);
#endif /* GRAPHICSUTIL_H */

View File

@ -3072,9 +3072,6 @@ static void mapmenuactionpress(const bool version2_2)
case 11:
//quit to menu
//Kill contents of offset render buffer, since we do that for some reason.
//This fixes an apparent frame flicker.
ClearSurface(graphics.menuoffbuffer);
graphics.fademode = FADE_START_FADEOUT;
music.fadeout();
map.nexttowercolour();

View File

@ -361,6 +361,7 @@ void KeyPoll::Poll(void)
}
}
SDL_DisableScreenSaver();
gameScreen.recacheTextures();
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
if (!game.disablepause)

View File

@ -1406,15 +1406,18 @@ void gamelogic(void)
if (map.finalmode && map.final_colormode)
{
map.final_aniframedelay--;
if(map.final_aniframedelay==0)
if (map.final_aniframedelay == 0)
{
graphics.foregrounddrawn=false;
graphics.foregrounddrawn = false;
}
if (map.final_aniframedelay <= 0) {
if (map.final_aniframedelay <= 0)
{
map.final_aniframedelay = 2;
map.final_aniframe++;
if (map.final_aniframe >= 4)
{
map.final_aniframe = 0;
}
}
}

View File

@ -1085,7 +1085,7 @@ void mapclass::gotoroom(int rx, int ry)
//Do we need to reload the background?
bool redrawbg = game.roomx != game.prevroomx || game.roomy != game.prevroomy;
if(redrawbg)
if (redrawbg)
{
graphics.backgrounddrawn = false; //Used for background caching speedup
}

View File

@ -147,12 +147,12 @@ static void menurender(void)
case Menu::mainmenu:
{
const int temp = 50;
graphics.drawsprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
#if defined(MAKEANDPLAY)
const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION");
graphics.Print(264-graphics.len(editionlabel),temp+35,editionlabel,tr, tg, tb);
@ -435,16 +435,16 @@ static void menurender(void)
graphics.Print( -1, 50, loc::gettext("VVVVVV is a game by"), tr, tg, tb, true);
graphics.bigprint( 40, 65, "Terry Cavanagh", tr, tg, tb, true, 2);
graphics.drawimagecol(7, -1, 86, graphics.getRGB(tr, tg, tb), true);
graphics.drawimagecol(IMAGE_SITE, -1, 86, graphics.getRGB(tr, tg, tb), true);
graphics.Print( -1, 120, loc::gettext("and features music by"), tr, tg, tb, true);
graphics.bigprint( 40, 135, "Magnus Pålsson", tr, tg, tb, true, 2);
graphics.drawimagecol(8, -1, 156, graphics.getRGB(tr, tg, tb), true);
graphics.drawimagecol(IMAGE_SITE2, -1, 156, graphics.getRGB(tr, tg, tb), true);
break;
case Menu::credits2:
graphics.Print( -1, 50, loc::gettext("Roomnames are by"), tr, tg, tb, true);
graphics.bigprint( 40, 65, "Bennett Foddy", tr, tg, tb, true);
graphics.drawimagecol(9, -1, 86, graphics.getRGB(tr, tg, tb), true);
graphics.drawimagecol(IMAGE_SITE3, -1, 86, graphics.getRGB(tr, tg, tb), true);
graphics.Print( -1, 110, loc::gettext("C++ version by"), tr, tg, tb, true);
graphics.bigprint( 40, 125, "Simon Roth", tr, tg, tb, true);
graphics.bigprint( 40, 145, "Ethan Lee", tr, tg, tb, true);
@ -713,7 +713,7 @@ static void menurender(void)
int box_x = SDL_min(10, (320-overflow.max_w_px)/2);
int box_h = overflow.max_h_px - SDL_max(0, 10-loc::get_langmeta()->font_h);
FillRect(graphics.backBuffer, box_x-1, 30-1, overflow.max_w_px+2, box_h+2, tr/3, tg/3, tb/3);
graphics.fill_rect(box_x-1, 30-1, overflow.max_w_px+2, box_h+2, tr/3, tg/3, tb/3);
int wraplimit;
if (overflow.multiline)
@ -1029,7 +1029,7 @@ static void menurender(void)
graphics.bigprint(-1, 30, loc::gettext("Text Outline"), tr, tg, tb, true);
int next_y = graphics.PrintWrap(-1, 65, loc::gettext("Disables outline on game text."), tr, tg, tb, true);
FillRect(graphics.backBuffer, 0, next_y-4, 320, 16, tr, tg, tb);
graphics.fill_rect(0, next_y-4, 320, 16, tr, tg, tb);
if (!graphics.notextoutline)
{
@ -1142,8 +1142,8 @@ static void menurender(void)
);
graphics.Print(262-graphics.len(buffer), 132-20, buffer, 255 - (help.glow / 2), 255 - (help.glow / 2), 255 - (help.glow / 2));
graphics.drawsprite(34, 126-20, 50, graphics.col_clock);
graphics.drawsprite(270, 126-20, 22, graphics.col_trinket);
graphics.draw_sprite(34, 126-20, 50, graphics.col_clock);
graphics.draw_sprite(270, 126-20, 22, graphics.col_trinket);
break;
}
case 1:
@ -1166,8 +1166,8 @@ static void menurender(void)
);
graphics.Print(262-graphics.len(buffer), 132-20, buffer, 255 - (help.glow / 2), 255 - (help.glow / 2), 255 - (help.glow / 2));
graphics.drawsprite(34, 126-20, 50, graphics.col_clock);
graphics.drawsprite(270, 126-20, 22, graphics.col_trinket);
graphics.draw_sprite(34, 126-20, 50, graphics.col_clock);
graphics.draw_sprite(270, 126-20, 22, graphics.col_trinket);
break;
}
}
@ -1597,9 +1597,7 @@ static void menurender(void)
void titlerender(void)
{
ClearSurface(graphics.backBuffer);
graphics.clear();
if (!game.menustart)
{
tr = graphics.col_tr;
@ -1607,12 +1605,12 @@ void titlerender(void)
tb = graphics.col_tb;
int temp = 50;
graphics.drawsprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
#if defined(MAKEANDPLAY)
const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION");
graphics.Print(264-graphics.len(editionlabel),temp+35,editionlabel,tr, tg, tb);
@ -1650,7 +1648,7 @@ void titlerender(void)
void gamecompleterender(void)
{
ClearSurface(graphics.backBuffer);
graphics.clear();
if(!game.colourblindmode) graphics.drawtowerbackground(graphics.titlebg);
@ -1665,12 +1663,12 @@ void gamecompleterender(void)
if (graphics.onscreen(220 + position))
{
int temp = 220 + position;
graphics.drawsprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
}
if (graphics.onscreen(290 + position)) graphics.bigprint( -1, 290 + position, loc::gettext("Starring"), tr, tg, tb, true, 2);
@ -1802,9 +1800,9 @@ void gamecompleterender(void)
void gamecompleterender2(void)
{
ClearSurface(graphics.backBuffer);
graphics.clear();
graphics.drawimage(10, 0, 0);
graphics.drawimage(IMAGE_ENDING, 0, 0);
for (int j = 0; j < 30; j++)
{
@ -1814,18 +1812,18 @@ void gamecompleterender2(void)
{
if (i > game.creditposx)
{
FillRect(graphics.backBuffer, i * 8, j * 8, 8, 8, 0, 0, 0);
graphics.fill_rect(i * 8, j * 8, 8, 8, 0, 0, 0);
}
}
if (j > game.creditposy)
{
FillRect(graphics.backBuffer, i * 8, j * 8, 8, 8, 0, 0, 0);
graphics.fill_rect(i * 8, j * 8, 8, 8, 0, 0, 0);
}
}
}
FillRect(graphics.backBuffer, graphics.lerp(game.oldcreditposx * 8, game.creditposx * 8) + 8, game.creditposy * 8, 8, 8, 0, 0, 0);
graphics.fill_rect(graphics.lerp(game.oldcreditposx * 8, game.creditposx * 8) + 8, game.creditposy * 8, 8, 8, 0, 0, 0);
graphics.drawfade();
@ -1855,12 +1853,11 @@ static const char* interact_prompt(
void gamerender(void)
{
graphics.set_render_target(graphics.gameplayTexture);
graphics.set_color(0, 0, 0, 255);
if(!game.blackout)
{
if (map.towermode)
{
if (!game.colourblindmode)
@ -1869,7 +1866,7 @@ void gamerender(void)
}
else
{
ClearSurface(graphics.backBuffer);
graphics.clear();
}
graphics.drawtowermap();
}
@ -1881,7 +1878,7 @@ void gamerender(void)
}
else
{
ClearSurface(graphics.backBuffer);
graphics.clear();
}
if ((map.finalmode || map.custommode) && map.final_colormode)
{
@ -1962,7 +1959,10 @@ void gamerender(void)
graphics.cutscenebars();
graphics.drawfade();
BlitSurfaceStandard(graphics.backBuffer, NULL, graphics.menuoffbuffer, NULL);
graphics.set_render_target(graphics.gameTexture);
graphics.copy_texture(graphics.gameplayTexture, NULL, NULL);
graphics.drawgui();
if (graphics.flipmode)
@ -2280,13 +2280,13 @@ static void rendermap(void)
if (map.custommode && map.customshowmm)
{
graphics.drawpixeltextbox(35 + map.custommmxoff, 16 + map.custommmyoff, map.custommmxsize + 10, map.custommmysize + 10, 65, 185, 207);
graphics.drawpartimage(graphics.minimap_mounted ? 1 : 12, 40 + map.custommmxoff, 21 + map.custommmyoff, map.custommmxsize, map.custommmysize);
graphics.drawpartimage(graphics.minimap_mounted ? IMAGE_MINIMAP : IMAGE_CUSTOMMINIMAP, 40 + map.custommmxoff, 21 + map.custommmyoff, map.custommmxsize, map.custommmysize);
return;
}
#endif /* NO_CUSTOM_LEVELS */
graphics.drawpixeltextbox(35, 16, 250, 190, 65, 185, 207);
graphics.drawimage(1, 40, 21, false);
graphics.drawimage(IMAGE_MINIMAP, 40, 21, false);
}
static void rendermapfog(void)
@ -2304,7 +2304,7 @@ static void rendermapfog(void)
{
for (int y = 0; y < data.zoom; y++)
{
graphics.drawimage(2, data.xoff + 40 + (x * 12) + (i * (12 * data.zoom)), data.yoff + 21 + (y * 9) + (j * (9 * data.zoom)), false);
graphics.drawimage(IMAGE_COVERED, data.xoff + 40 + (x * 12) + (i * (12 * data.zoom)), data.yoff + 21 + (y * 9) + (j * (9 * data.zoom)), false);
}
}
}
@ -2383,12 +2383,13 @@ static void rendermapcursor(const bool flashing)
void maprender(void)
{
ClearSurface(graphics.backBuffer);
graphics.set_render_target(graphics.menuTexture);
graphics.clear();
draw_roomname_menu();
//Background color
FillRect(graphics.backBuffer,0, 12, 320, 240, 10, 24, 26 );
graphics.fill_rect(0, 12, 320, 240, 10, 24, 26 );
//Menubar:
graphics.drawtextbox( -10, 212, 43, 3, 65, 185, 207);
@ -2458,7 +2459,7 @@ void maprender(void)
{
for (int i = 0; i < 20; i++)
{
graphics.drawimage(2, 40 + (i * 12), 21 + (j * 9), false);
graphics.drawimage(IMAGE_COVERED, 40 + (i * 12), 21 + (j * 9), false);
}
}
graphics.bprint(-1, 105, loc::gettext("NO SIGNAL"), 245, 245, 245, true);
@ -2746,8 +2747,8 @@ void maprender(void)
);
graphics.Print(262 - graphics.len(buffer), FLIP(132, 8), buffer, 255 - help.glow/2, 255 - help.glow/2, 255 - help.glow/2);
graphics.drawsprite(34, FLIP(126, 17), 50, graphics.col_clock);
graphics.drawsprite(270, FLIP(126, 17), 22, graphics.col_trinket);
graphics.draw_sprite(34, FLIP(126, 17), 50, graphics.col_clock);
graphics.draw_sprite(270, FLIP(126, 17), 22, graphics.col_trinket);
break;
}
case 10:
@ -2851,19 +2852,7 @@ void maprender(void)
}
// We need to draw the black screen above the menu in order to disguise it
// being jankily brought down in glitchrunner mode when exiting to the title
// Otherwise, there's no reason to obscure the menu
if (GlitchrunnerMode_less_than_or_equal(Glitchrunner2_2)
|| FADEMODE_IS_FADING(graphics.fademode)
|| game.fadetomenu
|| game.fadetolab)
{
graphics.drawfade();
}
graphics.set_render_target(graphics.gameTexture);
if (graphics.resumegamemode || graphics.menuoffset > 0 || graphics.oldmenuoffset > 0)
{
@ -2871,22 +2860,38 @@ void maprender(void)
}
else
{
graphics.renderwithscreeneffects();
graphics.copy_texture(graphics.menuTexture, NULL, NULL);
}
// We need to draw the black screen above the menu in order to disguise it
// being jankily brought down in glitchrunner mode when exiting to the title
// Otherwise, there's no reason to obscure the menu
if (GlitchrunnerMode_less_than_or_equal(Glitchrunner2_2)
|| FADEMODE_IS_FADING(graphics.fademode)
|| game.fadetomenu
|| game.fadetolab)
{
graphics.drawfade();
}
graphics.renderwithscreeneffects();
}
#undef FLIP
void teleporterrender(void)
{
ClearSurface(graphics.backBuffer);
graphics.set_render_target(graphics.menuTexture);
graphics.clear();
const int telex = map.teleporters[game.teleport_to_teleporter].x;
const int teley = map.teleporters[game.teleport_to_teleporter].y;
draw_roomname_menu();
//Background color
FillRect(graphics.backBuffer, 0, 12, 320, 240, 10, 24, 26);
graphics.fill_rect(0, 12, 320, 240, 10, 24, 26);
rendermap();
rendermapfog();
@ -2944,6 +2949,7 @@ void teleporterrender(void)
if (game.advancetext) graphics.bprint(5, 5, loc::gettext("- Press ACTION to advance text -"), 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), true);
}
graphics.set_render_target(graphics.gameTexture);
if (graphics.resumegamemode || graphics.menuoffset > 0 || graphics.oldmenuoffset > 0)
{
@ -2951,6 +2957,8 @@ void teleporterrender(void)
}
else
{
graphics.render();
graphics.copy_texture(graphics.menuTexture, NULL, NULL);
}
graphics.render();
}

View File

@ -3,6 +3,7 @@
#include "Constants.h"
#include "Game.h"
#include "Graphics.h"
#include "GraphicsUtil.h"
#include "KeyPoll.h"
#include "Localization.h"
#include "LocalizationMaint.h"
@ -54,7 +55,9 @@ namespace roomname_translator
fullscreen_rect.y = 0;
fullscreen_rect.w = 320;
fullscreen_rect.h = 240;
SDL_BlitSurface(dimbuffer, NULL, graphics.backBuffer, &fullscreen_rect);
graphics.set_blendmode(SDL_BLENDMODE_BLEND);
graphics.fill_rect(0, 0, 0, 96);
graphics.set_blendmode(SDL_BLENDMODE_NONE);
if (help_screen)
{
graphics.bprint(0, 0, "=== Room name translation mode help ===", 255,255,255);

View File

@ -7,8 +7,10 @@
#include "Constants.h"
#include "FileSystemUtils.h"
#include "Game.h"
#include "Graphics.h"
#include "GraphicsUtil.h"
#include "InterimVersion.h"
#include "Render.h"
#include "Vlogging.h"
void ScreenSettings_default(struct ScreenSettings* _this)
@ -26,8 +28,6 @@ void Screen::init(const struct ScreenSettings* settings)
{
m_window = NULL;
m_renderer = NULL;
m_screenTexture = NULL;
m_screen = NULL;
isWindowed = !settings->fullscreen;
scalingMode = settings->scalingMode;
isFiltered = settings->linearFilter;
@ -46,13 +46,18 @@ void Screen::init(const struct ScreenSettings* settings)
// Uncomment this next line when you need to debug -flibit
// SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "software", SDL_HINT_OVERRIDE);
SDL_CreateWindowAndRenderer(
m_window = SDL_CreateWindow(
"VVVVVV",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH_PIXELS * 2,
SCREEN_HEIGHT_PIXELS * 2,
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI,
&m_window,
&m_renderer
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI
);
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
#ifdef INTERIM_VERSION_EXISTS
/* Branch name limits are ill-defined but on GitHub it's ~256 chars
* ( https://stackoverflow.com/a/24014513/ ).
@ -66,25 +71,6 @@ void Screen::init(const struct ScreenSettings* settings)
LoadIcon();
// FIXME: This surface should be the actual backbuffer! -flibit
m_screen = SDL_CreateRGBSurface(
0,
SCREEN_WIDTH_PIXELS,
SCREEN_HEIGHT_PIXELS,
32,
0x00FF0000,
0x0000FF00,
0x000000FF,
0xFF000000
);
m_screenTexture = SDL_CreateTexture(
m_renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
SCREEN_WIDTH_PIXELS,
SCREEN_HEIGHT_PIXELS
);
badSignalEffect = settings->badSignal;
ResizeScreen(settings->windowWidth, settings->windowHeight);
@ -93,8 +79,6 @@ void Screen::init(const struct ScreenSettings* settings)
void Screen::destroy(void)
{
/* Order matters! */
VVV_freefunc(SDL_DestroyTexture, m_screenTexture);
VVV_freefunc(SDL_FreeSurface, m_screen);
VVV_freefunc(SDL_DestroyRenderer, m_renderer);
VVV_freefunc(SDL_DestroyWindow, m_window);
}
@ -121,11 +105,11 @@ void Screen::LoadIcon(void)
}
#else
SDL_Surface* LoadImage(const char* filename);
SDL_Surface* LoadImageSurface(const char* filename);
void Screen::LoadIcon(void)
{
SDL_Surface* icon = LoadImage("VVVVVV.png");
SDL_Surface* icon = LoadImageSurface("VVVVVV.png");
if (icon == NULL)
{
return;
@ -149,6 +133,7 @@ void Screen::ResizeScreen(int x, int y)
if (!isWindowed || isForcedFullscreen())
{
int result = SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
recacheTextures();
if (result != 0)
{
vlog_error("Error: could not set the game to fullscreen mode: %s", SDL_GetError());
@ -158,6 +143,7 @@ void Screen::ResizeScreen(int x, int y)
else
{
int result = SDL_SetWindowFullscreen(m_window, 0);
recacheTextures();
if (result != 0)
{
vlog_error("Error: could not set the game to windowed mode: %s", SDL_GetError());
@ -266,66 +252,10 @@ void Screen::GetWindowSize(int* x, int* y)
}
}
void Screen::UpdateScreen(SDL_Surface* buffer, SDL_Rect* rect )
void Screen::RenderPresent()
{
if((buffer == NULL) && (m_screen == NULL) )
{
return;
}
if(badSignalEffect)
{
buffer = ApplyFilter(buffer);
}
ClearSurface(m_screen);
BlitSurfaceStandard(buffer,NULL,m_screen,rect);
if(badSignalEffect)
{
VVV_freefunc(SDL_FreeSurface, buffer);
}
}
const SDL_PixelFormat* Screen::GetFormat(void)
{
return m_screen->format;
}
void Screen::FlipScreen(const bool flipmode)
{
static const SDL_Rect filterSubrect = {1, 1, 318, 238};
SDL_RendererFlip flip_flags;
if (flipmode)
{
flip_flags = SDL_FLIP_VERTICAL;
}
else
{
flip_flags = SDL_FLIP_NONE;
}
SDL_UpdateTexture(
m_screenTexture,
NULL,
m_screen->pixels,
m_screen->pitch
);
SDL_RenderCopyEx(
m_renderer,
m_screenTexture,
isFiltered ? &filterSubrect : NULL,
NULL,
0.0,
NULL,
flip_flags
);
SDL_RenderPresent(m_renderer);
SDL_RenderClear(m_renderer);
ClearSurface(m_screen);
graphics.clear();
}
void Screen::toggleFullScreen(void)
@ -354,20 +284,49 @@ void Screen::toggleLinearFilter(void)
isFiltered ? "linear" : "nearest",
SDL_HINT_OVERRIDE
);
SDL_DestroyTexture(m_screenTexture);
m_screenTexture = SDL_CreateTexture(
SDL_DestroyTexture(graphics.gameTexture);
graphics.gameTexture = SDL_CreateTexture(
m_renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
SDL_TEXTUREACCESS_TARGET,
SCREEN_WIDTH_PIXELS,
SCREEN_HEIGHT_PIXELS
);
if (graphics.gameTexture == NULL)
{
vlog_error("Could not create game texture: %s", SDL_GetError());
return;
}
}
void Screen::toggleVSync(void)
{
vsync = !vsync;
SDL_RenderSetVSync(m_renderer, (int) vsync);
recacheTextures();
}
void Screen::recacheTextures(void)
{
// Fix for d3d9, which clears target textures sometimes (ex. toggling vsync, switching fullscreen, etc...)
// Signal cached textures to be redrawn fully
graphics.backgrounddrawn = false;
graphics.foregrounddrawn = false;
graphics.towerbg.tdrawback = true;
graphics.titlebg.tdrawback = true;
if (game.ingame_titlemode)
{
// Redraw the cached gameplay texture if we're in the in-game menu.
// Additionally, reset alpha so things don't jitter when re-entering gameplay.
float oldAlpha = graphics.alpha;
graphics.alpha = 0;
gamerender();
graphics.alpha = oldAlpha;
}
}
/* FIXME: Launching in forced fullscreen then exiting and relaunching in normal

View File

@ -19,16 +19,15 @@ public:
void ResizeToNearestMultiple(void);
void GetWindowSize(int* x, int* y);
void UpdateScreen(SDL_Surface* buffer, SDL_Rect* rect);
void FlipScreen(bool flipmode);
const SDL_PixelFormat* GetFormat(void);
void RenderPresent();
void toggleFullScreen(void);
void toggleScalingMode(void);
void toggleLinearFilter(void);
void toggleVSync(void);
void recacheTextures(void);
bool isForcedFullscreen(void);
bool isWindowed;
@ -39,8 +38,6 @@ public:
SDL_Window *m_window;
SDL_Renderer *m_renderer;
SDL_Texture *m_screenTexture;
SDL_Surface* m_screen;
};
#ifndef GAMESCREEN_DEFINITION

View File

@ -175,41 +175,54 @@ void scriptclass::run(void)
#if !defined(NO_CUSTOM_LEVELS)
if (words[0] == "warpdir")
{
int temprx=ss_toi(words[1])-1;
int tempry=ss_toi(words[2])-1;
int temprx = ss_toi(words[1]) - 1;
int tempry = ss_toi(words[2]) - 1;
const RoomProperty* room;
cl.setroomwarpdir(temprx, tempry, ss_toi(words[3]));
room = cl.getroomprop(temprx, tempry);
//Do we update our own room?
if(game.roomx-100==temprx && game.roomy-100==tempry){
if (game.roomx - 100 == temprx && game.roomy - 100 == tempry)
{
//If screen warping, then override all that:
graphics.backgrounddrawn = false;
map.warpx=false; map.warpy=false;
if(room->warpdir==0){
map.warpx = false;
map.warpy = false;
if (room->warpdir == 0)
{
map.background = 1;
//Be careful, we could be in a Lab or Warp Zone room...
if(room->tileset==2){
if (room->tileset == 2)
{
//Lab
map.background = 2;
graphics.rcol = room->tilecol;
}else if(room->tileset==3){
}
else if (room->tileset == 3)
{
//Warp Zone
map.background = 6;
}
}else if(room->warpdir==1){
map.warpx=true;
map.background=3;
graphics.rcol = cl.getwarpbackground(temprx,tempry);
}else if(room->warpdir==2){
map.warpy=true;
map.background=4;
graphics.rcol = cl.getwarpbackground(temprx,tempry);
}else if(room->warpdir==3){
map.warpx=true; map.warpy=true;
}
else if (room->warpdir == 1)
{
map.warpx = true;
map.background = 3;
graphics.rcol = cl.getwarpbackground(temprx, tempry);
}
else if (room->warpdir == 2)
{
map.warpy = true;
map.background = 4;
graphics.rcol = cl.getwarpbackground(temprx, tempry);
}
else if (room->warpdir == 3)
{
map.warpx = true;
map.warpy = true;
map.background = 5;
graphics.rcol = cl.getwarpbackground(temprx,tempry);
graphics.rcol = cl.getwarpbackground(temprx, tempry);
}
}
}

View File

@ -5,8 +5,7 @@
struct TowerBG
{
SDL_Surface* buffer;
SDL_Surface* buffer_lerp;
SDL_Texture* texture;
bool tdrawback;
int bypos;
int bscroll;

View File

@ -46,6 +46,15 @@ void VVV_fillstring(
} \
do { } while (false)
#define WHINE_ONCE_ARGS(args) \
static bool whine = true; \
if (whine) \
{ \
whine = false; \
vlog_error args; \
} \
do { } while (false)
/* Don't call this directly; use the VVV_between macro. */
void _VVV_between(
const char* original,

View File

@ -584,34 +584,12 @@ int main(int argc, char *argv[])
vlog_info("\t\t");
vlog_info("\t\t");
//Set up screen
// Load Ini
// Set up screen
graphics.init();
game.init();
game.seed_use_sdl_getticks = seed_use_sdl_getticks;
// This loads music too...
if (!graphics.reloadresources())
{
/* Something wrong with the default assets? We can't use them to
* display the error message, and we have to bail. */
SDL_ShowSimpleMessageBox(
SDL_MESSAGEBOX_ERROR,
graphics.error_title,
graphics.error,
NULL
);
VVV_exit(1);
}
game.gamestate = PRELOADER;
game.menustart = false;
@ -636,11 +614,26 @@ int main(int argc, char *argv[])
gameScreen.init(&screen_settings);
}
// This loads music too...
if (!graphics.reloadresources())
{
/* Something wrong with the default assets? We can't use them to
* display the error message, and we have to bail. */
SDL_ShowSimpleMessageBox(
SDL_MESSAGEBOX_ERROR,
graphics.error_title,
graphics.error,
NULL
);
VVV_exit(1);
}
loc::loadtext(false);
loc::loadlanguagelist();
game.createmenu(Menu::mainmenu);
graphics.create_buffers(gameScreen.GetFormat());
graphics.create_buffers();
if (game.skipfakeload)
game.gamestate = TITLEMODE;
@ -790,9 +783,10 @@ static void cleanup(void)
{
game.savestatsandsettings();
}
gameScreen.destroy();
graphics.grphx.destroy();
graphics.destroy_buffers();
gameScreen.destroy();
graphics.destroy();
music.destroy();
map.destroy();
@ -849,9 +843,13 @@ static void inline deltaloop(void)
if (implfunc->type == Func_delta && implfunc->func != NULL)
{
graphics.clear();
graphics.set_render_target(graphics.gameTexture);
implfunc->func();
gameScreen.FlipScreen(graphics.flipmode);
gameScreen.RenderPresent();
}
}
}
@ -873,7 +871,7 @@ static void unfocused_run(void)
{
if (!game.blackout)
{
ClearSurface(graphics.backBuffer);
graphics.fill_rect(0, 0, 0);
#define FLIP(YPOS) graphics.flipmode ? 232 - YPOS : YPOS
graphics.bprint(5, FLIP(110), loc::gettext("Game paused"), 196 - help.glow, 255 - help.glow, 196 - help.glow, true);
graphics.bprint(5, FLIP(120), loc::gettext("[click to resume]"), 196 - help.glow, 255 - help.glow, 196 - help.glow, true);

View File

@ -95,15 +95,15 @@ void preloaderrender(void)
pre_temprecty = (i * 16)- pre_offset;
if (i % 2 == 0)
{
FillRect(graphics.backBuffer, pre_temprectx, pre_temprecty, pre_temprectw,pre_temprecth, pre_lightcol);
graphics.fill_rect(pre_temprectx, pre_temprecty, pre_temprectw,pre_temprecth, pre_lightcol);
}
else
{
FillRect(graphics.backBuffer, pre_temprectx, pre_temprecty, pre_temprectw,pre_temprecth, pre_darkcol);
graphics.fill_rect(pre_temprectx, pre_temprecty, pre_temprectw,pre_temprecth, pre_darkcol);
}
}
FillRect(graphics.backBuffer, pre_frontrectx, pre_frontrecty, pre_frontrectw,pre_frontrecth, graphics.getRGB(0x3E,0x31,0xA2));
graphics.fill_rect(pre_frontrectx, pre_frontrecty, pre_frontrectw,pre_frontrecth, graphics.getRGB(0x3E,0x31,0xA2));
print_percentage = true;
@ -114,12 +114,12 @@ void preloaderrender(void)
}else if (pre_transition <= -10) {
//Switch to TITLEMODE (handled by preloaderrenderfixed)
}else if (pre_transition < 5) {
ClearSurface(graphics.backBuffer);
graphics.fill_rect(0, 0, 0);
}else if (pre_transition < 20) {
pre_temprecty = 0;
pre_temprecth = 240;
ClearSurface(graphics.backBuffer);
FillRect(graphics.backBuffer, pre_frontrectx, pre_frontrecty, pre_frontrectw,pre_frontrecth, graphics.getRGB(0x3E,0x31,0xA2));
graphics.fill_rect(0, 0, 0);
graphics.fill_rect(pre_frontrectx, pre_frontrecty, pre_frontrectw,pre_frontrecth, graphics.getRGB(0x3E,0x31,0xA2));
print_percentage = true;
}