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) { void Drawer2D_BmpCopy(Bitmap* dst, int x, int y, Bitmap* src) {
int width = src->Width, height = src->Height; int width = src->Width, height = src->Height;
BitmapCol* dstRow; 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, 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, Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight,
int scaleWidth, int scaleHeight); 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. */ /* Fills the given area using pixels from the source bitmap. */
CC_API void Drawer2D_BmpCopy(Bitmap* dst, int x, int y, Bitmap* src); CC_API void Drawer2D_BmpCopy(Bitmap* dst, int x, int y, Bitmap* src);

View File

@ -328,7 +328,7 @@ void Launcher_SaveSkin(void) {
*----------------------------------------------------------Background-----------------------------------------------------* *----------------------------------------------------------Background-----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static bool useBitmappedFont; static bool useBitmappedFont;
static Bitmap terrainBmp, fontBmp; static Bitmap dirtBmp, stoneBmp, fontBmp;
#define TILESIZE 48 #define TILESIZE 48
static bool Launcher_SelectZipEntry(const String* path) { static bool Launcher_SelectZipEntry(const String* path) {
@ -339,19 +339,20 @@ static bool Launcher_SelectZipEntry(const String* path) {
static void Launcher_LoadTextures(Bitmap* bmp) { static void Launcher_LoadTextures(Bitmap* bmp) {
int tileSize = bmp->Width / 16; 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 */ /* Precompute the scaled background */
Drawer2D_BmpScaled(&terrainBmp, TILESIZE, 0, TILESIZE, TILESIZE, Drawer2D_BmpScaled(&dirtBmp, 0, 0, TILESIZE, TILESIZE,
bmp, 2 * tileSize, 0, tileSize, tileSize, bmp, 2 * tileSize, 0, tileSize, tileSize,
TILESIZE, TILESIZE); TILESIZE, TILESIZE);
Drawer2D_BmpScaled(&terrainBmp, 0, 0, TILESIZE, TILESIZE, Drawer2D_BmpScaled(&stoneBmp, 0, 0, TILESIZE, TILESIZE,
bmp, 1 * tileSize, 0, tileSize, tileSize, bmp, 1 * tileSize, 0, tileSize, tileSize,
TILESIZE, TILESIZE); TILESIZE, TILESIZE);
Gradient_Tint(&terrainBmp, 128, 64, Gradient_Tint(&dirtBmp, 128, 64,
TILESIZE, 0, TILESIZE, TILESIZE); 0, 0, TILESIZE, TILESIZE);
Gradient_Tint(&terrainBmp, 96, 96, Gradient_Tint(&stoneBmp, 96, 96,
0, 0, TILESIZE, TILESIZE); 0, 0, TILESIZE, TILESIZE);
} }
@ -370,7 +371,7 @@ static ReturnCode Launcher_ProcessZipEntry(const String* path, struct Stream* da
useBitmappedFont = !Options_GetBool(OPT_USE_CHAT_FONT, false); useBitmappedFont = !Options_GetBool(OPT_USE_CHAT_FONT, false);
} }
} else if (String_CaselessEqualsConst(path, "terrain.png")) { } else if (String_CaselessEqualsConst(path, "terrain.png")) {
if (terrainBmp.Scan0) return 0; if (dirtBmp.Scan0) return 0;
res = Png_Decode(&bmp, data); res = Png_Decode(&bmp, data);
if (res) { if (res) {
@ -419,19 +420,32 @@ void Launcher_TryLoadTexturePack(void) {
Launcher_ExtractTexturePack(&path); Launcher_ExtractTexturePack(&path);
/* user selected texture pack is missing some required .png files */ /* user selected texture pack is missing some required .png files */
if (!fontBmp.Scan0 || !terrainBmp.Scan0) { if (!fontBmp.Scan0 || !dirtBmp.Scan0) {
Launcher_ExtractTexturePack(&defZipPath); Launcher_ExtractTexturePack(&defZipPath);
} }
} }
static void Launcher_ClearTile(int x, int y, int width, int height, int srcX) { /* Fills the given area using pixels from the source bitmap, by repeatedly tiling the bitmap. */
Drawer2D_BmpTiled(&Launcher_Framebuffer, x, y, width, height, CC_NOINLINE static void Launcher_ClearTile(int x, int y, int width, int height, Bitmap* src) {
&terrainBmp, srcX, 0, TILESIZE, TILESIZE); 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) { void Launcher_ResetArea(int x, int y, int width, int height) {
if (Launcher_ClassicBackground && terrainBmp.Scan0) { if (Launcher_ClassicBackground && dirtBmp.Scan0) {
Launcher_ClearTile(x, y, width, height, 0); Launcher_ClearTile(x, y, width, height, &stoneBmp);
} else { } else {
Gradient_Noise(&Launcher_Framebuffer, Launcher_BackgroundCol, 6, x, y, width, height); Gradient_Noise(&Launcher_Framebuffer, Launcher_BackgroundCol, 6, x, y, width, height);
} }
@ -449,9 +463,9 @@ void Launcher_ResetPixels(void) {
return; return;
} }
if (Launcher_ClassicBackground && terrainBmp.Scan0) { if (Launcher_ClassicBackground && dirtBmp.Scan0) {
Launcher_ClearTile(0, 0, Window_Width, TILESIZE, TILESIZE); Launcher_ClearTile(0, 0, Window_Width, TILESIZE, &dirtBmp);
Launcher_ClearTile(0, TILESIZE, Window_Width, Window_Height - TILESIZE, 0); Launcher_ClearTile(0, TILESIZE, Window_Width, Window_Height - TILESIZE, &stoneBmp);
} else { } else {
Launcher_ResetArea(0, 0, Window_Width, Window_Height); 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) #define Display_CentreY(height) (Display_Bounds.Y + (Display_Bounds.Height - height) / 2)
int Window_Width, Window_Height; int Window_Width, Window_Height;
static int windowX, windowY;
bool Window_Exists, Window_Focused; bool Window_Exists, Window_Focused;
const void* Window_Handle; const void* Window_Handle;
@ -129,7 +128,8 @@ static HINSTANCE win_instance;
static HWND win_handle; static HWND win_handle;
static HDC win_DC; static HDC win_DC;
static bool suppress_resize; 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 }; POINT topLeft = { 0, 0 };
GetWindowRect(win_handle, &rect); GetWindowRect(win_handle, &rect);
win_bounds.X = rect.left; win_bounds.Width = rect.right - rect.left; win_totalWidth = Rect_Width(rect);
win_bounds.Y = rect.top; win_bounds.Height = rect.bottom - rect.top; win_totalHeight = Rect_Height(rect);
GetClientRect(win_handle, &rect); GetClientRect(win_handle, &rect);
Window_Width = rect.right - rect.left; Window_Width = Rect_Width(rect);
Window_Height = rect.bottom - rect.top; Window_Height = Rect_Height(rect);
/* GetClientRect always returns 0,0 for left,top (see MSDN) */ /* GetClientRect always returns 0,0 for left,top (see MSDN) */
ClientToScreen(win_handle, &topLeft); ClientToScreen(win_handle, &topLeft);
@ -193,7 +193,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
{ {
WINDOWPOS* pos = (WINDOWPOS*)lParam; WINDOWPOS* pos = (WINDOWPOS*)lParam;
if (pos->hwnd != win_handle) break; 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(); Window_RefreshBounds();
if (sized && !suppress_resize) Event_RaiseVoid(&WindowEvents.Resized); 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) { 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) { if (width != Window_Width || height != Window_Height) {
Window_Width = width; Window_Width = width;
Window_Height = height; Window_Height = height;
@ -1169,7 +1163,7 @@ static void Cursor_GetRawPos(int* x, int* y) {
} }
void Cursor_SetPosition(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 */ XFlush(win_display); /* TODO: not sure if XFlush call is necessary */
} }
@ -1459,7 +1453,9 @@ void Window_DisableRawMouse(void) { Window_DefaultDisableRawMouse(); }
#include <dlfcn.h> #include <dlfcn.h>
static WindowRef win_handle; static WindowRef win_handle;
static int windowX, windowY;
static bool win_fullscreen; static bool win_fullscreen;
/* fullscreen is tied to OpenGL context unfortunately */ /* fullscreen is tied to OpenGL context unfortunately */
static void GLContext_UnsetFullscreen(void); static void GLContext_UnsetFullscreen(void);
static void GLContext_SetFullscreen(void); static void GLContext_SetFullscreen(void);