diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 40c9819cc..f1b22a97a 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -775,12 +775,17 @@ static void gfx_opengl_set_scissor(int x, int y, int width, int height) { glScissor(x, y, width, height); } -static void gfx_opengl_set_use_alpha(bool use_alpha) { +static void gfx_opengl_set_use_alpha(bool use_alpha, bool modulate) { if (use_alpha) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } + if (modulate) { + glBlendFunc(GL_DST_COLOR, GL_ZERO); + } else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } } static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) { diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 9193c2d47..0e0b39e59 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -204,6 +204,7 @@ static struct RenderingState { float depth_zfar; bool decal_mode; bool alpha_blend; + bool modulate; struct XYWidthHeight viewport, scissor; struct ShaderProgram* shader_program; TextureCacheNode* textures[SHADER_MAX_TEXTURES]; @@ -1279,6 +1280,7 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo bool invisible = (rdp.other_mode_l & (3 << 24)) == (G_BL_0 << 24) && (rdp.other_mode_l & (3 << 20)) == (G_BL_CLR_MEM << 20); bool use_grayscale = rdp.grayscale; + bool use_modulate = use_alpha && (rsp.extra_geometry_mode & G_MODULATE_EXT) != 0; if (texture_edge) { use_alpha = true; @@ -1400,10 +1402,11 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo gfx_rapi->load_shader(prg); rendering_state.shader_program = prg; } - if (use_alpha != rendering_state.alpha_blend) { + if (use_alpha != rendering_state.alpha_blend || use_modulate != rendering_state.modulate) { gfx_flush(); - gfx_rapi->set_use_alpha(use_alpha); + gfx_rapi->set_use_alpha(use_alpha, use_modulate); rendering_state.alpha_blend = use_alpha; + rendering_state.modulate = use_modulate; } uint8_t num_inputs; bool used_textures[2]; diff --git a/port/fast3d/gfx_rendering_api.h b/port/fast3d/gfx_rendering_api.h index b600749c2..69c56fd7b 100644 --- a/port/fast3d/gfx_rendering_api.h +++ b/port/fast3d/gfx_rendering_api.h @@ -32,7 +32,7 @@ struct GfxRenderingAPI { void (*set_zmode_decal)(bool zmode_decal); void (*set_viewport)(int x, int y, int width, int height); void (*set_scissor)(int x, int y, int width, int height); - void (*set_use_alpha)(bool use_alpha); + void (*set_use_alpha)(bool use_alpha, bool modulate); void (*draw_triangles)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris); void (*init)(void); void (*on_resize)(void); diff --git a/src/game/bondview.c b/src/game/bondview.c index 783b68936..461ebc79a 100644 --- a/src/game/bondview.c +++ b/src/game/bondview.c @@ -316,9 +316,16 @@ Gfx *bviewDrawStatic(Gfx *gdl, u32 arg1, s32 arg2) gdl = bviewPrepareStaticI8(gdl, arg1, arg2); +#ifdef PLATFORM_N64 for (y = viewtop; y < viewtop + viewheight; y++) { gdl = bviewCopyPixels(gdl, fb2, random() % 240, 5, y, 1.0f, viewleft, viewwidth); } +#else + gDPSetCombineLERP(gdl++, + NOISE, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT, + NOISE, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT); + gDPFillRectangleEXT(gdl++, viewleft, viewtop, viewleft + viewwidth, viewtop + viewheight); +#endif if (fb2) { // empty @@ -401,6 +408,7 @@ Gfx *bviewDrawFilmInterlace(Gfx *gdl, u32 colour, u32 alpha) gdl = bviewPrepareStaticRgba16(gdl, colour, alpha); +#ifdef PLATFORM_N64 for (y = viewtop; y < viewtop + viewheight; y++) { s32 offsety = y - offset; s32 tmpy = y; @@ -419,6 +427,32 @@ Gfx *bviewDrawFilmInterlace(Gfx *gdl, u32 colour, u32 alpha) gdl = bviewCopyPixels(gdl, fb, tmpy, 5, y, 1, viewleft, viewwidth); } +#else + gDPSetCombineMode(gdl++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetRenderMode(gdl++, G_RM_CLD_SURF, G_RM_CLD_SURF2); + gSPSetExtraGeometryModeEXT(gdl++, G_MODULATE_EXT); + + for (y = viewtop; y < viewtop + viewheight; y++) { + s32 offsety = y - offset; + s32 tmpy = y; + + if (offsety % 6 == 0 || y == viewtop) { + if (offsety % 12 < 6) { + gDPSetPrimColor(gdl++, 0, 0, 0x7f, 0xff, 0xff, 0xff); + } else { + gDPSetPrimColor(gdl++, 0, 0, 0x00, 0xaf, 0xff, 0xff); + } + } + + if (random() % 20 == 1) { + tmpy += random() % 200; + } + + gDPFillRectangle(gdl++, viewleft, tmpy, viewleft + viewwidth, tmpy + 1); + } + + gSPClearExtraGeometryModeEXT(gdl++, G_MODULATE_EXT); +#endif return gdl; } diff --git a/src/include/gbiex.h b/src/include/gbiex.h index 574850299..c3bf9e964 100644 --- a/src/include/gbiex.h +++ b/src/include/gbiex.h @@ -202,6 +202,7 @@ #define G_ASPECT_CENTER_EXT (G_ASPECT_LEFT_EXT | G_ASPECT_RIGHT_EXT) #define G_ASPECT_MODE_EXT G_ASPECT_CENTER_EXT #define G_NO_CLIPPING_EXT 0x00000040 +#define G_MODULATE_EXT 0x00000080 // this should really go into OTHERMODE_H, but for some reason I can't get it to work /* Extended command macros */ diff --git a/src/lib/vi.c b/src/lib/vi.c index a7edc92e8..f76788821 100644 --- a/src/lib/vi.c +++ b/src/lib/vi.c @@ -915,7 +915,7 @@ Gfx *viSetFillColour(Gfx *gdl, s32 r, s32 g, s32 b) if (g_ViIs16Bit) { gDPSetFillColor(gdl++, (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1)); } else { - gDPSetFillColor(gdl++, r << 24 | g << 16 | b << 8 | 0xff); + (gdl++, r << 24 | g << 16 | b << 8 | 0xff); } return gdl;