Skip to content

Commit de9aff6

Browse files
dkosmariDaniel K. O. (dkosmari)
andauthored
Add JPEG support for loading splash screens (#7)
* Added support for loading JPEG images. * Sorted headers. * Formatting for clang-format. --------- Co-authored-by: Daniel K. O. (dkosmari) <none@none>
1 parent 2ad5d0f commit de9aff6

5 files changed

Lines changed: 118 additions & 11 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ CXXFLAGS := $(CFLAGS) -std=c++23 -fno-rtti
3838
ASFLAGS := -g $(ARCH)
3939
LDFLAGS = -g $(ARCH) $(RPXSPECS) --entry=_start -Wl,-Map,$(notdir $*.map)
4040

41-
LIBS := -lpng -lwut -lz
41+
LIBS := -lpng -lturbojpeg -lwut -lz
4242

4343
ifeq ($(DEBUG),1)
4444
CXXFLAGS += -DDEBUG -g

README.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ other modules of the environment are loading.
77
Place the `01_splashscreen.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run the
88
EnvironmentLoader. The module will attempt to load the splash image, in this order:
99
1. `[ENVIRONMENT]/splash.png`
10-
2. `[ENVIRONMENT]/splash.tga`
11-
3. A random image from the directory `[ENVIRONMENT]/splashes/`.
10+
2. `[ENVIRONMENT]/splash.jpg` or `[ENVIRONMENT]/splash.jpeg`
11+
3. `[ENVIRONMENT]/splash.tga`
12+
4. A random image (PNG, JPEG or TGA) from the directory `[ENVIRONMENT]/splashes/`.
1213

13-
If no splash screen is found on the sd card, this module will effectively do nothing.
14+
If no splash image is found on the sd card, this module will effectively do nothing.
1415

1516
**Notes:**
1617
- `[ENVIRONMENT]` is the directory of the environment, for Aroma with would be `sd:/wiiu/enviroments/aroma/splash.png`
@@ -22,14 +23,19 @@ If no splash screen is found on the sd card, this module will effectively do not
2223
### Logging
2324
Building via `make` only logs errors (via OSReport). To enable logging via the [LoggingModule](https://github.com/wiiu-env/LoggingModule) set `DEBUG` to `1` or `VERBOSE`.
2425

25-
`make` Logs errors only (via OSReport).
26-
`make DEBUG=1` Enables information and error logging via [LoggingModule](https://github.com/wiiu-env/LoggingModule).
27-
`make DEBUG=VERBOSE` Enables verbose information and error logging via [LoggingModule](https://github.com/wiiu-env/LoggingModule).
26+
- `make` Logs errors only (via OSReport).
27+
- `make DEBUG=1` Enables information and error logging via [LoggingModule](https://github.com/wiiu-env/LoggingModule).
28+
- `make DEBUG=VERBOSE` Enables verbose information and error logging via [LoggingModule](https://github.com/wiiu-env/LoggingModule).
2829

2930
If the [LoggingModule](https://github.com/wiiu-env/LoggingModule) is not present, it'll fall back to UDP (Port 4405) and [CafeOS](https://github.com/wiiu-env/USBSerialLoggingModule) logging.
3031

3132
## Building
32-
For building, you just need [wut](https://github.com/devkitPro/wut/) installed, then use the `make` command.
33+
For building, you need to install (via devkitPro's `pacman`):
34+
- [wut](https://github.com/devkitPro/wut/)
35+
- ppc-libpng
36+
- ppc-libjpeg-turbo
37+
38+
Then use the `make` command.
3339

3440
## Building using the Dockerfile
3541

source/gfx/JPEGTexture.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include "JPEGTexture.h"
2+
#include <cstdlib>
3+
#include <cstring>
4+
#include <gx2/mem.h>
5+
#include <turbojpeg.h>
6+
7+
GX2Texture *JPEG_LoadTexture(std::span<uint8_t> data) {
8+
GX2Texture *texture = nullptr;
9+
10+
tjhandle handle = tjInitDecompress();
11+
if (!handle) {
12+
return nullptr;
13+
}
14+
15+
int height;
16+
int width;
17+
int subsamp;
18+
int colorspace;
19+
if (tjDecompressHeader3(handle,
20+
data.data(), data.size(),
21+
&width, &height,
22+
&subsamp, &colorspace)) {
23+
goto error;
24+
}
25+
26+
texture = static_cast<GX2Texture *>(std::malloc(sizeof(GX2Texture)));
27+
if (!texture) {
28+
goto error;
29+
}
30+
31+
std::memset(texture, 0, sizeof(GX2Texture));
32+
texture->surface.width = width;
33+
texture->surface.height = height;
34+
texture->surface.depth = 1;
35+
texture->surface.mipLevels = 1;
36+
texture->surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
37+
texture->surface.aa = GX2_AA_MODE1X;
38+
texture->surface.use = GX2_SURFACE_USE_TEXTURE;
39+
texture->surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
40+
texture->surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
41+
texture->surface.swizzle = 0;
42+
texture->viewFirstMip = 0;
43+
texture->viewNumMips = 1;
44+
texture->viewFirstSlice = 0;
45+
texture->viewNumSlices = 1;
46+
texture->compMap = 0x0010203;
47+
GX2CalcSurfaceSizeAndAlignment(&texture->surface);
48+
GX2InitTextureRegs(texture);
49+
50+
if (texture->surface.imageSize == 0) {
51+
goto error;
52+
}
53+
54+
texture->surface.image = std::aligned_alloc(texture->surface.alignment,
55+
texture->surface.imageSize);
56+
if (!texture->surface.image) {
57+
goto error;
58+
}
59+
60+
if (tjDecompress2(handle,
61+
data.data(), data.size(),
62+
static_cast<unsigned char *>(texture->surface.image),
63+
width,
64+
texture->surface.pitch * 4,
65+
height,
66+
TJPF_RGBA,
67+
0)) {
68+
goto error;
69+
}
70+
71+
tjDestroy(handle);
72+
73+
GX2Invalidate(GX2_INVALIDATE_MODE_CPU | GX2_INVALIDATE_MODE_TEXTURE,
74+
texture->surface.image, texture->surface.imageSize);
75+
return texture;
76+
77+
error:
78+
if (texture) {
79+
std::free(texture->surface.image);
80+
}
81+
std::free(texture);
82+
tjDestroy(handle);
83+
return nullptr;
84+
}

source/gfx/JPEGTexture.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <gx2/texture.h>
5+
#include <span>
6+
7+
GX2Texture *JPEG_LoadTexture(std::span<uint8_t> data);

source/gfx/SplashScreenDrawer.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "SplashScreenDrawer.h"
2+
#include "JPEGTexture.h"
23
#include "PNGTexture.h"
34
#include "ShaderSerializer.h"
45
#include "TGATexture.h"
@@ -7,6 +8,7 @@
78
#include "utils/utils.h"
89
#include <cctype>
910
#include <coreinit/time.h>
11+
#include <cstdlib>
1012
#include <gx2/draw.h>
1113
#include <gx2/mem.h>
1214
#include <gx2r/draw.h>
@@ -131,6 +133,8 @@ static GX2Texture *LoadImageAsTexture(const std::filesystem::path &filename) {
131133
auto ext = ToLower(filename.extension());
132134
if (ext == ".png") {
133135
return PNG_LoadTexture(buffer);
136+
} else if (ext == ".jpg" || ext == ".jpeg") {
137+
return JPEG_LoadTexture(buffer);
134138
} else if (ext == ".tga") {
135139
return TGA_LoadTexture(buffer);
136140
}
@@ -140,6 +144,12 @@ static GX2Texture *LoadImageAsTexture(const std::filesystem::path &filename) {
140144

141145
SplashScreenDrawer::SplashScreenDrawer(const std::filesystem::path &splash_base_path) {
142146
mTexture = LoadImageAsTexture(splash_base_path / "splash.png");
147+
if (!mTexture) {
148+
mTexture = LoadImageAsTexture(splash_base_path / "splash.jpg");
149+
}
150+
if (!mTexture) {
151+
mTexture = LoadImageAsTexture(splash_base_path / "splash.jpeg");
152+
}
143153
if (!mTexture) {
144154
mTexture = LoadImageAsTexture(splash_base_path / "splash.tga");
145155
}
@@ -152,7 +162,7 @@ SplashScreenDrawer::SplashScreenDrawer(const std::filesystem::path &splash_base_
152162
continue;
153163
}
154164
auto ext = ToLower(entry.path().extension());
155-
if (ext == ".png" || ext == ".tga") {
165+
if (ext == ".png" || ext == ".tga" || ext == ".jpg" || ext == ".jpeg") {
156166
candidates.push_back(entry.path());
157167
}
158168
}
@@ -241,10 +251,10 @@ SplashScreenDrawer::~SplashScreenDrawer() {
241251
GX2RDestroyBufferEx(&mTexCoordBuffer, GX2R_RESOURCE_BIND_NONE);
242252
if (mTexture) {
243253
if (mTexture->surface.image != nullptr) {
244-
free(mTexture->surface.image);
254+
std::free(mTexture->surface.image);
245255
mTexture->surface.image = nullptr;
246256
}
247-
::free(mTexture);
257+
std::free(mTexture);
248258
mTexture = nullptr;
249259
}
250260
}

0 commit comments

Comments
 (0)