Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
background.c
Go to the documentation of this file.
1#include "common.h"
2#include "model.h"
3#include "gcc/string.h"
4
5char gCloudyFlowerFieldsBg[] = "fla_bg";
6char gSunnyFlowerFieldsBg[] = "flb_bg";
10
13
14void load_map_bg(char* optAssetName) {
15 if (optAssetName != NULL) {
16 UNK_PTR compressedData;
17 u32 assetSize;
18 char* assetName = optAssetName;
19
21 // Use sunny Flower Fields bg rather than cloudy
22 if (strcmp(assetName, gCloudyFlowerFieldsBg) == 0) {
23 assetName = gSunnyFlowerFieldsBg;
24 }
25 }
26
27 compressedData = load_asset_by_name(assetName, &assetSize);
28 decode_yay0(compressedData, &gBackgroundImage);
29 general_heap_free(compressedData);
30 }
31}
32
39
49
50void set_background_size(s16 startX, s16 startY, s16 sizeX, s16 sizeY) {
51 gGameStatusPtr->backgroundFlags &= ~BACKGROUND_FLAG_TEXTURE;
56}
57
58u16 blend_background_channel(u16 arg0, s32 arg1, s32 alpha) {
59 return arg0 + (arg1 - arg0) * alpha / 256;
60}
61
64 u16 flags = 0;
65 s32 fogR, fogG, fogB, fogA;
66 u8 r1, g1, b1, a1;
67 u8 r2, g2, b2;
68 u16 blendedR, blendedG, blendedB;
69 s32 i;
70
71 f32 theta, sinTheta, cosTheta, scrollValue, f5, waveOffset;
72
73 s32 bgMinX;
74 s32 bgMinY;
75 s32 bgMaxX;
76 s32 bgMaxY;
77 s32 lineHeight;
78 s32 numLines;
79 s32 extraHeight;
80
81 s32 bgXOffset;
82 s16 texOffsetY;
83
84 u8* newvar;
85
86 enum {
87 BG_BLEND_NONE = 0,
88 BG_BLEND_HAS_FOG = 1,
89 BG_BLEND_SHOULD_LERP = 2,
90 BG_BLEND_SHOULD_BLEND = 4,
91 };
92
94 get_world_fog_color(&fogR, &fogG, &fogB, &fogA);
95 flags = BG_BLEND_HAS_FOG;
97 }
98
99 switch (*gBackgroundTintModePtr) {
100 case ENV_TINT_NONE:
101 case ENV_TINT_SHROUD:
102 mdl_get_shroud_tint_params(&r1, &g1, &b1, &a1);
103 if (a1 != 0) {
104 flags |= BG_BLEND_SHOULD_LERP;
105 }
106 break;
107 case ENV_TINT_DEPTH:
108 case ENV_TINT_REMAP:
109 default:
110 mdl_get_remap_tint_params(&r1, &g1, &b1, &r2, &g2, &b2);
111 if (!(r1 == 255 && g1 == 255 && b1 == 255 && r2 == 0 && g2 == 0 && b2 == 0)) {
112 flags |= BG_BLEND_SHOULD_BLEND;
113 }
114 break;
115 }
116
117 switch (flags) {
118 case BG_BLEND_NONE:
119 gGameStatusPtr->backgroundFlags &= ~BACKGROUND_FLAG_FOG;
120 break;
121 case BG_BLEND_HAS_FOG:
123 break;
124 case BG_BLEND_SHOULD_LERP:
126 fogR = r1;
127 fogG = g1;
128 fogB = b1;
129 fogA = a1;
130 break;
131 case BG_BLEND_HAS_FOG | BG_BLEND_SHOULD_LERP:
133 fogR = (fogR * (255 - a1) + r1 * a1) / 255;
134 fogG = (fogG * (255 - a1) + g1 * a1) / 255;
135 fogB = (fogB * (255 - a1) + b1 * a1) / 255;
136 fogA = (fogA * (255 - a1) + a1 * a1) / 255;
137 break;
138 case BG_BLEND_SHOULD_BLEND:
140 break;
141 }
142
144 switch (*gBackgroundTintModePtr) {
145 case ENV_TINT_NONE:
146 case ENV_TINT_SHROUD:
147 if (fogA == 255) {
148 for (i = 0; i < ARRAY_COUNT(gBackgroundPalette); i++) {
149 gBackgroundPalette[i] = 1;
150 }
151 } else {
152 // lerp from background palette color to fog color based on fog alpha
153 for (i = 0; i < ARRAY_COUNT(gBackgroundPalette); i++) {
154 // NOTE: values after UNPACK range from [0,31], so we need to shift fog color into that range
155 u16 palColor = gGameStatusPtr->backgroundPalette[i];
156 blendedB = blend_background_channel(UNPACK_PAL_B(palColor), fogB >> 3, fogA);
157 blendedG = blend_background_channel(UNPACK_PAL_G(palColor), fogG >> 3, fogA);
158 blendedR = blend_background_channel(UNPACK_PAL_R(palColor), fogR >> 3, fogA);
159 gBackgroundPalette[i] = blendedB << 1 | blendedG << 6 | blendedR << 11 | 1;
160 }
161 }
162 break;
163 case ENV_TINT_DEPTH:
164 case ENV_TINT_REMAP:
165 default:
166 // the background color channels are remapped from [0,255] -> [min,max]
167 for (i = 0; i < ARRAY_COUNT(gBackgroundPalette); i++) {
168 // NOTE: values after UNPACK range from [0,31], so we need to shift other colors into that range
169 u16 palColor = gGameStatusPtr->backgroundPalette[i];
170 blendedB = (b2 >> 3) + ((UNPACK_PAL_B(palColor) * b1 >> 3) >> 5);
171 blendedG = (g2 >> 3) + ((UNPACK_PAL_G(palColor) * g1 >> 3) >> 5);
172 blendedR = (r2 >> 3) + ((UNPACK_PAL_R(palColor) * r1 >> 3) >> 5);
173
174 if (blendedB > 0x1F) {
175 blendedB = 0x1F;
176 }
177 if (blendedG > 0x1F) {
178 blendedG = 0x1F;
179 }
180 if (blendedR > 0x1F) {
181 blendedR = 0x1F;
182 }
183 gBackgroundPalette[i] = blendedB << 1 | blendedG << 6 | blendedR << 11 | 1;
184 }
185 break;
186 }
187 }
188
189 theta = clamp_angle(-cam->curBoomYaw);
190 sinTheta = sin_deg(theta);
191 cosTheta = cos_deg(theta);
192 f5 = cosTheta * cam->lookAt_obj.x - sinTheta * cam->lookAt_obj.z + cam->leadAmount;
193 scrollValue = -f5 * 0.25f;
194 scrollValue += gGameStatusPtr->backgroundMaxX * theta * (1 / 90.0f);
195
196 if (fabsf(scrollValue - gBackroundLastScrollValue) < 0.3f) {
197 scrollValue = gBackroundLastScrollValue;
198 } else {
199 gBackroundLastScrollValue = scrollValue;
200 }
201
202 while (scrollValue < 0.0f) {
203 scrollValue += gGameStatusPtr->backgroundMaxX * 32;
204 }
205
206 bgXOffset = gGameStatusPtr->backgroundXOffset = ((s32)scrollValue) % gGameStatusPtr->backgroundMaxX;
211
212 gDPPipeSync(gMainGfxPos++);
213 gDPSetCycleType(gMainGfxPos++, G_CYC_COPY);
214 gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE);
215 gDPSetTextureLUT(gMainGfxPos++, G_TT_RGBA16);
216 gDPSetCombineMode(gMainGfxPos++, G_CC_DECALRGB, G_CC_DECALRGB);
217 gDPSetRenderMode(gMainGfxPos++, G_RM_NOOP, G_RM_NOOP2);
218 gDPSetTextureFilter(gMainGfxPos++, G_TF_POINT);
219 gDPPipeSync(gMainGfxPos++);
220
222 gDPLoadTLUT_pal256(gMainGfxPos++, gGameStatusPtr->backgroundPalette);
223 } else {
224 gDPLoadTLUT_pal256(gMainGfxPos++, gBackgroundPalette);
225 }
226
228 lineHeight = 2048 / gGameStatusPtr->backgroundMaxX;
229 numLines = gGameStatusPtr->backgroundMaxY / lineHeight;
230 extraHeight = gGameStatusPtr->backgroundMaxY % lineHeight;
231 for (i = 0; i < numLines; i++) {
232 texOffsetY = gBackroundTextureYOffset + lineHeight * i;
233 if (texOffsetY > gGameStatusPtr->backgroundMaxY) {
234 texOffsetY -= gGameStatusPtr->backgroundMaxY;
235 }
236 gDPLoadTextureTile(gMainGfxPos++, gGameStatusPtr->backgroundRaster + bgMaxX * texOffsetY,
237 G_IM_FMT_CI, G_IM_SIZ_8b, bgMaxX, 6,
238 0, 0, 295, 5, 0,
239 G_TX_WRAP, G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
240
241 gSPTextureRectangle(gMainGfxPos++, bgMinX * 4, (lineHeight * i + bgMinY) * 4,
242 (bgXOffset + bgMinX - 1) * 4, (lineHeight * i + lineHeight - 1 + bgMinY) * 4,
243 G_TX_RENDERTILE, (bgMaxX - bgXOffset) * 32, 0, 4096, 1024);
244 gSPTextureRectangle(gMainGfxPos++, (bgXOffset + bgMinX) * 4, (lineHeight * i + bgMinY) * 4,
245 (bgMaxX + bgMinX - 1) * 4, (lineHeight * i + lineHeight - 1 + bgMinY) * 4,
246 G_TX_RENDERTILE, 0, 0, 4096, 1024);
247 }
248 if (extraHeight != 0) {
249 texOffsetY = gBackroundTextureYOffset + lineHeight * i;
250 if (texOffsetY > gGameStatusPtr->backgroundMaxY) {
251 texOffsetY -= gGameStatusPtr->backgroundMaxY;
252 }
253 gDPLoadTextureTile(gMainGfxPos++, gGameStatusPtr->backgroundRaster + bgMaxX * texOffsetY,
254 G_IM_FMT_CI, G_IM_SIZ_8b, bgMaxX, extraHeight,
255 0, 0, 295, extraHeight - 1, 0,
256 G_TX_WRAP, G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
257 gSPTextureRectangle(gMainGfxPos++, bgMinX * 4, (lineHeight * i + bgMinY) * 4,
258 (bgXOffset + bgMinX - 1) * 4, (bgMaxY - 1 + bgMinY) * 4,
259 G_TX_RENDERTILE, (bgMaxX - bgXOffset) * 32, 0, 4096, 1024);
260 gSPTextureRectangle(gMainGfxPos++, (bgXOffset + bgMinX) * 4, (lineHeight * i + bgMinY) * 4,
261 (bgMaxX + bgMinX - 1) * 4, (bgMaxY - 1 + bgMinY) * 4,
262 G_TX_RENDERTILE, 0, 0, 4096, 1024);
263 }
264 } else {
265 lineHeight = 6;
266 numLines = gGameStatusPtr->backgroundMaxY / lineHeight;
267 extraHeight = gGameStatusPtr->backgroundMaxY % lineHeight;
268 gBackroundWavePhase += TAU / 60; // 60 frames period
269 for (i = 0; i < numLines; i++) {
270 waveOffset = sin_rad(gBackroundWavePhase + i * (TAU / 15)) * 3.0f;
271 bgXOffset = 2.0f * (gGameStatusPtr->backgroundXOffset + waveOffset);
272 texOffsetY = gBackroundTextureYOffset + lineHeight * i;
273 if (texOffsetY > gGameStatusPtr->backgroundMaxY) {
274 texOffsetY -= gGameStatusPtr->backgroundMaxY;
275 }
276 gDPLoadTextureTile(gMainGfxPos++, gGameStatusPtr->backgroundRaster + bgMaxX * texOffsetY,
277 G_IM_FMT_CI, G_IM_SIZ_8b, bgMaxX, 6,
278 0, 0, 295, 5, 0,
279 G_TX_WRAP, G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
280
281 gSPTextureRectangle(gMainGfxPos++, bgMinX * 4, (lineHeight * i + bgMinY) * 4,
282 (2 * bgXOffset + (bgMinX - 1)) * 4, (lineHeight * i + lineHeight - 1 + bgMinY) * 4,
283 G_TX_RENDERTILE, bgMaxX * 32 - bgXOffset * 16, 0, 4096, 1024);
284 gSPTextureRectangle(gMainGfxPos++, bgXOffset * 2 + bgMinX * 4, (lineHeight * i + bgMinY) * 4,
285 (bgMaxX + bgMinX - 1) * 4, (lineHeight * i + lineHeight - 1 + bgMinY) * 4,
286 G_TX_RENDERTILE, 0, 0, 4096, 1024);
287 }
288 if (extraHeight != 0) {
289 waveOffset = sin_rad(gBackroundWavePhase + i * (TAU / 15)) * 3.0f;
290 bgXOffset = 2.0f * (gGameStatusPtr->backgroundXOffset + waveOffset);
291 texOffsetY = gBackroundTextureYOffset + lineHeight * i;
292 if (texOffsetY > gGameStatusPtr->backgroundMaxY) {
293 texOffsetY -= gGameStatusPtr->backgroundMaxY;
294 }
295 gDPLoadTextureTile(gMainGfxPos++, gGameStatusPtr->backgroundRaster + bgMaxX * texOffsetY,
296 G_IM_FMT_CI, G_IM_SIZ_8b, bgMaxX, extraHeight,
297 0, 0, 295, extraHeight - 1, 0,
298 G_TX_WRAP, G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
299 gSPTextureRectangle(gMainGfxPos++, bgMinX * 4, (lineHeight * i + bgMinY) * 4,
300 (2 * bgXOffset + (bgMinX - 1)) * 4, (bgMaxY - 1 + bgMinY) * 4,
301 G_TX_RENDERTILE, bgMaxX * 32 - bgXOffset * 16, 0, 4096, 1024);
302 gSPTextureRectangle(gMainGfxPos++, bgXOffset * 2 + bgMinX * 4, (lineHeight * i + bgMinY) * 4,
303 (bgMaxX + bgMinX - 1) * 4, (bgMaxY - 1 + bgMinY) * 4,
304 G_TX_RENDERTILE, 0, 0, 4096, 1024);
305 }
306 }
307}
308
311}
312
314 gBackroundWaveEnabled = FALSE;
315}
s16 gBackroundTextureYOffset
Definition background.c:8
s8 gBackroundWaveEnabled
Definition background.c:7
char gCloudyFlowerFieldsBg[]
Definition background.c:5
u16 blend_background_channel(u16 arg0, s32 arg1, s32 alpha)
Definition background.c:58
void disable_background_wave(void)
Definition background.c:313
void enable_background_wave(void)
Definition background.c:309
BSS PAL_BIN gBackgroundPalette[256]
Definition background.c:11
void load_map_bg(char *optAssetName)
Definition background.c:14
BSS f32 gBackroundLastScrollValue
Definition background.c:12
void appendGfx_background_texture(void)
Definition background.c:62
char gSunnyFlowerFieldsBg[]
Definition background.c:6
f32 gBackroundWavePhase
Definition background.c:9
void set_background_size(s16 startX, s16 startY, s16 sizeX, s16 sizeY)
Definition background.c:50
void reset_background_settings(void)
Definition background.c:33
void set_background(BackgroundHeader *bg)
Definition background.c:40
u16 * backgroundPalette
#define PAL_BIN
s8 flags
Definition demo_api.c:15
#define sin_deg
#define clamp_angle
#define cos_deg
#define mdl_get_shroud_tint_params
@ BACKGROUND_FLAG_TEXTURE
Definition enums.h:6285
@ BACKGROUND_RENDER_STATE_MASK
Definition enums.h:6290
@ BACKGROUND_FLAG_FOG
Definition enums.h:6286
@ ENV_TINT_SHROUD
Definition enums.h:4387
@ ENV_TINT_DEPTH
Definition enums.h:4389
@ ENV_TINT_REMAP
Definition enums.h:4393
@ ENV_TINT_NONE
Definition enums.h:4385
@ STORY_CH6_DESTROYED_PUFF_PUFF_MACHINE
Definition enums.h:191
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1690
f32 fabsf(f32 f)
void * load_asset_by_name(const char *assetName, u32 *decompressedSize)
Definition world.c:251
s32 is_world_fog_enabled(void)
Definition model.c:3796
s32 general_heap_free(void *data)
Definition heap.c:18
void decode_yay0(void *src, void *dst)
void get_world_fog_color(s32 *r, s32 *g, s32 *b, s32 *a)
Definition model.c:3805
f32 sin_rad(f32 x)
Definition 43F0.c:713
void mdl_get_remap_tint_params(u8 *primR, u8 *primG, u8 *primB, u8 *envR, u8 *envG, u8 *envB)
Definition model.c:3954
@ GB_StoryProgress
#define UNPACK_PAL_B(color)
Definition macros.h:269
#define UNPACK_PAL_R(color)
Definition macros.h:267
#define TAU
Definition macros.h:128
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define UNPACK_PAL_G(color)
Definition macros.h:268
Vec3f lookAt_obj
#define UNK_PTR
Definition types.h:7
BackgroundHeader gBackgroundImage
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
u8 * gBackgroundTintModePtr
Definition model.c:105
s32 gCurrentCameraID
Definition cam_math.c:4