Make drawing stone/dirt background for classic mode launcher quite a bit faster

This commit is contained in:
UnknownShadow200 2019-07-28 18:56:39 +10:00
parent 29cd6608ff
commit 3286dcf58c
4 changed files with 42 additions and 54 deletions

View file

@ -238,23 +238,6 @@ void Drawer2D_BmpScaled(Bitmap* dst, int x, int y, int width, int height,
}
}
void Drawer2D_BmpTiled(Bitmap* dst, int x, int y, int width, int height,
Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight) {
BitmapCol* dstRow;
BitmapCol* srcRow;
int xx, yy;
if (!Drawer2D_Clamp(dst, &x, &y, &width, &height)) return;
for (yy = 0; yy < height; yy++) {
srcRow = Bitmap_GetRow(src, srcY + ((y + yy) % srcHeight));
dstRow = Bitmap_GetRow(dst, y + yy) + x;
for (xx = 0; xx < width; xx++) {
dstRow[xx] = srcRow[srcX + ((x + xx) % srcWidth)];
}
}
}
void Drawer2D_BmpCopy(Bitmap* dst, int x, int y, Bitmap* src) {
int width = src->Width, height = src->Height;
BitmapCol* dstRow;

View file

@ -58,11 +58,6 @@ CC_API void Drawer2D_BmpIndexed(Bitmap* bmp, int x, int y, int size,
CC_API void Drawer2D_BmpScaled(Bitmap* dst, int x, int y, int width, int height,
Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight,
int scaleWidth, int scaleHeight);
/* Fills the given area using pixels from a region in the source bitmap, by repeatedly tiling the region. */
/* For example, if area was 12x5 and region was 5x5, region gets drawn at (0,0), (5,0), (10,0) */
/* NOTE: The tiling origin is at (0, 0) not at (x, y) */
CC_API void Drawer2D_BmpTiled(Bitmap* dst, int x, int y, int width, int height,
Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight);
/* Fills the given area using pixels from the source bitmap. */
CC_API void Drawer2D_BmpCopy(Bitmap* dst, int x, int y, Bitmap* src);

View file

@ -328,7 +328,7 @@ void Launcher_SaveSkin(void) {
*----------------------------------------------------------Background-----------------------------------------------------*
*#########################################################################################################################*/
static bool useBitmappedFont;
static Bitmap terrainBmp, fontBmp;
static Bitmap dirtBmp, stoneBmp, fontBmp;
#define TILESIZE 48
static bool Launcher_SelectZipEntry(const String* path) {
@ -339,20 +339,21 @@ static bool Launcher_SelectZipEntry(const String* path) {
static void Launcher_LoadTextures(Bitmap* bmp) {
int tileSize = bmp->Width / 16;
Bitmap_Allocate(&terrainBmp, TILESIZE * 2, TILESIZE);
Bitmap_Allocate(&dirtBmp, TILESIZE, TILESIZE);
Bitmap_Allocate(&stoneBmp, TILESIZE, TILESIZE);
/* Precompute the scaled background */
Drawer2D_BmpScaled(&terrainBmp, TILESIZE, 0, TILESIZE, TILESIZE,
Drawer2D_BmpScaled(&dirtBmp, 0, 0, TILESIZE, TILESIZE,
bmp, 2 * tileSize, 0, tileSize, tileSize,
TILESIZE, TILESIZE);
Drawer2D_BmpScaled(&terrainBmp, 0, 0, TILESIZE, TILESIZE,
Drawer2D_BmpScaled(&stoneBmp, 0, 0, TILESIZE, TILESIZE,
bmp, 1 * tileSize, 0, tileSize, tileSize,
TILESIZE, TILESIZE);
Gradient_Tint(&terrainBmp, 128, 64,
TILESIZE, 0, TILESIZE, TILESIZE);
Gradient_Tint(&terrainBmp, 96, 96,
0, 0, TILESIZE, TILESIZE);
Gradient_Tint(&dirtBmp, 128, 64,
0, 0, TILESIZE, TILESIZE);
Gradient_Tint(&stoneBmp, 96, 96,
0, 0, TILESIZE, TILESIZE);
}
static ReturnCode Launcher_ProcessZipEntry(const String* path, struct Stream* data, struct ZipState* s) {
@ -370,7 +371,7 @@ static ReturnCode Launcher_ProcessZipEntry(const String* path, struct Stream* da
useBitmappedFont = !Options_GetBool(OPT_USE_CHAT_FONT, false);
}
} else if (String_CaselessEqualsConst(path, "terrain.png")) {
if (terrainBmp.Scan0) return 0;
if (dirtBmp.Scan0) return 0;
res = Png_Decode(&bmp, data);
if (res) {
@ -419,19 +420,32 @@ void Launcher_TryLoadTexturePack(void) {
Launcher_ExtractTexturePack(&path);
/* user selected texture pack is missing some required .png files */
if (!fontBmp.Scan0 || !terrainBmp.Scan0) {
if (!fontBmp.Scan0 || !dirtBmp.Scan0) {
Launcher_ExtractTexturePack(&defZipPath);
}
}
static void Launcher_ClearTile(int x, int y, int width, int height, int srcX) {
Drawer2D_BmpTiled(&Launcher_Framebuffer, x, y, width, height,
&terrainBmp, srcX, 0, TILESIZE, TILESIZE);
/* Fills the given area using pixels from the source bitmap, by repeatedly tiling the bitmap. */
CC_NOINLINE static void Launcher_ClearTile(int x, int y, int width, int height, Bitmap* src) {
Bitmap* dst = &Launcher_Framebuffer;
BitmapCol* dstRow;
BitmapCol* srcRow;
int xx, yy;
if (!Drawer2D_Clamp(dst, &x, &y, &width, &height)) return;
for (yy = 0; yy < height; yy++) {
srcRow = Bitmap_GetRow(src, (y + yy) % TILESIZE);
dstRow = Bitmap_GetRow(dst, y + yy) + x;
for (xx = 0; xx < width; xx++) {
dstRow[xx] = srcRow[(x + xx) % TILESIZE];
}
}
}
void Launcher_ResetArea(int x, int y, int width, int height) {
if (Launcher_ClassicBackground && terrainBmp.Scan0) {
Launcher_ClearTile(x, y, width, height, 0);
if (Launcher_ClassicBackground && dirtBmp.Scan0) {
Launcher_ClearTile(x, y, width, height, &stoneBmp);
} else {
Gradient_Noise(&Launcher_Framebuffer, Launcher_BackgroundCol, 6, x, y, width, height);
}
@ -449,9 +463,9 @@ void Launcher_ResetPixels(void) {
return;
}
if (Launcher_ClassicBackground && terrainBmp.Scan0) {
Launcher_ClearTile(0, 0, Window_Width, TILESIZE, TILESIZE);
Launcher_ClearTile(0, TILESIZE, Window_Width, Window_Height - TILESIZE, 0);
if (Launcher_ClassicBackground && dirtBmp.Scan0) {
Launcher_ClearTile(0, 0, Window_Width, TILESIZE, &dirtBmp);
Launcher_ClearTile(0, TILESIZE, Window_Width, Window_Height - TILESIZE, &stoneBmp);
} else {
Launcher_ResetArea(0, 0, Window_Width, Window_Height);
}

View file

@ -17,7 +17,6 @@ int Display_ScaleY(int y) { return y * Display_DpiY / DISPLAY_DEFAULT_DPI; }
#define Display_CentreY(height) (Display_Bounds.Y + (Display_Bounds.Height - height) / 2)
int Window_Width, Window_Height;
static int windowX, windowY;
bool Window_Exists, Window_Focused;
const void* Window_Handle;
@ -129,7 +128,8 @@ static HINSTANCE win_instance;
static HWND win_handle;
static HDC win_DC;
static bool suppress_resize;
static Rect2D win_bounds; /* Rectangle of window including titlebar and borders */
static int win_totalWidth, win_totalHeight; /* Size of window including titlebar and borders */
static int windowX, windowY;
/*########################################################################################################################*
@ -158,12 +158,12 @@ static void Window_RefreshBounds(void) {
POINT topLeft = { 0, 0 };
GetWindowRect(win_handle, &rect);
win_bounds.X = rect.left; win_bounds.Width = rect.right - rect.left;
win_bounds.Y = rect.top; win_bounds.Height = rect.bottom - rect.top;
win_totalWidth = Rect_Width(rect);
win_totalHeight = Rect_Height(rect);
GetClientRect(win_handle, &rect);
Window_Width = rect.right - rect.left;
Window_Height = rect.bottom - rect.top;
Window_Width = Rect_Width(rect);
Window_Height = Rect_Height(rect);
/* GetClientRect always returns 0,0 for left,top (see MSDN) */
ClientToScreen(win_handle, &topLeft);
@ -193,7 +193,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
{
WINDOWPOS* pos = (WINDOWPOS*)lParam;
if (pos->hwnd != win_handle) break;
bool sized = pos->cx != win_bounds.Width || pos->cy != win_bounds.Height;
bool sized = pos->cx != win_totalWidth || pos->cy != win_totalHeight;
Window_RefreshBounds();
if (sized && !suppress_resize) Event_RaiseVoid(&WindowEvents.Resized);
@ -767,12 +767,6 @@ static void Window_RegisterAtoms(void) {
}
static void Window_RefreshBounds(int width, int height) {
Window child;
/* e->x and e->y are relative to parent window, which might not be root window */
/* e.g. linux mint + cinnamon, if you use /client resolution, e->x = 10, e->y = 36 */
/* So just always translate topleft to root window coordinates to avoid this */
XTranslateCoordinates(win_display, win_handle, win_rootWin, 0,0, &windowX, &windowY, &child);
if (width != Window_Width || height != Window_Height) {
Window_Width = width;
Window_Height = height;
@ -1169,7 +1163,7 @@ static void Cursor_GetRawPos(int* x, int* y) {
}
void Cursor_SetPosition(int x, int y) {
XWarpPointer(win_display, None, win_rootWin, 0,0, 0,0, x + windowX, y + windowY);
XWarpPointer(win_display, None, win_handle, 0, 0, 0, 0, x, y);
XFlush(win_display); /* TODO: not sure if XFlush call is necessary */
}
@ -1459,7 +1453,9 @@ void Window_DisableRawMouse(void) { Window_DefaultDisableRawMouse(); }
#include <dlfcn.h>
static WindowRef win_handle;
static int windowX, windowY;
static bool win_fullscreen;
/* fullscreen is tied to OpenGL context unfortunately */
static void GLContext_UnsetFullscreen(void);
static void GLContext_SetFullscreen(void);