From ba0c93d814e782b7365b6bb1119c6b66c0699f52 Mon Sep 17 00:00:00 2001 From: Sryder13 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 3649db08e..d4ad4a68a 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 6dc0f0f79..43d4537fd 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 b2b517737..18a287ee4 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 d3b3df667..2fc0ba8a0 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 fb012535c..79f7c905e 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); + 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 { @@ -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 666f2e1e2..4389a15d5 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 17cd43629..034c52147 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