From ba0c93d814e782b7365b6bb1119c6b66c0699f52 Mon Sep 17 00:00:00 2001 From: Sryder13 <sryder13@gmail.com> Date: Wed, 19 Mar 2014 23:10:37 +0000 Subject: [PATCH] MD2 & Patch drawing fixes MD2's can be translucent again. MD2's can use sprites instead of another random texture if they have no texture. Patches are drawn in the correct place on non aspect correct resolutions. Cropped Patches are drawn. --- src/doomdef.h | 2 +- src/hardware/hw_draw.c | 70 ++++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_main.c | 39 ++++++----------------- src/hardware/hw_main.h | 1 + src/hardware/hw_md2.c | 40 +++++++++--------------- src/screen.c | 4 +-- src/v_video.c | 3 +- 7 files changed, 100 insertions(+), 59 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 3649db08ea..d4ad4a68a8 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -469,7 +469,7 @@ extern const char *compdate, *comptime, *comprevision; #if !defined (_NDS) && !defined (_PSP) /// Shuffle's incomplete OpenGL sorting code. -//#define SHUFFLE +#define SHUFFLE // This has nothing to do with sorting, why was it disabled? #endif #if !defined (_NDS) && !defined (_PSP) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 6dc0f0f790..43d4537fd3 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -209,6 +209,76 @@ void HWR_DrawSciencePatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, HWD.pfnDrawPolygon(NULL, v, 4, flags); } +void HWR_DrawCroppedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, fixed_t scale, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) +{ + FOutVector v[4]; + FBITFIELD flags; + + float cx = FIXED_TO_FLOAT(x); + float cy = FIXED_TO_FLOAT(y); + +// 3--2 +// | /| +// |/ | +// 0--1 + float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; + float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; + float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(scale); + float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(scale); + + // make patch ready in hardware cache + HWR_GetPatch(gpatch); + + switch (option & V_SCALEPATCHMASK) + { + case V_NOSCALEPATCH: + pdupx = pdupy = 2.0f; + break; + case V_SMALLSCALEPATCH: + pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); + pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); + break; + case V_MEDSCALEPATCH: + pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); + pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); + break; + } + + if (option & V_NOSCALESTART) + sdupx = sdupy = 2.0f; + + v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; + v[2].x = v[1].x = ((cx-sx)*sdupx+(w-gpatch->leftoffset)*pdupx)/vid.width - 1; + v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height; + v[2].y = v[3].y = 1-((cy-sy)*sdupy+(h-gpatch->topoffset)*pdupy)/vid.height; + + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].sow = v[3].sow = ((float)sx/(float)gpatch->height); + v[2].sow = v[1].sow = gpatch->max_s*((float)w/(float)gpatch->width); + v[0].tow = v[1].tow = ((float)sy/(float)gpatch->height); + v[2].tow = v[3].tow = gpatch->max_t*((float)h/(float)gpatch->height); + + flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; + + if (option & V_WRAPX) + flags |= PF_ForceWrapX; + if (option & V_WRAPY) + flags |= PF_ForceWrapY; + + // clip it since it is used for bunny scroll in doom I + if (option & V_TRANSLUCENT) + { + FSurfaceInfo Surf; + Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; + Surf.FlatColor.s.alpha = (UINT8)cv_grtranslucenthud.value; + flags |= PF_Modulated; + HWD.pfnDrawPolygon(&Surf, v, 4, flags); + } + else + HWD.pfnDrawPolygon(NULL, v, 4, flags); +} + void HWR_DrawClippedPatch (GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) { // hardware clips the patch quite nicely anyway :) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b2b5177372..18a287ee4f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1212,23 +1212,17 @@ static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo* if (list[i].caster) { - if (sector->lightlist[i].caster->flags & FF_SOLID && !(cutflag & FF_EXTRA)) - solid = true; - else if (sector->lightlist[i].caster->flags & FF_CUTEXTRA && cutflag & FF_EXTRA) + if (sector->lightlist[i].caster->flags & FF_FOG && cutflag & FF_FOG) // Only fog cuts fog { if (sector->lightlist[i].caster->flags & FF_EXTRA) { - if (sector->lightlist[i].caster->flags == cutflag) + if (sector->lightlist[i].caster->flags == cutflag) // only cut by the same solid = true; } else solid = true; } - else - solid = false; } - else - solid = false; height = FIXED_TO_FLOAT(list[i].height); @@ -3385,30 +3379,17 @@ noshadow: if (sector->numlights) { - INT32 light = R_GetPlaneLight(sector, spr->mobj->z, false); + INT32 light; - if ((sector->lightlist[light].height > (spr->mobj->z + spr->mobj->height)) && !(sector->lightlist[light].flags & FF_NOSHADE)) - { - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); - else - lightlevel = LightLevelToLum(255); + light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } - else // If we can't use the light at its bottom, we'll use the light at its top - { - light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); - - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); - else - lightlevel = LightLevelToLum(255); + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); + else + lightlevel = LightLevelToLum(255); - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } + if (sector->lightlist[light].extra_colormap) + colormap = sector->lightlist[light].extra_colormap; } else { diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index d3b3df6677..2fc0ba8a0d 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -45,6 +45,7 @@ void HWR_SetViewSize(void); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawClippedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawSciencePatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, fixed_t scale); +void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, fixed_t scale, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void HWR_DrawTranslucentPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawSmallPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, const UINT8 *colormap); void HWR_DrawMappedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, const UINT8 *colormap); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index fb012535c9..79f7c905ea 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1087,30 +1087,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (sector->numlights) { - INT32 light = R_GetPlaneLight(sector, spr->mobj->z, false); + INT32 light; - if (sector->lightlist[light].height > (spr->mobj->z + spr->mobj->height)) - { - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); - else - lightlevel = LightLevelToLum(255); - - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } - else // If we can't use the light at its bottom, we'll use the light at its top - { - light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); + light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); - else - lightlevel = LightLevelToLum(255); + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); + else + lightlevel = LightLevelToLum(255); - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } + if (sector->lightlist[light].extra_colormap) + colormap = sector->lightlist[light].extra_colormap; } else { @@ -1156,7 +1143,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { Surf.FlatColor.s.alpha = 0xFF; - blend = PF_Translucent; + blend = PF_Translucent|PF_Occlude; } // dont forget to enabled the depth test because we can't do this like @@ -1164,7 +1151,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) // 1. load model+texture if not already loaded // 2. draw model with correct position, rotation,... - if (spr->mobj->skin) + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) // Use the player MD2 list if the mobj has a skin and is using the player sprites { md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins]; md2->skin = (skin_t*)spr->mobj->skin-skins; @@ -1188,13 +1175,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr) return; } } - HWD.pfnSetBlend(blend); + //HWD.pfnSetBlend(blend); // This seems to actually break translucency? finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy gpatch = md2->grpatch; if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) md2_loadTexture(md2); - else if (gpatch->mipmap.grInfo.format) + + if (gpatch && gpatch->mipmap.grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { // This is safe, since we know the texture has been downloaded HWD.pfnSetTexture(&gpatch->mipmap); @@ -1211,7 +1199,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) buff = md2->model->glCommandBuffer; curr = &md2->model->frames[frame]; if (cv_grmd2.value == 1 - && spr->mobj->state->nextstate != S_NULL + && spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) { const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; diff --git a/src/screen.c b/src/screen.c index 666f2e1e2a..4389a15d57 100644 --- a/src/screen.c +++ b/src/screen.c @@ -227,7 +227,7 @@ void SCR_Startup(void) vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT); vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT); - vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); + //vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); // This was just placing it incorrectly at non aspect correct resolutions vid.meddupx = (UINT8)(vid.dupx >> 1) + 1; vid.meddupy = (UINT8)(vid.dupy >> 1) + 1; @@ -269,7 +269,7 @@ void SCR_Recalc(void) vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT); vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT); - vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); + //vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); // This was just placing it incorrectly at non aspect correct resolutions //vid.baseratio = FixedDiv(vid.height << FRACBITS, BASEVIDHEIGHT << FRACBITS); vid.baseratio = FRACUNIT; diff --git a/src/v_video.c b/src/v_video.c index 17cd436290..034c521476 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1040,8 +1040,9 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, INT32 scrn, patch_t *patch, fixed_ const UINT8 *source, *deststop; #ifdef HWRENDER - // fuck off + // Done if (rendermode != render_soft && rendermode != render_none) + HWR_DrawCroppedPatch((GLPatch_t *)patch, x, y, scrn, science, sx, sy, w, h); return; #endif -- GitLab