1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 01:59:43 +01:00

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.) (Ordered alphabetically by first name.)
* Alexandra Fox
* AlexApps99 (@AlexApps99) * AlexApps99 (@AlexApps99)
* Allison Fleischer (AllisonFleischer) * Allison Fleischer (AllisonFleischer)
* AllyTally (@AllyTally)
* Brian Callahan (@ibara) * Brian Callahan (@ibara)
* Charlie Bruce (@charliebruce) * Charlie Bruce (@charliebruce)
* Christoph Böhmwalder (@chrboe) * 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 /* CONTRIBUTORS.txt, again listed alphabetically (according to `sort`) by first name
* Misa is special; she gets to be listed in C++ credits alongside Ethan */ * Misa is special; she gets to be listed in C++ credits alongside Ethan */
static const char* githubfriends[] = { static const char* githubfriends[] = {
"Alexandra Fox",
"AlexApps99", "AlexApps99",
"Allison Fleischer", "Allison Fleischer",
"AllyTally",
"Brian Callahan", "Brian Callahan",
"Charlie Bruce", "Charlie Bruce",
"Christoph Böhmwalder", "Christoph Böhmwalder",

View file

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

View file

@ -22,6 +22,7 @@
#include "Script.h" #include "Script.h"
#include "UtilityClass.h" #include "UtilityClass.h"
#include "VFormat.h" #include "VFormat.h"
#include "Vlogging.h"
editorclass::editorclass(void) 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) 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); graphics.set_color(color);
FillRect(graphics.backBuffer, x, y2-1, x2-x, 1, color);
FillRect(graphics.backBuffer, x, y, 1, y2-y, color); const SDL_Rect rect = {x, y, x2 - x, y2 - y};
FillRect(graphics.backBuffer, x2-1, y, 1, y2-y, color);
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) 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); graphics.set_color(color);
FillRect(graphics.backBuffer, x, y+y2-1, x2, 1, color);
FillRect(graphics.backBuffer, x, y, 1, y2, color); const SDL_Rect rect = {x, y, x2, y2};
FillRect(graphics.backBuffer, x+x2-1, y, 1, y2, color);
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); const RoomProperty* const room = cl.getroomprop(ed.levx, ed.levy);
//Draw grid //Draw grid
graphics.clear();
ClearSurface(graphics.backBuffer);
for(int j=0; j<30; j++) for(int j=0; j<30; j++)
{ {
for(int i=0; i<40; i++) for(int i=0; i<40; i++)
@ -566,12 +577,12 @@ void editorrender(void)
//left edge //left edge
if(ed.freewrap((ed.levx*40)-1,j+(ed.levy*30))==1) 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 //right edge
if(ed.freewrap((ed.levx*40)+40,j+(ed.levy*30))==1) 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) 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) 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 // Special case for drawing gray entities
bool custom_gray = room->tileset == 3 && room->tilecol == 6; 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 // Draw entities backward to remain accurate with ingame
for (int i = customentities.size() - 1; i >= 0; i--) for (int i = customentities.size() - 1; i >= 0; i--)
@ -613,7 +623,7 @@ void editorrender(void)
{ {
ed.entcolreal = graphics.getcol(18); 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==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==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); 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)); 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; break;
case 2: //Threadmills & platforms case 2: //Threadmills & platforms
if (!INBOUNDS_VEC(obj.customplatformtile, graphics.entcolours))
{
continue;
}
tpoint.x = (customentities[i].x*8)- (ed.levx*40*8); tpoint.x = (customentities[i].x*8)- (ed.levx*40*8);
tpoint.y = (customentities[i].y*8)- (ed.levy*30*8); tpoint.y = (customentities[i].y*8)- (ed.levy*30*8);
drawRect = graphics.tiles_rect; drawRect = graphics.tiles_rect;
drawRect.x += tpoint.x; drawRect.x += tpoint.x;
drawRect.y += tpoint.y; drawRect.y += tpoint.y;
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
if (custom_gray) BlitSurfaceTinted(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect, gray_ct); graphics.draw_grid_tile(custom_gray ? graphics.grphx.im_entcolours_tint : graphics.grphx.im_entcolours, obj.customplatformtile, drawRect.x, drawRect.y, 8, 8);
else BlitSurfaceStandard(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect);
drawRect.x += 8; drawRect.x += 8;
} }
@ -664,8 +669,7 @@ void editorrender(void)
drawRect.x += tpoint.x; drawRect.x += tpoint.x;
drawRect.y += tpoint.y; drawRect.y += tpoint.y;
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
if (custom_gray) BlitSurfaceTinted(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect, gray_ct); graphics.draw_grid_tile(custom_gray ? graphics.grphx.im_entcolours_tint : graphics.grphx.im_entcolours, obj.customplatformtile, drawRect.x, drawRect.y, 8, 8);
else BlitSurfaceStandard(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect);
drawRect.x += 8; drawRect.x += 8;
} }
} }
@ -682,18 +686,13 @@ void editorrender(void)
} }
break; break;
case 3: //Disappearing Platform case 3: //Disappearing Platform
if (!INBOUNDS_VEC(obj.customplatformtile, graphics.entcolours))
{
continue;
}
tpoint.x = (customentities[i].x*8)- (ed.levx*40*8); tpoint.x = (customentities[i].x*8)- (ed.levx*40*8);
tpoint.y = (customentities[i].y*8)- (ed.levy*30*8); tpoint.y = (customentities[i].y*8)- (ed.levy*30*8);
drawRect = graphics.tiles_rect; drawRect = graphics.tiles_rect;
drawRect.x += tpoint.x; drawRect.x += tpoint.x;
drawRect.y += tpoint.y; drawRect.y += tpoint.y;
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
if (custom_gray) BlitSurfaceTinted(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect, gray_ct); graphics.draw_grid_tile(custom_gray ? graphics.grphx.im_entcolours_tint : graphics.grphx.im_entcolours, obj.customplatformtile, drawRect.x, drawRect.y, 8, 8);
else BlitSurfaceStandard(graphics.entcolours[obj.customplatformtile],NULL, graphics.backBuffer, &drawRect);
drawRect.x += 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)); 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; break;
case 9: //Shiny Trinket 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)); 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; break;
case 10: //Checkpoints 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)); 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; break;
case 11: //Gravity lines case 11: //Gravity lines
@ -714,7 +713,7 @@ void editorrender(void)
int tx = customentities[i].p2; int tx = customentities[i].p2;
int tx2 = tx + customentities[i].p3/8; int tx2 = tx + customentities[i].p3/8;
int ty = customentities[i].y % 30; 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)); 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 else //Vertical
@ -722,12 +721,12 @@ void editorrender(void)
int tx = customentities[i].x % 40; int tx = customentities[i].x % 40;
int ty = customentities[i].p2; int ty = customentities[i].p2;
int ty2 = ty + customentities[i].p3/8; 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)); 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; break;
case 13://Warp tokens 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)); 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) if (i == edent_under_cursor)
{ {
@ -740,18 +739,18 @@ void editorrender(void)
} }
break; break;
case 15: //Crewmates 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)); 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; break;
case 16: //Start case 16: //Start
{ {
if(customentities[i].p1==0) //Left 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) 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)); 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; short labelcol = ed.entframe<2 ? 255 : 196;
@ -790,7 +789,7 @@ void editorrender(void)
usethistile = 0; // Flipped; usethistile = 0; // Flipped;
usethisy -= 8; 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)); 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) 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) 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)); 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) 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!) //Draw ghosts (spooky!)
if (game.ghostsenabled) { 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++) { 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 (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 if (ed.ghosts[i].rx != ed.levx || ed.ghosts[i].ry != ed.levy)
|| !INBOUNDS_VEC(ed.ghosts[i].frame, graphics.sprites))
continue; continue;
point tpoint; point tpoint;
tpoint.x = ed.ghosts[i].x; tpoint.x = ed.ghosts[i].x;
@ -937,10 +937,12 @@ void editorrender(void)
SDL_Rect drawRect = graphics.sprites_rect; SDL_Rect drawRect = graphics.sprites_rect;
drawRect.x += tpoint.x; drawRect.x += tpoint.x;
drawRect.y += tpoint.y; 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 //Draw Cursor
@ -1026,11 +1028,19 @@ void editorrender(void)
//Draw five lines of the editor //Draw five lines of the editor
const int temp = ed.dmtile - (ed.dmtile % 40) - 80; const int temp = ed.dmtile - (ed.dmtile % 40) - 80;
FillRect(graphics.backBuffer, 0,-t2,320,40, graphics.getRGB(0,0,0)); graphics.fill_rect(0,-t2,320,40, graphics.getRGB(0,0,0));
FillRect(graphics.backBuffer, 0,-t2+40,320,2, graphics.getRGB(255,255,255)); graphics.fill_rect(0,-t2+40,320,2, graphics.getRGB(255,255,255));
int texturewidth;
int textureheight;
if (room->tileset == 0) 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++) for(int i=0; i<40; i++)
{ {
@ -1043,7 +1053,11 @@ void editorrender(void)
} }
else 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++) for(int i=0; i<40; i++)
{ {
@ -1064,8 +1078,8 @@ void editorrender(void)
short labellen = 2 + graphics.len(loc::gettext("Tile:")); short labellen = 2 + graphics.len(loc::gettext("Tile:"));
graphics.bprint(2, 45-t2, loc::gettext("Tile:"), 196, 196, 255 - help.glow, false); 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); 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)); graphics.fill_rect(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+3,45-t2,8,8, graphics.getRGB(0,0,0));
if(room->tileset==0) if(room->tileset==0)
{ {
@ -1081,8 +1095,8 @@ void editorrender(void)
short labellen = 2 + graphics.len(loc::gettext("Tile:")); short labellen = 2 + graphics.len(loc::gettext("Tile:"));
graphics.bprint(2, 12, loc::gettext("Tile:"), 196, 196, 255 - help.glow, false); 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); 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)); graphics.fill_rect(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+3,12,8,8, graphics.getRGB(0,0,0));
if(room->tileset==0) if(room->tileset==0)
{ {
@ -1143,16 +1157,16 @@ void editorrender(void)
message = graphics.string_wordwrap(message, 312, &lines); message = graphics.string_wordwrap(message, 312, &lines);
short textheight = 8*lines; short textheight = 8*lines;
FillRect(graphics.backBuffer, 0,238-textheight,320,240, graphics.getRGB(32,32,32)); graphics.fill_rect(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,239-textheight,320,240, graphics.getRGB(0,0,0));
graphics.PrintWrap(4, 240-textheight, message, 255,255,255, false, 8, 312); graphics.PrintWrap(4, 240-textheight, message, 255,255,255, false, 8, 312);
} }
else if(ed.scripteditmod) else if(ed.scripteditmod)
{ {
//Elaborate C64 BASIC menu goes here! //Elaborate C64 BASIC menu goes here!
FillRect(graphics.backBuffer, 0,0,320,240, graphics.getRGB(123, 111, 218)); graphics.fill_rect(0,0,320,240, graphics.getRGB(123, 111, 218));
FillRect(graphics.backBuffer, 14,16,292,208, graphics.getRGB(61, 48, 162)); graphics.fill_rect(14,16,292,208, graphics.getRGB(61, 48, 162));
switch(ed.scripthelppage) switch(ed.scripthelppage)
{ {
case 0: case 0:
@ -1189,7 +1203,7 @@ void editorrender(void)
case 1: case 1:
{ {
//Current scriptname //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]; char namebuffer[SCREEN_WIDTH_CHARS + 1];
vformat_buf( vformat_buf(
namebuffer, sizeof(namebuffer), namebuffer, sizeof(namebuffer),
@ -1223,7 +1237,7 @@ void editorrender(void)
} }
else else
{ {
ClearSurface(graphics.backBuffer); graphics.clear();
} }
int tr = graphics.titlebg.r - (help.glow / 4) - int(fRandom() * 4); 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); std::string wrapped = graphics.string_wordwrap(ed.textdesc, 312, &lines);
short textheight = 8*lines+8; short textheight = 8*lines+8;
FillRect(graphics.backBuffer, 0, 238-textheight, 320, 240, graphics.getRGB(32, 32, 32)); graphics.fill_rect(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, 239-textheight, 320, 240, graphics.getRGB(0, 0, 0));
graphics.PrintWrap(4, 240-textheight, wrapped, 255, 255, 255, false, 8, 312); graphics.PrintWrap(4, 240-textheight, wrapped, 255, 255, 255, false, 8, 312);
std::string input = key.keybuffer; std::string input = key.keybuffer;
if (ed.entframe < 2) if (ed.entframe < 2)
@ -1262,8 +1276,8 @@ void editorrender(void)
else if(ed.warpmod) else if(ed.warpmod)
{ {
//placing warp token //placing warp token
FillRect(graphics.backBuffer, 0,221,320,240, graphics.getRGB(32,32,32)); graphics.fill_rect(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,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, 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); 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) if(ed.spacemod)
{ {
FillRect(graphics.backBuffer, 0,208,320,240, graphics.getRGB(32,32,32)); graphics.fill_rect(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,209,320,240, graphics.getRGB(0,0,0));
//Draw little icons for each thingy //Draw little icons for each thingy
int tx=6, ty=211, tg=32; int tx=6, ty=211, tg=32;
@ -1281,9 +1295,9 @@ void editorrender(void)
{ {
for(int i=0; i<10; i++) 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: //0:
graphics.drawtile(tx,ty,83); graphics.drawtile(tx,ty,83);
graphics.drawtile(tx+8,ty,83); graphics.drawtile(tx+8,ty,83);
@ -1300,10 +1314,10 @@ void editorrender(void)
graphics.drawtile(tx+4,ty+4,8); graphics.drawtile(tx+4,ty+4,8);
//3: //3:
tx+=tg; tx+=tg;
graphics.drawsprite(tx,ty,22,196,196,196); graphics.draw_sprite(tx,ty,22,196,196,196);
//4: //4:
tx+=tg; tx+=tg;
graphics.drawsprite(tx,ty,21,196,196,196); graphics.draw_sprite(tx,ty,21,196,196,196);
//5: //5:
tx+=tg; tx+=tg;
graphics.drawtile(tx,ty+4,3); graphics.drawtile(tx,ty+4,3);
@ -1318,10 +1332,10 @@ void editorrender(void)
graphics.drawtile(tx+8,ty+4,1); graphics.drawtile(tx+8,ty+4,1);
//8: //8:
tx+=tg; tx+=tg;
graphics.drawsprite(tx,ty,78+ed.entframe,196,196,196); graphics.draw_sprite(tx,ty,78+ed.entframe,196,196,196);
//9: //9:
tx+=tg; 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++) for (int i = 0; i < 10; i++)
{ {
@ -1339,9 +1353,9 @@ void editorrender(void)
{ {
for(int i=0; i<7; i++) 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: //10:
graphics.Print(tx,ty,"A",196, 196, 255 - help.glow, false); graphics.Print(tx,ty,"A",196, 196, 255 - help.glow, false);
graphics.Print(tx+8,ty,"B",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); graphics.Print(tx+8,ty+8,"D",196, 196, 255 - help.glow, false);
//11: //11:
tx+=tg; tx+=tg;
graphics.drawsprite(tx,ty,17,196,196,196); graphics.draw_sprite(tx,ty,17,196,196,196);
//12: //12:
tx+=tg; tx+=tg;
fillboxabs(tx+4,ty+4,8,8,graphics.getRGB(96,96,96)); fillboxabs(tx+4,ty+4,8,8,graphics.getRGB(96,96,96));
//13: //13:
tx+=tg; 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: //14:
tx+=tg; 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: //15:
tx+=tg; tx+=tg;
graphics.drawsprite(tx,ty,186,graphics.col_crewblue); graphics.draw_sprite(tx,ty,186,graphics.col_crewblue);
//16: //16:
tx+=tg; 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++) for (int i = 0; i < 7; i++)
{ {
@ -1446,30 +1460,27 @@ void editorrender(void)
break; break;
} }
int toolnamelen = graphics.len(toolname); int toolnamelen = graphics.len(toolname);
FillRect(graphics.backBuffer, 0,197,toolnamelen+8,11, graphics.getRGB(32,32,32)); graphics.fill_rect(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,198,toolnamelen+7,10, graphics.getRGB(0,0,0));
graphics.bprint(2,199, toolname, 196, 196, 255 - help.glow); graphics.bprint(2,199, toolname, 196, 196, 255 - help.glow);
FillRect(graphics.backBuffer, 260,197,80,11, graphics.getRGB(32,32,32)); graphics.fill_rect(260,197,80,11, graphics.getRGB(32,32,32));
FillRect(graphics.backBuffer, 261,198,80,10, graphics.getRGB(0,0,0)); 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); graphics.bprint(268,199, "("+help.String(ed.levx+1)+","+help.String(ed.levy+1)+")",196, 196, 255 - help.glow, false);
} }
else else
{ {
//FillRect(graphics.backBuffer, 0,230,72,240, graphics.RGB(32,32,32)); //graphics.fill_rect(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,231,71,240, graphics.RGB(0,0,0));
if(room->roomname!="") if(room->roomname!="")
{
if (graphics.translucentroomname)
{ {
graphics.footerrect.y = 230 + ed.roomnamehide; graphics.footerrect.y = 230 + ed.roomnamehide;
SDL_BlitSurface(graphics.footerbuffer, NULL, graphics.backBuffer, &graphics.footerrect);
} graphics.set_blendmode(SDL_BLENDMODE_BLEND);
else graphics.fill_rect(&graphics.footerrect, graphics.getRGBA(0, 0, 0, graphics.translucentroomname ? 127 : 255));
{ graphics.set_blendmode(SDL_BLENDMODE_NONE);
FillRect(graphics.backBuffer, 0,230+ed.roomnamehide,320,10, graphics.getRGB(0,0,0));
}
graphics.bprint(5,231+ed.roomnamehide,room->roomname, 196, 196, 255 - help.glow, true); 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(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); 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)); 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++) for (size_t i = 0; i < SDL_arraysize(shiftmenuoptions); i++)
graphics.Print(4, 120+i*10, shiftmenuoptions[i], 164,164,164,false); graphics.Print(4, 120+i*10, shiftmenuoptions[i], 164,164,164,false);
fillboxabs(220, 207,100,60,graphics.getRGB(64,64,64)); 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, 210, loc::gettext("S: Save Map"),164,164,164,false);
graphics.Print(224, 220, loc::gettext("L: Load 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; short banner_y = 120 - textheight/2 - 5;
float alpha = graphics.lerp(ed.oldnotedelay, ed.notedelay); float alpha = graphics.lerp(ed.oldnotedelay, ed.notedelay);
FillRect(graphics.backBuffer, 0, banner_y, 320, 10+textheight, graphics.getRGB(92,92,92)); graphics.fill_rect(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+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); graphics.PrintWrap(0,banner_y+5, wrapped, 196-((45.0f-alpha)*4), 196-((45.0f-alpha)*4), 196-((45.0f-alpha)*4), true);
} }
@ -1858,7 +1869,6 @@ static void editormenuactionpress(void)
case 4: case 4:
//Load level //Load level
ed.settingsmod = false; ed.settingsmod = false;
graphics.backgrounddrawn=false;
map.nexttowercolour(); map.nexttowercolour();
ed.keydelay = 6; ed.keydelay = 6;
@ -1946,6 +1956,7 @@ static void editormenuactionpress(void)
music.playef(11); music.playef(11);
music.fadeout(); music.fadeout();
graphics.fademode = FADE_START_FADEOUT; graphics.fademode = FADE_START_FADEOUT;
graphics.backgrounddrawn = false;
break; break;
case 2: case 2:
//Go back to editor //Go back to editor
@ -2076,7 +2087,6 @@ void editorinput(void)
{ {
ed.settingsmod = true; ed.settingsmod = true;
} }
graphics.backgrounddrawn=false;
if (ed.settingsmod) if (ed.settingsmod)
{ {
@ -2540,15 +2550,26 @@ void editorinput(void)
else if (key.keymap[SDLK_LCTRL] || key.keymap[SDLK_RCTRL]) else if (key.keymap[SDLK_LCTRL] || key.keymap[SDLK_RCTRL])
{ {
// Ctrl modifiers // Ctrl modifiers
int numtiles; int texturewidth;
int textureheight;
if (cl.getroomprop(ed.levx, ed.levy)->tileset == 0) 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 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; ed.dmtileeditor=10;
if(left_pressed) if(left_pressed)
{ {
@ -2583,13 +2604,11 @@ void editorinput(void)
if (key.keymap[SDLK_F1]) if (key.keymap[SDLK_F1])
{ {
ed.switch_tileset(true); ed.switch_tileset(true);
graphics.backgrounddrawn = false;
ed.keydelay = 6; ed.keydelay = 6;
} }
if (key.keymap[SDLK_F2]) if (key.keymap[SDLK_F2])
{ {
ed.switch_tilecol(true); ed.switch_tilecol(true);
graphics.backgrounddrawn = false;
ed.keydelay = 6; ed.keydelay = 6;
} }
if (key.keymap[SDLK_F3]) if (key.keymap[SDLK_F3])
@ -2600,7 +2619,6 @@ void editorinput(void)
if (key.keymap[SDLK_w]) if (key.keymap[SDLK_w])
{ {
ed.switch_warpdir(true); ed.switch_warpdir(true);
graphics.backgrounddrawn = false;
ed.keydelay = 6; ed.keydelay = 6;
} }
@ -2659,13 +2677,11 @@ void editorinput(void)
if(key.keymap[SDLK_F1]) if(key.keymap[SDLK_F1])
{ {
ed.switch_tileset(false); ed.switch_tileset(false);
graphics.backgrounddrawn = false;
ed.keydelay = 6; ed.keydelay = 6;
} }
if(key.keymap[SDLK_F2]) if(key.keymap[SDLK_F2])
{ {
ed.switch_tilecol(false); ed.switch_tilecol(false);
graphics.backgrounddrawn = false;
ed.keydelay = 6; ed.keydelay = 6;
} }
if(key.keymap[SDLK_F3]) if(key.keymap[SDLK_F3])
@ -2730,7 +2746,6 @@ void editorinput(void)
if(key.keymap[SDLK_w]) if(key.keymap[SDLK_w])
{ {
ed.switch_warpdir(false); ed.switch_warpdir(false);
graphics.backgrounddrawn = false;
ed.keydelay = 6; ed.keydelay = 6;
} }
if(key.keymap[SDLK_e]) if(key.keymap[SDLK_e])
@ -2848,7 +2863,6 @@ void editorinput(void)
} }
music.haltdasmusik(); music.haltdasmusik();
graphics.backgrounddrawn=false;
ed.returneditoralpha = 1000; // Let's start it higher than 255 since it gets clamped ed.returneditoralpha = 1000; // Let's start it higher than 255 since it gets clamped
ed.oldreturneditoralpha = 1000; ed.oldreturneditoralpha = 1000;
script.startgamemode(Start_EDITORPLAYTESTING); script.startgamemode(Start_EDITORPLAYTESTING);
@ -2892,34 +2906,34 @@ void editorinput(void)
if(up_pressed) if(up_pressed)
{ {
ed.keydelay = 6; ed.keydelay = 6;
graphics.backgrounddrawn=false;
ed.levy--; ed.levy--;
ed.updatetiles = true; ed.updatetiles = true;
ed.changeroom = true; ed.changeroom = true;
graphics.backgrounddrawn = false;
} }
else if(down_pressed) else if(down_pressed)
{ {
ed.keydelay = 6; ed.keydelay = 6;
graphics.backgrounddrawn=false;
ed.levy++; ed.levy++;
ed.updatetiles = true; ed.updatetiles = true;
ed.changeroom = true; ed.changeroom = true;
graphics.backgrounddrawn = false;
} }
else if(left_pressed) else if(left_pressed)
{ {
ed.keydelay = 6; ed.keydelay = 6;
graphics.backgrounddrawn=false;
ed.levx--; ed.levx--;
ed.updatetiles = true; ed.updatetiles = true;
ed.changeroom = true; ed.changeroom = true;
graphics.backgrounddrawn = false;
} }
else if(right_pressed) else if(right_pressed)
{ {
ed.keydelay = 6; ed.keydelay = 6;
graphics.backgrounddrawn=false;
ed.levx++; ed.levx++;
ed.updatetiles = true; ed.updatetiles = true;
ed.changeroom = true; ed.changeroom = true;
graphics.backgrounddrawn = false;
} }
if (ed.levx < 0) ed.levx += cl.mapwidth; if (ed.levx < 0) ed.levx += cl.mapwidth;
@ -4248,6 +4262,8 @@ void editorclass::switch_tileset(const bool reversed)
note = buffer; note = buffer;
notedelay = 45; notedelay = 45;
updatetiles = true; updatetiles = true;
graphics.backgrounddrawn = false;
} }
void editorclass::switch_tilecol(const bool reversed) void editorclass::switch_tilecol(const bool reversed)
@ -4270,6 +4286,8 @@ void editorclass::switch_tilecol(const bool reversed)
notedelay = 45; notedelay = 45;
note = loc::gettext("Tileset Colour Changed"); note = loc::gettext("Tileset Colour Changed");
updatetiles = true; updatetiles = true;
graphics.backgrounddrawn = false;
} }
void editorclass::clamp_tilecol(const int rx, const int ry, const bool wrap) 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; notedelay = 45;
graphics.backgrounddrawn = false;
} }
#endif /* NO_CUSTOM_LEVELS and NO_EDITOR */ #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; colpoint2.y = entities[j].yp;
int drawframe1 = entities[i].collisiondrawframe; int drawframe1 = entities[i].collisiondrawframe;
int drawframe2 = entities[j].drawframe; 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) if (INBOUNDS_VEC(drawframe1, spritesvec) && INBOUNDS_VEC(drawframe2, spritesvec)
&& graphics.Hitest(spritesvec[drawframe1], && graphics.Hitest(spritesvec[drawframe1],
colpoint1, spritesvec[drawframe2], colpoint2)) 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 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) #define FADEMODE_IS_FADING(mode) ((mode) != FADE_NONE && (mode) != FADE_FULLY_BLACK)
class Graphics class Graphics
@ -29,7 +47,7 @@ public:
void init(void); void init(void);
void destroy(void); void destroy(void);
void create_buffers(const SDL_PixelFormat* fmt); void create_buffers(void);
void destroy_buffers(void); void destroy_buffers(void);
GraphicsResources grphx; GraphicsResources grphx;
@ -39,18 +57,13 @@ public:
bool Makebfont(void); bool Makebfont(void);
void drawhuetile(int x, int y, int t, SDL_Color ct);
SDL_Color huetilegetcol(int t); SDL_Color huetilegetcol(int t);
SDL_Color bigchunkygetcol(int t); SDL_Color bigchunkygetcol(int t);
void drawgravityline(int t); void drawgravityline(int t);
bool MakeTileArray(void);
bool MakeSpriteArray(void); bool MakeSpriteArray(void);
bool maketelearray(void);
void drawcoloredtile(int x, int y, int t, int r, int g, int b); 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); 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 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 updatetextboxes(void);
void drawgui(void); void drawgui(void);
void drawsprite(int x, int y, int t, int r, int g, int b); void draw_sprite(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, SDL_Color color);
void scroll_texture(SDL_Texture* texture, int x, int y);
void printcrewname(int x, int y, int t); void printcrewname(int x, int y, int t);
void printcrewnamedark(int x, int y, int t); void printcrewnamedark(int x, int y, int t);
void printcrewnamestatus(int x, int y, int t, bool rescued); 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_tab(int opt, const char* text, bool selected = false);
void map_option(int opt, int num_opts, const std::string& text, bool selected = false); void map_option(int opt, int num_opts, const std::string& text, bool selected = false);
@ -261,28 +320,22 @@ public:
int m; int m;
std::vector <SDL_Surface*> images; std::vector <SDL_Surface*> sprites_surf;
std::vector <SDL_Surface*> flipsprites_surf;
std::vector <SDL_Surface*> tele; SDL_Texture* images[NUM_IMAGES];
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;
bool flipmode; bool flipmode;
bool setflipmode; bool setflipmode;
bool notextoutline; bool notextoutline;
//buffer objects. //TODO refactor buffer objects
SDL_Surface* backBuffer; SDL_Texture* gameTexture;
SDL_Surface* menubuffer; SDL_Texture* tempTexture;
SDL_Surface* foregroundBuffer; SDL_Texture* gameplayTexture;
SDL_Surface* menuoffbuffer; SDL_Texture* menuTexture;
SDL_Surface* warpbuffer; SDL_Texture* ghostTexture;
SDL_Surface* warpbuffer_lerp; SDL_Texture* backgroundTexture;
SDL_Texture* foregroundTexture;
TowerBG towerbg; TowerBG towerbg;
TowerBG titlebg; TowerBG titlebg;
@ -291,11 +344,9 @@ public:
SDL_Rect sprites_rect; SDL_Rect sprites_rect;
SDL_Rect line_rect; SDL_Rect line_rect;
SDL_Rect tele_rect; SDL_Rect tele_rect;
SDL_Rect towerbuffer_rect;
SDL_Rect prect; SDL_Rect prect;
SDL_Rect footerrect; SDL_Rect footerrect;
SDL_Surface* footerbuffer;
int linestate, linedelay; int linestate, linedelay;
int backoffset; int backoffset;
@ -340,8 +391,6 @@ public:
std::map<int, int> font_positions; std::map<int, int> font_positions;
SDL_Surface* ghostbuffer;
#ifndef GAME_DEFINITION #ifndef GAME_DEFINITION
float inline lerp(const float v0, const float v1) float inline lerp(const float v0, const float v1)
{ {

View file

@ -2,7 +2,9 @@
#include "Alloc.h" #include "Alloc.h"
#include "FileSystemUtils.h" #include "FileSystemUtils.h"
#include "GraphicsUtil.h"
#include "Vlogging.h" #include "Vlogging.h"
#include "Screen.h"
// Used to load PNG data // Used to load PNG data
extern "C" extern "C"
@ -17,15 +19,11 @@ extern "C"
extern const char* lodepng_error_text(unsigned code); extern const char* lodepng_error_text(unsigned code);
} }
/* Don't declare `static`, this is used elsewhere */ static SDL_Surface* LoadImageRaw(const char* filename, unsigned char** data)
SDL_Surface* LoadImage(const char *filename)
{ {
//Temporary storage for the image that's loaded //Temporary storage for the image that's loaded
SDL_Surface* loadedImage = NULL; SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
unsigned char *data;
unsigned int width, height; unsigned int width, height;
unsigned int error; unsigned int error;
@ -37,7 +35,7 @@ SDL_Surface* LoadImage(const char *filename)
SDL_assert(0 && "Image file missing!"); SDL_assert(0 && "Image file missing!");
return NULL; return NULL;
} }
error = lodepng_decode32(&data, &width, &height, fileIn, length); error = lodepng_decode32(data, &width, &height, fileIn, length);
VVV_free(fileIn); VVV_free(fileIn);
if (error != 0) if (error != 0)
@ -47,7 +45,7 @@ SDL_Surface* LoadImage(const char *filename)
} }
loadedImage = SDL_CreateRGBSurfaceWithFormatFrom( loadedImage = SDL_CreateRGBSurfaceWithFormatFrom(
data, *data,
width, width,
height, height,
32, 32,
@ -55,61 +53,260 @@ SDL_Surface* LoadImage(const char *filename)
SDL_PIXELFORMAT_ABGR8888 SDL_PIXELFORMAT_ABGR8888
); );
if (loadedImage != NULL) return loadedImage;
}
static SDL_Surface* LoadSurfaceFromRaw(SDL_Surface* loadedImage)
{ {
optimizedImage = SDL_ConvertSurfaceFormat( SDL_Surface* optimizedImage = SDL_ConvertSurfaceFormat(
loadedImage, loadedImage,
SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888,
0 0
); );
VVV_freefunc(SDL_FreeSurface, loadedImage);
VVV_free(data);
SDL_SetSurfaceBlendMode(optimizedImage, SDL_BLENDMODE_BLEND); SDL_SetSurfaceBlendMode(optimizedImage, SDL_BLENDMODE_BLEND);
return optimizedImage; return optimizedImage;
} }
else
/* 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)
{
VVV_freefunc(SDL_FreeSurface, loadedImage);
}
VVV_free(data);
if (optimizedImage == NULL)
{ {
VVV_free(data); VVV_free(data);
vlog_error("Image not found: %s", filename); vlog_error("Image not found: %s", filename);
SDL_assert(0 && "Image not found! See stderr."); 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; 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) void GraphicsResources::init(void)
{ {
im_tiles = LoadImage("graphics/tiles.png"); LoadVariants("graphics/tiles.png", &im_tiles, &im_tiles_white, &im_tiles_tint);
im_tiles2 = LoadImage("graphics/tiles2.png"); LoadVariants("graphics/tiles2.png", &im_tiles2, NULL, &im_tiles2_tint);
LoadVariants("graphics/entcolours.png", &im_entcolours, NULL, &im_entcolours_tint);
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_tiles3 = LoadImage("graphics/tiles3.png");
im_entcolours = LoadImage("graphics/entcolours.png"); im_bfont = LoadImage("graphics/font.png", TEX_WHITE);
im_sprites = LoadImage("graphics/sprites.png"); im_teleporter = LoadImage("graphics/teleporter.png", TEX_WHITE);
im_flipsprites = LoadImage("graphics/flipsprites.png");
im_bfont = LoadImage("graphics/font.png");
im_teleporter = LoadImage("graphics/teleporter.png");
im_image0 = LoadImage("graphics/levelcomplete.png"); im_image0 = LoadImage("graphics/levelcomplete.png");
im_image1 = LoadImage("graphics/minimap.png"); im_image1 = LoadImage("graphics/minimap.png");
im_image2 = LoadImage("graphics/covered.png"); im_image2 = LoadImage("graphics/covered.png");
im_image3 = LoadImage("graphics/elephant.png"); im_image3 = LoadImage("graphics/elephant.png", TEX_WHITE);
im_image4 = LoadImage("graphics/gamecomplete.png"); im_image4 = LoadImage("graphics/gamecomplete.png");
im_image5 = LoadImage("graphics/fliplevelcomplete.png"); im_image5 = LoadImage("graphics/fliplevelcomplete.png");
im_image6 = LoadImage("graphics/flipgamecomplete.png"); im_image6 = LoadImage("graphics/flipgamecomplete.png");
im_image7 = LoadImage("graphics/site.png"); im_image7 = LoadImage("graphics/site.png", TEX_WHITE);
im_image8 = LoadImage("graphics/site2.png"); im_image8 = LoadImage("graphics/site2.png", TEX_WHITE);
im_image9 = LoadImage("graphics/site3.png"); im_image9 = LoadImage("graphics/site3.png", TEX_WHITE);
im_image10 = LoadImage("graphics/ending.png"); im_image10 = LoadImage("graphics/ending.png");
im_image11 = LoadImage("graphics/site4.png"); im_image11 = LoadImage("graphics/site4.png", TEX_WHITE);
im_image12 = LoadImage("graphics/minimap.png");
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) 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);
CLEAR(im_tiles_white);
CLEAR(im_tiles_tint);
CLEAR(im_tiles2); CLEAR(im_tiles2);
CLEAR(im_tiles2_tint);
CLEAR(im_tiles3); CLEAR(im_tiles3);
CLEAR(im_entcolours); CLEAR(im_entcolours);
CLEAR(im_entcolours_tint);
CLEAR(im_sprites); CLEAR(im_sprites);
CLEAR(im_flipsprites); CLEAR(im_flipsprites);
CLEAR(im_bfont); CLEAR(im_bfont);
@ -129,4 +326,7 @@ void GraphicsResources::destroy(void)
CLEAR(im_image11); CLEAR(im_image11);
CLEAR(im_image12); CLEAR(im_image12);
#undef CLEAR #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> #include <SDL.h>
enum TextureLoadType
{
TEX_COLOR,
TEX_WHITE,
TEX_GRAYSCALE
};
class GraphicsResources class GraphicsResources
{ {
public: public:
void init(void); void init(void);
void destroy(void); void destroy(void);
SDL_Surface* im_tiles; SDL_Surface* im_sprites_surf;
SDL_Surface* im_tiles2; SDL_Surface* im_flipsprites_surf;
SDL_Surface* im_tiles3;
SDL_Surface* im_entcolours; SDL_Texture* im_tiles;
SDL_Surface* im_sprites; SDL_Texture* im_tiles_white;
SDL_Surface* im_flipsprites; SDL_Texture* im_tiles_tint;
SDL_Surface* im_bfont; SDL_Texture* im_tiles2;
SDL_Surface* im_teleporter; SDL_Texture* im_tiles2_tint;
SDL_Surface* im_image0; SDL_Texture* im_tiles3;
SDL_Surface* im_image1; SDL_Texture* im_entcolours;
SDL_Surface* im_image2; SDL_Texture* im_entcolours_tint;
SDL_Surface* im_image3; SDL_Texture* im_sprites;
SDL_Surface* im_image4; SDL_Texture* im_flipsprites;
SDL_Surface* im_image5; SDL_Texture* im_bfont;
SDL_Surface* im_image6; SDL_Texture* im_teleporter;
SDL_Surface* im_image7; SDL_Texture* im_image0;
SDL_Surface* im_image8; SDL_Texture* im_image1;
SDL_Surface* im_image9; SDL_Texture* im_image2;
SDL_Surface* im_image10; SDL_Texture* im_image3;
SDL_Surface* im_image11; SDL_Texture* im_image4;
SDL_Surface* im_image12; 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 */ #endif /* GRAPHICSRESOURCES_H */

View file

@ -3,8 +3,12 @@
#include <stdlib.h> #include <stdlib.h>
#include "Alloc.h" #include "Alloc.h"
#include "Constants.h"
#include "Graphics.h" #include "Graphics.h"
#include "Maths.h" #include "Maths.h"
#include "Screen.h"
#include "UtilityClass.h"
#include "Vlogging.h"
@ -52,20 +56,6 @@ static SDL_Surface* RecreateSurfaceWithDimensions(
return retval; 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 ) SDL_Surface* GetSubSurface( SDL_Surface* metaSurface, int x, int y, int width, int height )
{ {
// Create an SDL_Rect with the area of the _surface // 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; 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 SDL_PixelFormat* fmt = surface->format;
const int bpp = fmt->BytesPerPixel; const int bpp = fmt->BytesPerPixel;
@ -130,188 +120,6 @@ SDL_Color ReadPixel(const SDL_Surface* surface, const int x, const int y)
return color; 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 oldscrollamount = 0;
static int scrollamount = 0; static int scrollamount = 0;
static bool isscrolling = 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; 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; 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); blue = SDL_max(blue - (distX + distY), 0);
const SDL_Color color = {red, green, blue, pixel.a}; const SDL_Color color = {red, green, blue, pixel.a};
DrawPixel(ret, x, y, color); DrawPixel(dest, x, y, color);
} }
} }
return ret; SDL_FreeFormat(format);
}
SDL_UpdateTexture(graphics.gameTexture, NULL, dest->pixels, dest->pitch);
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_FreeSurface(src);
SDL_Rect rect = {_x, _y, _w, _h}; SDL_FreeSurface(dest);
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);
}
} }

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 ); 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_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); void UpdateFilter(void);
SDL_Surface* ApplyFilter( SDL_Surface* _src ); void ApplyFilter(void);
#endif /* GRAPHICSUTIL_H */ #endif /* GRAPHICSUTIL_H */

View file

@ -3072,9 +3072,6 @@ static void mapmenuactionpress(const bool version2_2)
case 11: case 11:
//quit to menu //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; graphics.fademode = FADE_START_FADEOUT;
music.fadeout(); music.fadeout();
map.nexttowercolour(); map.nexttowercolour();

View file

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

View file

@ -1410,13 +1410,16 @@ void gamelogic(void)
{ {
graphics.foregrounddrawn = false; graphics.foregrounddrawn = false;
} }
if (map.final_aniframedelay <= 0) { if (map.final_aniframedelay <= 0)
{
map.final_aniframedelay = 2; map.final_aniframedelay = 2;
map.final_aniframe++; map.final_aniframe++;
if (map.final_aniframe >= 4) if (map.final_aniframe >= 4)
{
map.final_aniframe = 0; map.final_aniframe = 0;
} }
} }
}
game.activeactivity = obj.checkactivity(); game.activeactivity = obj.checkactivity();

View file

@ -147,12 +147,12 @@ static void menurender(void)
case Menu::mainmenu: case Menu::mainmenu:
{ {
const int temp = 50; const int temp = 50;
graphics.drawsprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((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) + 5 * 32, temp, 23, tr, tg, tb);
#if defined(MAKEANDPLAY) #if defined(MAKEANDPLAY)
const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION"); const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION");
graphics.Print(264-graphics.len(editionlabel),temp+35,editionlabel,tr, tg, tb); 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.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.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.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.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; break;
case Menu::credits2: case Menu::credits2:
graphics.Print( -1, 50, loc::gettext("Roomnames are by"), tr, tg, tb, true); graphics.Print( -1, 50, loc::gettext("Roomnames are by"), tr, tg, tb, true);
graphics.bigprint( 40, 65, "Bennett Foddy", 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.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, 125, "Simon Roth", tr, tg, tb, true);
graphics.bigprint( 40, 145, "Ethan Lee", 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_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); 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; int wraplimit;
if (overflow.multiline) if (overflow.multiline)
@ -1029,7 +1029,7 @@ static void menurender(void)
graphics.bigprint(-1, 30, loc::gettext("Text Outline"), tr, tg, tb, true); 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); 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) 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.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.draw_sprite(34, 126-20, 50, graphics.col_clock);
graphics.drawsprite(270, 126-20, 22, graphics.col_trinket); graphics.draw_sprite(270, 126-20, 22, graphics.col_trinket);
break; break;
} }
case 1: 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.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.draw_sprite(34, 126-20, 50, graphics.col_clock);
graphics.drawsprite(270, 126-20, 22, graphics.col_trinket); graphics.draw_sprite(270, 126-20, 22, graphics.col_trinket);
break; break;
} }
} }
@ -1597,9 +1597,7 @@ static void menurender(void)
void titlerender(void) void titlerender(void)
{ {
graphics.clear();
ClearSurface(graphics.backBuffer);
if (!game.menustart) if (!game.menustart)
{ {
tr = graphics.col_tr; tr = graphics.col_tr;
@ -1607,12 +1605,12 @@ void titlerender(void)
tb = graphics.col_tb; tb = graphics.col_tb;
int temp = 50; int temp = 50;
graphics.drawsprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((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) + 5 * 32, temp, 23, tr, tg, tb);
#if defined(MAKEANDPLAY) #if defined(MAKEANDPLAY)
const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION"); const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION");
graphics.Print(264-graphics.len(editionlabel),temp+35,editionlabel,tr, tg, tb); graphics.Print(264-graphics.len(editionlabel),temp+35,editionlabel,tr, tg, tb);
@ -1650,7 +1648,7 @@ void titlerender(void)
void gamecompleterender(void) void gamecompleterender(void)
{ {
ClearSurface(graphics.backBuffer); graphics.clear();
if(!game.colourblindmode) graphics.drawtowerbackground(graphics.titlebg); if(!game.colourblindmode) graphics.drawtowerbackground(graphics.titlebg);
@ -1665,12 +1663,12 @@ void gamecompleterender(void)
if (graphics.onscreen(220 + position)) if (graphics.onscreen(220 + position))
{ {
int temp = 220 + position; int temp = 220 + position;
graphics.drawsprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 0 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 1 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 2 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((160 - 96) + 3 * 32, temp, 23, tr, tg, tb);
graphics.drawsprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb); graphics.draw_sprite((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) + 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); 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) 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++) for (int j = 0; j < 30; j++)
{ {
@ -1814,18 +1812,18 @@ void gamecompleterender2(void)
{ {
if (i > game.creditposx) 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) 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(); graphics.drawfade();
@ -1855,12 +1853,11 @@ static const char* interact_prompt(
void gamerender(void) void gamerender(void)
{ {
graphics.set_render_target(graphics.gameplayTexture);
graphics.set_color(0, 0, 0, 255);
if(!game.blackout) if(!game.blackout)
{ {
if (map.towermode) if (map.towermode)
{ {
if (!game.colourblindmode) if (!game.colourblindmode)
@ -1869,7 +1866,7 @@ void gamerender(void)
} }
else else
{ {
ClearSurface(graphics.backBuffer); graphics.clear();
} }
graphics.drawtowermap(); graphics.drawtowermap();
} }
@ -1881,7 +1878,7 @@ void gamerender(void)
} }
else else
{ {
ClearSurface(graphics.backBuffer); graphics.clear();
} }
if ((map.finalmode || map.custommode) && map.final_colormode) if ((map.finalmode || map.custommode) && map.final_colormode)
{ {
@ -1962,7 +1959,10 @@ void gamerender(void)
graphics.cutscenebars(); graphics.cutscenebars();
graphics.drawfade(); graphics.drawfade();
BlitSurfaceStandard(graphics.backBuffer, NULL, graphics.menuoffbuffer, NULL);
graphics.set_render_target(graphics.gameTexture);
graphics.copy_texture(graphics.gameplayTexture, NULL, NULL);
graphics.drawgui(); graphics.drawgui();
if (graphics.flipmode) if (graphics.flipmode)
@ -2280,13 +2280,13 @@ static void rendermap(void)
if (map.custommode && map.customshowmm) if (map.custommode && map.customshowmm)
{ {
graphics.drawpixeltextbox(35 + map.custommmxoff, 16 + map.custommmyoff, map.custommmxsize + 10, map.custommmysize + 10, 65, 185, 207); 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; return;
} }
#endif /* NO_CUSTOM_LEVELS */ #endif /* NO_CUSTOM_LEVELS */
graphics.drawpixeltextbox(35, 16, 250, 190, 65, 185, 207); 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) static void rendermapfog(void)
@ -2304,7 +2304,7 @@ static void rendermapfog(void)
{ {
for (int y = 0; y < data.zoom; y++) 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) void maprender(void)
{ {
ClearSurface(graphics.backBuffer); graphics.set_render_target(graphics.menuTexture);
graphics.clear();
draw_roomname_menu(); draw_roomname_menu();
//Background color //Background color
FillRect(graphics.backBuffer,0, 12, 320, 240, 10, 24, 26 ); graphics.fill_rect(0, 12, 320, 240, 10, 24, 26 );
//Menubar: //Menubar:
graphics.drawtextbox( -10, 212, 43, 3, 65, 185, 207); graphics.drawtextbox( -10, 212, 43, 3, 65, 185, 207);
@ -2458,7 +2459,7 @@ void maprender(void)
{ {
for (int i = 0; i < 20; i++) 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); 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.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.draw_sprite(34, FLIP(126, 17), 50, graphics.col_clock);
graphics.drawsprite(270, FLIP(126, 17), 22, graphics.col_trinket); graphics.draw_sprite(270, FLIP(126, 17), 22, graphics.col_trinket);
break; break;
} }
case 10: case 10:
@ -2851,8 +2852,16 @@ void maprender(void)
} }
graphics.set_render_target(graphics.gameTexture);
if (graphics.resumegamemode || graphics.menuoffset > 0 || graphics.oldmenuoffset > 0)
{
graphics.menuoffrender();
}
else
{
graphics.copy_texture(graphics.menuTexture, NULL, NULL);
}
// We need to draw the black screen above the menu in order to disguise it // 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 // being jankily brought down in glitchrunner mode when exiting to the title
@ -2865,28 +2874,24 @@ void maprender(void)
graphics.drawfade(); graphics.drawfade();
} }
if (graphics.resumegamemode || graphics.menuoffset > 0 || graphics.oldmenuoffset > 0)
{
graphics.menuoffrender();
}
else
{
graphics.renderwithscreeneffects(); graphics.renderwithscreeneffects();
} }
}
#undef FLIP #undef FLIP
void teleporterrender(void) 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 telex = map.teleporters[game.teleport_to_teleporter].x;
const int teley = map.teleporters[game.teleport_to_teleporter].y; const int teley = map.teleporters[game.teleport_to_teleporter].y;
draw_roomname_menu(); draw_roomname_menu();
//Background color //Background color
FillRect(graphics.backBuffer, 0, 12, 320, 240, 10, 24, 26); graphics.fill_rect(0, 12, 320, 240, 10, 24, 26);
rendermap(); rendermap();
rendermapfog(); 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); 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) if (graphics.resumegamemode || graphics.menuoffset > 0 || graphics.oldmenuoffset > 0)
{ {
@ -2951,6 +2957,8 @@ void teleporterrender(void)
} }
else else
{ {
graphics.copy_texture(graphics.menuTexture, NULL, NULL);
}
graphics.render(); graphics.render();
} }
}

View file

@ -3,6 +3,7 @@
#include "Constants.h" #include "Constants.h"
#include "Game.h" #include "Game.h"
#include "Graphics.h" #include "Graphics.h"
#include "GraphicsUtil.h"
#include "KeyPoll.h" #include "KeyPoll.h"
#include "Localization.h" #include "Localization.h"
#include "LocalizationMaint.h" #include "LocalizationMaint.h"
@ -54,7 +55,9 @@ namespace roomname_translator
fullscreen_rect.y = 0; fullscreen_rect.y = 0;
fullscreen_rect.w = 320; fullscreen_rect.w = 320;
fullscreen_rect.h = 240; 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) if (help_screen)
{ {
graphics.bprint(0, 0, "=== Room name translation mode help ===", 255,255,255); graphics.bprint(0, 0, "=== Room name translation mode help ===", 255,255,255);

View file

@ -7,8 +7,10 @@
#include "Constants.h" #include "Constants.h"
#include "FileSystemUtils.h" #include "FileSystemUtils.h"
#include "Game.h" #include "Game.h"
#include "Graphics.h"
#include "GraphicsUtil.h" #include "GraphicsUtil.h"
#include "InterimVersion.h" #include "InterimVersion.h"
#include "Render.h"
#include "Vlogging.h" #include "Vlogging.h"
void ScreenSettings_default(struct ScreenSettings* _this) void ScreenSettings_default(struct ScreenSettings* _this)
@ -26,8 +28,6 @@ void Screen::init(const struct ScreenSettings* settings)
{ {
m_window = NULL; m_window = NULL;
m_renderer = NULL; m_renderer = NULL;
m_screenTexture = NULL;
m_screen = NULL;
isWindowed = !settings->fullscreen; isWindowed = !settings->fullscreen;
scalingMode = settings->scalingMode; scalingMode = settings->scalingMode;
isFiltered = settings->linearFilter; isFiltered = settings->linearFilter;
@ -46,13 +46,18 @@ void Screen::init(const struct ScreenSettings* settings)
// Uncomment this next line when you need to debug -flibit // Uncomment this next line when you need to debug -flibit
// SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "software", SDL_HINT_OVERRIDE); // 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_WIDTH_PIXELS * 2,
SCREEN_HEIGHT_PIXELS * 2, SCREEN_HEIGHT_PIXELS * 2,
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI, SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI
&m_window,
&m_renderer
); );
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
#ifdef INTERIM_VERSION_EXISTS #ifdef INTERIM_VERSION_EXISTS
/* Branch name limits are ill-defined but on GitHub it's ~256 chars /* Branch name limits are ill-defined but on GitHub it's ~256 chars
* ( https://stackoverflow.com/a/24014513/ ). * ( https://stackoverflow.com/a/24014513/ ).
@ -66,25 +71,6 @@ void Screen::init(const struct ScreenSettings* settings)
LoadIcon(); 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; badSignalEffect = settings->badSignal;
ResizeScreen(settings->windowWidth, settings->windowHeight); ResizeScreen(settings->windowWidth, settings->windowHeight);
@ -93,8 +79,6 @@ void Screen::init(const struct ScreenSettings* settings)
void Screen::destroy(void) void Screen::destroy(void)
{ {
/* Order matters! */ /* Order matters! */
VVV_freefunc(SDL_DestroyTexture, m_screenTexture);
VVV_freefunc(SDL_FreeSurface, m_screen);
VVV_freefunc(SDL_DestroyRenderer, m_renderer); VVV_freefunc(SDL_DestroyRenderer, m_renderer);
VVV_freefunc(SDL_DestroyWindow, m_window); VVV_freefunc(SDL_DestroyWindow, m_window);
} }
@ -121,11 +105,11 @@ void Screen::LoadIcon(void)
} }
#else #else
SDL_Surface* LoadImage(const char* filename); SDL_Surface* LoadImageSurface(const char* filename);
void Screen::LoadIcon(void) void Screen::LoadIcon(void)
{ {
SDL_Surface* icon = LoadImage("VVVVVV.png"); SDL_Surface* icon = LoadImageSurface("VVVVVV.png");
if (icon == NULL) if (icon == NULL)
{ {
return; return;
@ -149,6 +133,7 @@ void Screen::ResizeScreen(int x, int y)
if (!isWindowed || isForcedFullscreen()) if (!isWindowed || isForcedFullscreen())
{ {
int result = SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP); int result = SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
recacheTextures();
if (result != 0) if (result != 0)
{ {
vlog_error("Error: could not set the game to fullscreen mode: %s", SDL_GetError()); 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 else
{ {
int result = SDL_SetWindowFullscreen(m_window, 0); int result = SDL_SetWindowFullscreen(m_window, 0);
recacheTextures();
if (result != 0) if (result != 0)
{ {
vlog_error("Error: could not set the game to windowed mode: %s", SDL_GetError()); 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_RenderPresent(m_renderer);
SDL_RenderClear(m_renderer); graphics.clear();
ClearSurface(m_screen);
} }
void Screen::toggleFullScreen(void) void Screen::toggleFullScreen(void)
@ -354,20 +284,49 @@ void Screen::toggleLinearFilter(void)
isFiltered ? "linear" : "nearest", isFiltered ? "linear" : "nearest",
SDL_HINT_OVERRIDE SDL_HINT_OVERRIDE
); );
SDL_DestroyTexture(m_screenTexture); SDL_DestroyTexture(graphics.gameTexture);
m_screenTexture = SDL_CreateTexture( graphics.gameTexture = SDL_CreateTexture(
m_renderer, m_renderer,
SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, SDL_TEXTUREACCESS_TARGET,
SCREEN_WIDTH_PIXELS, SCREEN_WIDTH_PIXELS,
SCREEN_HEIGHT_PIXELS SCREEN_HEIGHT_PIXELS
); );
if (graphics.gameTexture == NULL)
{
vlog_error("Could not create game texture: %s", SDL_GetError());
return;
}
} }
void Screen::toggleVSync(void) void Screen::toggleVSync(void)
{ {
vsync = !vsync; vsync = !vsync;
SDL_RenderSetVSync(m_renderer, (int) 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 /* FIXME: Launching in forced fullscreen then exiting and relaunching in normal

View file

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

View file

@ -183,31 +183,44 @@ void scriptclass::run(void)
room = cl.getroomprop(temprx, tempry); room = cl.getroomprop(temprx, tempry);
//Do we update our own room? //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: //If screen warping, then override all that:
graphics.backgrounddrawn = false; graphics.backgrounddrawn = false;
map.warpx=false; map.warpy=false; map.warpx = false;
if(room->warpdir==0){ map.warpy = false;
if (room->warpdir == 0)
{
map.background = 1; map.background = 1;
//Be careful, we could be in a Lab or Warp Zone room... //Be careful, we could be in a Lab or Warp Zone room...
if(room->tileset==2){ if (room->tileset == 2)
{
//Lab //Lab
map.background = 2; map.background = 2;
graphics.rcol = room->tilecol; graphics.rcol = room->tilecol;
}else if(room->tileset==3){ }
else if (room->tileset == 3)
{
//Warp Zone //Warp Zone
map.background = 6; map.background = 6;
} }
}else if(room->warpdir==1){ }
else if (room->warpdir == 1)
{
map.warpx = true; map.warpx = true;
map.background = 3; map.background = 3;
graphics.rcol = cl.getwarpbackground(temprx, tempry); graphics.rcol = cl.getwarpbackground(temprx, tempry);
}else if(room->warpdir==2){ }
else if (room->warpdir == 2)
{
map.warpy = true; map.warpy = true;
map.background = 4; map.background = 4;
graphics.rcol = cl.getwarpbackground(temprx, tempry); graphics.rcol = cl.getwarpbackground(temprx, tempry);
}else if(room->warpdir==3){ }
map.warpx=true; map.warpy=true; else if (room->warpdir == 3)
{
map.warpx = true;
map.warpy = true;
map.background = 5; map.background = 5;
graphics.rcol = cl.getwarpbackground(temprx, tempry); graphics.rcol = cl.getwarpbackground(temprx, tempry);
} }

View file

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

View file

@ -46,6 +46,15 @@ void VVV_fillstring(
} \ } \
do { } while (false) 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. */ /* Don't call this directly; use the VVV_between macro. */
void _VVV_between( void _VVV_between(
const char* original, const char* original,

View file

@ -585,33 +585,11 @@ int main(int argc, char *argv[])
vlog_info("\t\t"); vlog_info("\t\t");
// Set up screen // Set up screen
// Load Ini
graphics.init(); graphics.init();
game.init(); game.init();
game.seed_use_sdl_getticks = seed_use_sdl_getticks; 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.gamestate = PRELOADER;
game.menustart = false; game.menustart = false;
@ -636,11 +614,26 @@ int main(int argc, char *argv[])
gameScreen.init(&screen_settings); 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::loadtext(false);
loc::loadlanguagelist(); loc::loadlanguagelist();
game.createmenu(Menu::mainmenu); game.createmenu(Menu::mainmenu);
graphics.create_buffers(gameScreen.GetFormat()); graphics.create_buffers();
if (game.skipfakeload) if (game.skipfakeload)
game.gamestate = TITLEMODE; game.gamestate = TITLEMODE;
@ -790,9 +783,10 @@ static void cleanup(void)
{ {
game.savestatsandsettings(); game.savestatsandsettings();
} }
gameScreen.destroy();
graphics.grphx.destroy(); graphics.grphx.destroy();
graphics.destroy_buffers(); graphics.destroy_buffers();
gameScreen.destroy();
graphics.destroy(); graphics.destroy();
music.destroy(); music.destroy();
map.destroy(); map.destroy();
@ -849,9 +843,13 @@ static void inline deltaloop(void)
if (implfunc->type == Func_delta && implfunc->func != NULL) if (implfunc->type == Func_delta && implfunc->func != NULL)
{ {
graphics.clear();
graphics.set_render_target(graphics.gameTexture);
implfunc->func(); implfunc->func();
gameScreen.FlipScreen(graphics.flipmode); gameScreen.RenderPresent();
} }
} }
} }
@ -873,7 +871,7 @@ static void unfocused_run(void)
{ {
if (!game.blackout) if (!game.blackout)
{ {
ClearSurface(graphics.backBuffer); graphics.fill_rect(0, 0, 0);
#define FLIP(YPOS) graphics.flipmode ? 232 - YPOS : YPOS #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(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); 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; pre_temprecty = (i * 16)- pre_offset;
if (i % 2 == 0) 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 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; print_percentage = true;
@ -114,12 +114,12 @@ void preloaderrender(void)
}else if (pre_transition <= -10) { }else if (pre_transition <= -10) {
//Switch to TITLEMODE (handled by preloaderrenderfixed) //Switch to TITLEMODE (handled by preloaderrenderfixed)
}else if (pre_transition < 5) { }else if (pre_transition < 5) {
ClearSurface(graphics.backBuffer); graphics.fill_rect(0, 0, 0);
}else if (pre_transition < 20) { }else if (pre_transition < 20) {
pre_temprecty = 0; pre_temprecty = 0;
pre_temprecth = 240; pre_temprecth = 240;
ClearSurface(graphics.backBuffer); graphics.fill_rect(0, 0, 0);
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; print_percentage = true;
} }