Fix 16bpp bitmaps

This commit is contained in:
UnknownShadow200 2024-06-28 16:52:16 +10:00
parent cadf185cee
commit 1383530c4f
18 changed files with 68 additions and 49 deletions

View File

@ -6,15 +6,7 @@
*/
struct Stream;
/* Represents a packed RGBA colour, suitable for 3D graphics API textures and 2D window framebuffers. */
#ifndef BITMAP_16BPP
typedef cc_uint32 BitmapCol;
#define BITMAPCOLOR_SIZE 4
#else
typedef cc_uint16 BitmapCol;
#define BITMAPCOLOR_SIZE 2
#endif
#define BITMAP_16BPP
#if defined CC_BUILD_WEB || defined CC_BUILD_ANDROID || defined CC_BUILD_PSP || defined CC_BUILD_PSVITA || defined CC_BUILD_PS2
#define BITMAPCOLOR_R_SHIFT 0
#define BITMAPCOLOR_G_SHIFT 8
@ -38,6 +30,10 @@ struct Stream;
#endif
#ifndef BITMAP_16BPP
/* Represents a packed RGBA colour, suitable for 3D graphics API textures and 2D window framebuffers. */
typedef cc_uint32 BitmapCol;
#define BITMAPCOLOR_SIZE 4
/* Masks a packed color to the selected component */
#define BITMAPCOLOR_R_MASK (0xFFU << BITMAPCOLOR_R_SHIFT)
#define BITMAPCOLOR_G_MASK (0xFFU << BITMAPCOLOR_G_SHIFT)
@ -56,6 +52,10 @@ struct Stream;
#define BitmapColor_B_Bits(value) ((cc_uint8)(value) << BITMAPCOLOR_B_SHIFT)
#define BitmapColor_A_Bits(value) ((cc_uint8)(value) << BITMAPCOLOR_A_SHIFT)
#else
/* Represents a packed RGBA colour, suitable for 3D graphics API textures and 2D window framebuffers. */
typedef cc_uint16 BitmapCol;
#define BITMAPCOLOR_SIZE 2
/* Masks a packed color to the selected component */
#define BITMAPCOLOR_R_MASK (0x3FU << BITMAPCOLOR_R_SHIFT)
#define BITMAPCOLOR_G_MASK (0x3FU << BITMAPCOLOR_G_SHIFT)
@ -63,9 +63,9 @@ struct Stream;
#define BITMAPCOLOR_A_MASK (0x01U << BITMAPCOLOR_A_SHIFT)
/* Extracts just the R/G/B/A component from a bitmap color */
#define BitmapCol_R(color) (((cc_uint8)(color >> BITMAPCOLOR_R_SHIFT) & 0x3F) << 3)
#define BitmapCol_G(color) (((cc_uint8)(color >> BITMAPCOLOR_G_SHIFT) & 0x3F) << 3)
#define BitmapCol_B(color) (((cc_uint8)(color >> BITMAPCOLOR_B_SHIFT) & 0x3F) << 3)
#define BitmapCol_R(color) (((cc_uint8)(color >> BITMAPCOLOR_R_SHIFT) & 0x1F) << 3)
#define BitmapCol_G(color) (((cc_uint8)(color >> BITMAPCOLOR_G_SHIFT) & 0x1F) << 3)
#define BitmapCol_B(color) (((cc_uint8)(color >> BITMAPCOLOR_B_SHIFT) & 0x1F) << 3)
#define BitmapCol_A(color) (((cc_uint8)(color >> BITMAPCOLOR_A_SHIFT) & 0x01) << 7)
/* Converts input value into a packed color component */

View File

@ -568,7 +568,7 @@
<ClCompile Include="Window_PSP.c" />
<ClCompile Include="Window_PSVita.c" />
<ClCompile Include="Window_Saturn.c" />
<ClCompile Include="Window_SDL.c" />
<ClCompile Include="Window_SDL2.c" />
<ClCompile Include="Window_SDL3.c" />
<ClCompile Include="Window_Switch.c" />
<ClCompile Include="Window_Terminal.c" />

View File

@ -641,9 +641,6 @@
<ClCompile Include="Window_3DS.c">
<Filter>Source Files\Window</Filter>
</ClCompile>
<ClCompile Include="Window_SDL.c">
<Filter>Source Files\Window</Filter>
</ClCompile>
<ClCompile Include="Window_Web.c">
<Filter>Source Files\Window</Filter>
</ClCompile>
@ -788,6 +785,9 @@
<ClCompile Include="LBackend_Android.c">
<Filter>Source Files\Launcher</Filter>
</ClCompile>
<ClCompile Include="Window_SDL2.c">
<Filter>Source Files\Window</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\misc\windows\CCicon.rc">

View File

@ -703,11 +703,12 @@ static CC_INLINE void Game_RenderFrame(void) {
float t;
cc_uint64 render = Stopwatch_Measure();
double delta = Stopwatch_ElapsedMicroseconds(frameStart, render) / (1000.0 * 1000.0);
double deltaD = Stopwatch_ElapsedMicroseconds(frameStart, render) / (1000.0 * 1000.0);
float delta = (float)deltaD;
Window_ProcessEvents(delta);
if (delta > 5.0) delta = 5.0; /* avoid large delta with suspended process */
if (delta <= 0.0) return;
if (delta > 5.0f) delta = 5.0f; /* avoid large delta with suspended process */
if (delta <= 0.0f) return;
frameStart = render;
/* TODO: Should other tasks get called back too? */
@ -727,7 +728,7 @@ static CC_INLINE void Game_RenderFrame(void) {
Gfx_BeginFrame();
Gfx_BindIb(Gfx_defaultIb);
Game.Time += delta;
Game.Time += deltaD;
Game_Vertices = 0;
if (Input.Sources & INPUT_SOURCE_GAMEPAD) Gamepad_Tick(delta);
@ -739,7 +740,7 @@ static CC_INLINE void Game_RenderFrame(void) {
InputHandler_SetFOV(Camera.ZoomFov);
}
PerformScheduledTasks(delta);
PerformScheduledTasks(deltaD);
entTask = tasks[entTaskI];
t = (float)(entTask.accumulator / entTask.interval);
LocalPlayer_SetInterpPosition(Entities.CurPlayer, t);

View File

@ -252,7 +252,7 @@ static void D3D9_SetTextureData(IDirect3DTexture9* texture, struct Bitmap* bmp,
cc_result res = IDirect3DTexture9_LockRect(texture, lvl, &rect, NULL, 0);
if (res) Logger_Abort2(res, "D3D9_LockTextureData");
CopyTextureData(rect.pBits, rect.Pitch, bmp, rowWidth << 2);
CopyTextureData(rect.pBits, rect.Pitch, bmp, rowWidth * BITMAPCOLOR_SIZE);
res = IDirect3DTexture9_UnlockRect(texture, lvl);
if (res) Logger_Abort2(res, "D3D9_UnlockTextureData");
@ -268,7 +268,7 @@ static void D3D9_SetTexturePartData(IDirect3DTexture9* texture, int x, int y, co
res = IDirect3DTexture9_LockRect(texture, lvl, &rect, &part, 0);
if (res) Logger_Abort2(res, "D3D9_LockTexturePartData");
CopyTextureData(rect.pBits, rect.Pitch, bmp, rowWidth << 2);
CopyTextureData(rect.pBits, rect.Pitch, bmp, rowWidth * BITMAPCOLOR_SIZE);
res = IDirect3DTexture9_UnlockRect(texture, lvl);
if (res) Logger_Abort2(res, "D3D9_UnlockTexturePartData");

View File

@ -162,7 +162,8 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
}
} else {
// 32 bpp can just be copied straight across
CopyTextureData(fb->buffer, fb->stride, bmp, rowWidth << 2);
CopyTextureData(fb->buffer, fb->stride,
bmp, rowWidth * BITMAPCOLOR_SIZE);
}

View File

@ -163,7 +163,7 @@ typedef struct CCTexture_ {
cc_uint32 width, height;
cc_uint32 log2_width, log2_height;
cc_uint32 pad[(64 - 16)/4];
cc_uint32 pixels[]; // aligned to 64 bytes (only need 16?)
BitmapCol pixels[]; // aligned to 64 bytes (only need 16?)
} CCTexture;
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
@ -175,7 +175,8 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
tex->log2_width = draw_log2(bmp->width);
tex->log2_height = draw_log2(bmp->height);
CopyTextureData(tex->pixels, bmp->width * 4, bmp, rowWidth << 2);
CopyTextureData(tex->pixels, bmp->width * BITMAPCOLOR_SIZE,
bmp, rowWidth * BITMAPCOLOR_SIZE);
return tex;
}
@ -227,8 +228,10 @@ void Gfx_DeleteTexture(GfxResourceID* texId) {
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
CCTexture* tex = (CCTexture*)texId;
cc_uint32* dst = (tex->pixels + x) + y * tex->width;
CopyTextureData(dst, tex->width * 4, part, rowWidth << 2);
BitmapCol* dst = (tex->pixels + x) + y * tex->width;
CopyTextureData(dst, tex->width * BITMAPCOLOR_SIZE,
part, rowWidth * BITMAPCOLOR_SIZE);
}
void Gfx_EnableMipmaps(void) { }

View File

@ -562,7 +562,8 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
tex->width = bmp->width;
tex->height = bmp->height;
CopyTextureData(tex->pixels, bmp->width * 4, bmp, rowWidth << 2);
CopyTextureData(tex->pixels, bmp->width * BITMAPCOLOR_SIZE,
bmp, rowWidth * BITMAPCOLOR_SIZE);
return tex;
}
@ -613,8 +614,9 @@ void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, i
CCTexture* tex = (CCTexture*)texId;
// NOTE: Only valid for LINEAR textures
cc_uint32* dst = (tex->pixels + x) + y * tex->width;
CopyTextureData(dst, tex->width * 4, part, rowWidth << 2);
BitmapCol* dst = (tex->pixels + x) + y * tex->width;
CopyTextureData(dst, tex->width * BITMAPCOLOR_SIZE,
part, rowWidth * BITMAPCOLOR_SIZE);
rsxInvalidateTextureCache(context, GCM_INVALIDATE_TEXTURE);
/* TODO */

View File

@ -111,7 +111,7 @@ void Gfx_FreeState(void) {
typedef struct CCTexture_ {
cc_uint32 width, height;
cc_uint32 pad1, pad2; // data must be aligned to 16 bytes
cc_uint32 pixels[];
BitmapCol pixels[];
} CCTexture;
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
@ -120,14 +120,17 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
tex->width = bmp->width;
tex->height = bmp->height;
CopyTextureData(tex->pixels, bmp->width * 4, bmp, rowWidth << 2);
CopyTextureData(tex->pixels, bmp->width * BITMAPCOLOR_SIZE,
bmp, rowWidth * BITMAPCOLOR_SIZE);
return tex;
}
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
CCTexture* tex = (CCTexture*)texId;
cc_uint32* dst = (tex->pixels + x) + y * tex->width;
CopyTextureData(dst, tex->width * 4, part, rowWidth << 2);
BitmapCol* dst = (tex->pixels + x) + y * tex->width;
CopyTextureData(dst, tex->width * BITMAPCOLOR_SIZE,
part, rowWidth * BITMAPCOLOR_SIZE);
// TODO: Do line by line and only invalidate the actually changed parts of lines?
sceKernelDcacheWritebackInvalidateRange(dst, (tex->width * part->height) * 4);
}

View File

@ -682,7 +682,8 @@ static void GPUTextures_DeleteUnreferenced(void) {
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
int size = bmp->width * bmp->height * 4;
struct GPUTexture* tex = GPUTexture_Alloc(size);
CopyTextureData(tex->data, bmp->width * 4, bmp, rowWidth << 2);
CopyTextureData(tex->data, bmp->width * BITMAPCOLOR_SIZE,
bmp, rowWidth * BITMAPCOLOR_SIZE);
sceGxmTextureInitLinear(&tex->texture, tex->data,
SCE_GXM_TEXTURE_FORMAT_A8B8G8R8, bmp->width, bmp->height, 0);
@ -697,9 +698,10 @@ void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, i
int texWidth = sceGxmTextureGetWidth(&tex->texture);
// NOTE: Only valid for LINEAR textures
cc_uint32* dst = (tex->data + x) + y * texWidth;
BitmapCol* dst = (tex->data + x) + y * texWidth;
CopyTextureData(dst, texWidth * 4, part, rowWidth << 2);
CopyTextureData(dst, texWidth * BITMAPCOLOR_SIZE,
part, rowWidth * BITMAPCOLOR_SIZE);
// TODO: Do line by line and only invalidate the actually changed parts of lines?
//sceKernelDcacheWritebackInvalidateRange(dst, (tex->width * part->height) * 4);
}

View File

@ -92,14 +92,17 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
tex->width = bmp->width;
tex->height = bmp->height;
CopyTextureData(tex->pixels, bmp->width * 4, bmp, rowWidth << 2);
CopyTextureData(tex->pixels, bmp->width * BITMAPCOLOR_SIZE,
bmp, rowWidth * BITMAPCOLOR_SIZE);
return tex;
}
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
CCTexture* tex = (CCTexture*)texId;
BitmapCol* dst = (tex->pixels + x) + y * tex->width;
CopyTextureData(dst, tex->width * 4, part, rowWidth << 2);
CopyTextureData(dst, tex->width * BITMAPCOLOR_SIZE,
part, rowWidth * BITMAPCOLOR_SIZE);
}
void Gfx_EnableMipmaps(void) { }

View File

@ -104,7 +104,8 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
tex->surface.image = MEMAllocFromDefaultHeapEx(tex->surface.imageSize, tex->surface.alignment);
if (!tex->surface.image) { Mem_Free(tex); return NULL; }
CopyTextureData(tex->surface.image, tex->surface.pitch << 2, bmp, rowWidth << 2);
CopyTextureData(tex->surface.image, tex->surface.pitch << 2,
bmp, rowWidth * BITMAPCOLOR_SIZE);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, tex->surface.image, tex->surface.imageSize);
return tex;
}
@ -113,7 +114,8 @@ void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, i
GX2Texture* tex = (GX2Texture*)texId;
uint32_t* dst = (uint32_t*)tex->surface.image + (y * tex->surface.pitch) + x;
CopyTextureData(dst, tex->surface.pitch << 2, part, rowWidth << 2);
CopyTextureData(dst, tex->surface.pitch << 2,
part, rowWidth * BITMAPCOLOR_SIZE);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, tex->surface.image, tex->surface.imageSize);
}

View File

@ -96,7 +96,8 @@ static void Gfx_RestoreState(void) {
static void SetTextureData(struct XenosSurface* xtex, int x, int y, const struct Bitmap* bmp, int rowWidth, int lvl) {
void* dst = Xe_Surface_LockRect(xe, xtex, x, y, bmp->width, bmp->height, XE_LOCK_WRITE);
CopyTextureData(dst, bmp->width * 4, bmp, rowWidth << 2);
CopyTextureData(dst, bmp->width * BITMAPCOLOR_SIZE,
bmp, rowWidth * BITMAPCOLOR_SIZE);
Xe_Surface_Unlock(xe, xtex);
}

View File

@ -1987,7 +1987,7 @@ static void KeyBindsScreen_OnBindingClick(void* screen, void* widget) {
struct ButtonWidget* btn = (struct ButtonWidget*)widget;
int old = s->curI;
s->curI = btn->meta.val;
s->curI = (int)btn->meta.val;
s->closable = false;
KeyBindsScreen_Update(s, s->curI);

View File

@ -817,7 +817,9 @@ static void DrawGrayscaleGlyph(FT_Bitmap* img, struct Bitmap* bmp, int x, int y,
for (xx = 0; xx < img->width; xx++, src++, dst++) {
if ((unsigned)(x + xx) >= (unsigned)bmp->width) continue;
I = *src; invI = UInt8_MaxValue - I;
if (!I) continue;
/* TODO: Support transparent text */
/* dst->A = ((col.A * intensity) >> 8) + ((dst->A * invIntensity) >> 8);*/

View File

@ -107,7 +107,8 @@ static CC_NOINLINE void UpdateTextureSlow(int x, int y, struct Bitmap* part, int
ptr = Mem_Alloc(count, 4, "Gfx_UpdateTexture temp");
}
CopyTextureData(ptr, part->width << 2, part, rowWidth << 2);
CopyTextureData(ptr, part->width * BITMAPCOLOR_SIZE,
part, rowWidth * BITMAPCOLOR_SIZE);
if (full) {
_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, part->width, part->height, 0, PIXEL_FORMAT, TRANSFER_FORMAT, ptr);

View File

@ -328,7 +328,7 @@ static CC_INLINE void CopyTextureData(void* dst, int dstStride, const struct Bit
} else {
/* Have to copy scanline by scanline */
for (y = 0; y < src->height; y++) {
Mem_Copy(dst_, src_, src->width << 2);
Mem_Copy(dst_, src_, src->width * BITMAPCOLOR_SIZE);
src_ += srcStride;
dst_ += dstStride;
}

View File

@ -73,8 +73,6 @@ static void SetupProgram(int argc, char** argv) {
static int RunProgram(int argc, char** argv) {
cc_string args[GAME_MAX_CMDARGS];
cc_uint16 port;
int argsCount = Platform_GetCommandLineArgs(argc, argv, args);
#ifdef _MSC_VER
/* NOTE: Make sure to comment this out before pushing a commit */
@ -120,7 +118,7 @@ static int RunProgram(int argc, char** argv) {
String_Copy(&Game_Mppass, &args[1]);
String_Copy(&Server.Address,&args[2]);
if (!Convert_ParseInt(&args[3], &Server.Port) || port < 0 || port > 65535) {
if (!Convert_ParseInt(&args[3], &Server.Port) || Server.Port < 0 || Server.Port > 65535) {
WarnInvalidArg("Invalid port", &args[3]);
return 1;
}