From 99415a625f22f9f8c2217b920afc90f30846a733 Mon Sep 17 00:00:00 2001 From: plagman Date: Sat, 21 Aug 2010 07:39:12 +0000 Subject: [PATCH] Polymost-style HUD model support for Polymer. It properly displays all HRP HUD models as far as I can tell. git-svn-id: https://svn.eduke32.com/eduke32@1699 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/build.h | 2 +- polymer/eduke32/build/src/engine.c | 4 +- polymer/eduke32/build/src/engine_priv.h | 2 +- polymer/eduke32/build/src/mdsprite.c | 26 +-- polymer/eduke32/build/src/polymer.c | 48 +++- polymer/eduke32/build/src/polymost.c | 278 +++++++++++++----------- 6 files changed, 213 insertions(+), 147 deletions(-) diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index 2f738da86..e3f989bf9 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -189,7 +189,7 @@ EXTERN walltype *wall; EXTERN int16_t maskwall[MAXWALLSB], maskwallcnt; EXTERN int16_t thewall[MAXWALLSB]; EXTERN spritetype *sprite; -EXTERN spritetype *tspriteptr[MAXSPRITESONSCREEN]; +EXTERN spritetype *tspriteptr[MAXSPRITESONSCREEN + 1]; EXTERN int32_t spritesortcnt; EXTERN spritetype *tsprite; diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 05d457774..adb522ed6 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -436,7 +436,7 @@ int16_t maskwall[MAXWALLSB], maskwallcnt; static int32_t spritesx[MAXSPRITESONSCREEN]; static int32_t spritesy[MAXSPRITESONSCREEN+1]; static int32_t spritesz[MAXSPRITESONSCREEN]; -spritetype *tspriteptr[MAXSPRITESONSCREEN]; +spritetype *tspriteptr[MAXSPRITESONSCREEN + 1]; int16_t umost[MAXXDIM], dmost[MAXXDIM]; static int16_t bakumost[MAXXDIM], bakdmost[MAXXDIM]; @@ -5555,7 +5555,7 @@ int32_t preinitengine(void) tsprite = tsprite_s; spriteext = spriteext_s; spritesmooth = spritesmooth_s; - state_compress = (qlz_state_compress *) Bmalloc(sizeof(qlz_state_compress) + sizeof(qlz_state_decompress)); + state_compress = (qlz_state_compress *) Bmalloc(sizeof(qlz_state_compress) + sizeof(qlz_state_decompress)); state_decompress = (qlz_state_decompress *) ((int8_t *)(state_compress) + sizeof(qlz_state_compress)); #endif diff --git a/polymer/eduke32/build/src/engine_priv.h b/polymer/eduke32/build/src/engine_priv.h index d836b793b..3b5ce887d 100644 --- a/polymer/eduke32/build/src/engine_priv.h +++ b/polymer/eduke32/build/src/engine_priv.h @@ -14,7 +14,7 @@ extern int32_t pow2int[32]; extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB]; extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB]; extern int16_t maskwall[MAXWALLSB], maskwallcnt; -extern spritetype *tspriteptr[MAXSPRITESONSCREEN]; +extern spritetype *tspriteptr[MAXSPRITESONSCREEN + 1]; extern int32_t xdimen, xdimenrecip, halfxdimen, xdimenscale, xdimscale, ydimen; extern intptr_t frameoffset; extern int32_t globalposx, globalposy, globalposz, globalhoriz; diff --git a/polymer/eduke32/build/src/mdsprite.c b/polymer/eduke32/build/src/mdsprite.c index 3c9425999..aa690926f 100644 --- a/polymer/eduke32/build/src/mdsprite.c +++ b/polymer/eduke32/build/src/mdsprite.c @@ -1459,23 +1459,23 @@ static inline void invertmatrix(float* m, float* out) { float det; - det = m[0] * (m[4]*m[8] - m[5] * m[7]); - det -= m[1] * (m[3]*m[8] - m[5] * m[6]); + det = m[0] * (m[4]*m[8] - m[5] * m[7]); + det -= m[1] * (m[3]*m[8] - m[5] * m[6]); det += m[2] * (m[3]*m[7] - m[4] * m[6]); det = 1.0f / det; - out[0] = det * (m[4] * m[8] - m[5] * m[7]); - out[3] = det * (m[5] * m[6] - m[3] * m[8]); - out[6] = det * (m[3] * m[7] - m[1] * m[6]); - - out[1] = det * (m[2] * m[7] - m[1] * m[8]); - out[4] = det * (m[0] * m[8] - m[2] * m[6]); - out[7] = det * (m[1] * m[6] - m[0] * m[7]); - - out[2] = det * (m[1] * m[5] - m[2] * m[4]); - out[5] = det * (m[2] * m[3] - m[0] * m[5]); - out[8] = det * (m[0] * m[4] - m[1] * m[3]); + out[0] = det * (m[4] * m[8] - m[5] * m[7]); + out[3] = det * (m[5] * m[6] - m[3] * m[8]); + out[6] = det * (m[3] * m[7] - m[1] * m[6]); + + out[1] = det * (m[2] * m[7] - m[1] * m[8]); + out[4] = det * (m[0] * m[8] - m[2] * m[6]); + out[7] = det * (m[1] * m[6] - m[0] * m[7]); + + out[2] = det * (m[1] * m[5] - m[2] * m[4]); + out[5] = det * (m[2] * m[3] - m[0] * m[5]); + out[8] = det * (m[0] * m[4] - m[1] * m[3]); } static inline void normalize(float* vec) diff --git a/polymer/eduke32/build/src/polymer.c b/polymer/eduke32/build/src/polymer.c index 44c07992c..9a19d2e6f 100644 --- a/polymer/eduke32/build/src/polymer.c +++ b/polymer/eduke32/build/src/polymer.c @@ -3469,7 +3469,7 @@ static void polymer_drawmdsprite(spritetype *tspr) float *v0, *v1; md3surf_t *s; char lpal; - float spos[3], tspos[3], lpos[3], tlpos[3], vec[3], mat[4][4]; + float spos2[3], spos[3], tspos[3], lpos[3], tlpos[3], vec[3], mat[4][4]; float ang; float scale; double det; @@ -3489,9 +3489,28 @@ static void polymer_drawmdsprite(spritetype *tspr) if ((pr_vbos > 1) && (m->indices == NULL)) polymer_loadmodelvbos(m); - spos[0] = (float)tspr->y; - spos[1] = -(float)(tspr->z) / 16.0f; - spos[2] = -(float)tspr->x; + // Hackish, but that means it's a model drawn by rotatesprite. + if (tspriteptr[MAXSPRITESONSCREEN] == tspr) { + float x, y, z; + + spos[0] = (float)globalposy; + spos[1] = -(float)(globalposz) / 16.0f; + spos[2] = -(float)globalposx; + + // The coordinates are actually floats disguised as int in this case + memcpy(&x, &tspr->x, sizeof(float)); + memcpy(&y, &tspr->y, sizeof(float)); + memcpy(&z, &tspr->z, sizeof(float)); + + spos2[0] = (float)y - globalposy; + spos2[1] = -(float)(z - globalposz) / 16.0f; + spos2[2] = -(float)(x - globalposx); + } else { + spos[0] = (float)tspr->y; + spos[1] = -(float)(tspr->z) / 16.0f; + spos[2] = -(float)tspr->x; + } + ang = (float)((tspr->ang+spriteext[tspr->owner].angoff) & 2047) / (2048.0f / 360.0f); ang -= 90.0f; if (((tspr->cstat>>4) & 3) == 2) @@ -3504,8 +3523,22 @@ static void polymer_drawmdsprite(spritetype *tspr) scale *= m->scale; scale *= m->bscale; - bglTranslatef(spos[0], spos[1], spos[2]); - bglRotatef(-ang, 0.0f, 1.0f, 0.0f); + if (tspriteptr[MAXSPRITESONSCREEN] == tspr) { + float radplayerang, cosminusradplayerang, sinminusradplayerang; + + radplayerang = (globalang & 2047) * 2.0f * PI / 2048.0f; + cosminusradplayerang = cos(-radplayerang); + sinminusradplayerang = sin(-radplayerang); + + bglTranslatef(spos[0], spos[1], spos[2]); + bglRotatef(horizang, -cosminusradplayerang, 0.0f, sinminusradplayerang); + bglRotatef(spriteext[tspr->owner].roll / (2048.0f / 360.0f), sinminusradplayerang, 0.0f, cosminusradplayerang); + bglTranslatef(spos2[0], spos2[1], spos2[2]); + bglRotatef(-ang, 0.0f, 1.0f, 0.0f); + } else { + bglTranslatef(spos[0], spos[1], spos[2]); + bglRotatef(-ang, 0.0f, 1.0f, 0.0f); + } if (((tspr->cstat>>4) & 3) == 2) { bglTranslatef(0.0f, 0.0, -(float)(tilesizy[tspr->picnum] * tspr->yrepeat) / 8.0f); @@ -3530,7 +3563,8 @@ static void polymer_drawmdsprite(spritetype *tspr) bglTranslatef(0.0f, 0.0, m->zadd * 64); // scripted model rotation - if (spriteext[tspr->owner].pitch || spriteext[tspr->owner].roll) + if (tspr->owner < MAXSPRITES && + (spriteext[tspr->owner].pitch || spriteext[tspr->owner].roll)) { float pitchang, rollang, offsets[3]; diff --git a/polymer/eduke32/build/src/polymost.c b/polymer/eduke32/build/src/polymost.c index 4df0b0768..9f5c2ce32 100644 --- a/polymer/eduke32/build/src/polymost.c +++ b/polymer/eduke32/build/src/polymost.c @@ -5260,17 +5260,35 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 } } tspr.ang = hudmem[(dastat&4)>>2][picnum].angadd+globalang; - tspr.xrepeat = tspr.yrepeat = 32; if (dastat&4) { x1 = -x1; y1 = -y1; } - tspr.x = (int32_t)(((double)gcosang*z1 - (double)gsinang*x1)*16384.0 + globalposx); - tspr.y = (int32_t)(((double)gsinang*z1 + (double)gcosang*x1)*16384.0 + globalposy); - tspr.z = (int32_t)(globalposz + y1*16384.0*0.8); + + // In Polymost, we don't care if the model is very big + if (rendmode < 4) { + tspr.xrepeat = tspr.yrepeat = 32; + + tspr.x = (int32_t)(((double)gcosang*z1 - (double)gsinang*x1)*16384.0 + globalposx); + tspr.y = (int32_t)(((double)gsinang*z1 + (double)gcosang*x1)*16384.0 + globalposy); + tspr.z = (int32_t)(globalposz + y1*16384.0*0.8); + } else { + float x, y, z; + + tspr.xrepeat = tspr.yrepeat = 5; + + x = (float)(((double)gcosang*z1 - (double)gsinang*x1)*2560.0 + globalposx); + y = (float)(((double)gsinang*z1 + (double)gcosang*x1)*2560.0 + globalposy); + z = (float)(globalposz + y1*2560.0*0.8); + + memcpy(&tspr.x, &x, sizeof(float)); + memcpy(&tspr.y, &y, sizeof(float)); + memcpy(&tspr.z, &z, sizeof(float)); + } tspr.picnum = picnum; tspr.shade = dashade; tspr.pal = dapalnum; tspr.owner = uniqid+MAXSPRITES; globalorientation = (dastat&1)+((dastat&32)<<4)+((dastat&4)<<1); + tspr.cstat = globalorientation; if ((dastat&10) == 2) bglViewport(windowx1,yres-(windowy2+1),windowx2-windowx1+1,windowy2-windowy1+1); @@ -5280,20 +5298,23 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 glox1 = -1; //Force fullscreen (glox1=-1 forces it to restore) } - bglMatrixMode(GL_PROJECTION); - memset(m,0,sizeof(m)); - if ((dastat&10) == 2) + if (rendmode < 4) { - float ratioratio = (float)xdim/ydim; - m[0][0] = (float)ydimen*(ratioratio >= 1.6?1.2:1); m[0][2] = 1.0; - m[1][1] = (float)xdimen; m[1][2] = 1.0; - m[2][2] = 1.0; m[2][3] = (float)ydimen*(ratioratio >= 1.6?1.2:1); - m[3][2] =-1.0; + bglMatrixMode(GL_PROJECTION); + memset(m,0,sizeof(m)); + if ((dastat&10) == 2) + { + float ratioratio = (float)xdim/ydim; + m[0][0] = (float)ydimen*(ratioratio >= 1.6?1.2:1); m[0][2] = 1.0; + m[1][1] = (float)xdimen; m[1][2] = 1.0; + m[2][2] = 1.0; m[2][3] = (float)ydimen*(ratioratio >= 1.6?1.2:1); + m[3][2] =-1.0; + } + else { m[0][0] = m[2][3] = 1.0f; m[1][1] = ((float)xdim)/((float)ydim); m[2][2] = 1.0001f; m[3][2] = 1-m[2][2]; } + bglLoadMatrixf(&m[0][0]); + bglMatrixMode(GL_MODELVIEW); + bglLoadIdentity(); } - else { m[0][0] = m[2][3] = 1.0f; m[1][1] = ((float)xdim)/((float)ydim); m[2][2] = 1.0001f; m[3][2] = 1-m[2][2]; } - bglLoadMatrixf(&m[0][0]); - bglMatrixMode(GL_MODELVIEW); - bglLoadIdentity(); if (hudmem[(dastat&4)>>2][picnum].flags&8) //NODEPTH flag bglDisable(GL_DEPTH_TEST); @@ -5307,22 +5328,31 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 } } -#if 0 - if (!nofog) - { - i = klabs(tspr.shade); - bglFogf(GL_FOG_DENSITY,fogcalc(tspr.shade,sector[tspr.sectnum].visibility); - } - mddraw(&tspr); -#else #ifdef USE_OPENGL if (!nofog) bglDisable(GL_FOG); - mddraw(&tspr); + if (rendmode < 4) + mddraw(&tspr); + else { + tspriteptr[MAXSPRITESONSCREEN] = &tspr; + + bglEnable(GL_ALPHA_TEST); + bglEnable(GL_BLEND); + + spriteext[tspr.owner].roll = a; + + polymer_drawsprite(MAXSPRITESONSCREEN); + + spriteext[tspr.owner].roll = 0; + + bglDisable(GL_BLEND); + bglDisable(GL_ALPHA_TEST); + } + if (!nofog) bglEnable(GL_FOG); #else mddraw(&tspr); #endif -#endif + viewingrange = oldviewingrange; gxyaspect = ogxyaspect; globalshade = ogshade; @@ -5360,6 +5390,7 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 m[0][0] = m[2][3] = 1.0f; m[1][1] = ((float)xdim)/((float)ydim); m[2][2] = 1.0001f; m[3][2] = 1-m[2][2]; bglPushMatrix(); bglLoadMatrixf(&m[0][0]); bglMatrixMode(GL_MODELVIEW); + bglPushMatrix(); bglLoadIdentity(); bglDisable(GL_DEPTH_TEST); @@ -5519,6 +5550,7 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 if (rendmode >= 3) { bglMatrixMode(GL_PROJECTION); bglPopMatrix(); + bglMatrixMode(GL_MODELVIEW); bglPopMatrix(); } #endif @@ -6257,103 +6289,103 @@ Description of Ken's filter to improve LZW compression of DXT1 format by ~15%: ( */ #if defined(POLYMOST) && defined(USE_OPENGL) -int32_t dxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf, char *packbuf, uint32_t miplen) -{ - void *writebuf; - uint32_t j, k, offs, stride, cleng; - char *cptr; - - if ((pict->format == B_LITTLE32(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)) || - (pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT))) { offs = 0; stride = 8; } - else if ((pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)) || - (pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT))) { offs = 8; stride = 16; } - else { offs = 0; stride = 8; } - - if (stride == 16) //If DXT3... - { - //alpha_4x4 - cptr = midbuf; - for (k=0; k<8; k++) *cptr++ = pic[k]; - for (j=stride; (unsigned)j j-1) - { - cleng = j; - writebuf = midbuf; - } - else writebuf = packbuf; - } - else - { - cleng = (miplen/stride)<<3; - writebuf = midbuf; - } - j = B_LITTLE32(cleng); - Bwrite(fil,&j,sizeof(j)); - Bwrite(fil,writebuf,cleng); - } - - //rgb0,rgb1 - cptr = midbuf; - for (k=0; k<=2; k+=2) - for (j=0; (unsigned)j j-1) - { - cleng = j; - writebuf = midbuf; - } - else writebuf = packbuf; - } - else - { - cleng = (miplen/stride)<<2; - writebuf = midbuf; - } - j = B_LITTLE32(cleng); - Bwrite(fil,&j,sizeof(j)); - Bwrite(fil,writebuf,cleng); - - //index_4x4 - cptr = midbuf; - for (j=0; (unsigned)j>0)&3) + (((c2[1]>>0)&3)<<2) + (((c2[2]>>0)&3)<<4) + (((c2[3]>>0)&3)<<6); - cptr[1] = ((c2[0]>>2)&3) + (((c2[1]>>2)&3)<<2) + (((c2[2]>>2)&3)<<4) + (((c2[3]>>2)&3)<<6); - cptr[2] = ((c2[0]>>4)&3) + (((c2[1]>>4)&3)<<2) + (((c2[2]>>4)&3)<<4) + (((c2[3]>>4)&3)<<6); - cptr[3] = ((c2[0]>>6)&3) + (((c2[1]>>6)&3)<<2) + (((c2[2]>>6)&3)<<4) + (((c2[3]>>6)&3)<<6); - cptr += 4; - } - if (glusetexcache == 2) - { - j = (miplen/stride)<<2; - cleng = qlz_compress(midbuf,packbuf,j,state_compress); - if (cleng == 0 || cleng > j-1) - { - cleng = j; - writebuf = midbuf; - } - else writebuf = packbuf; - } - else - { - cleng = (miplen/stride)<<2; - writebuf = midbuf; - } - j = B_LITTLE32(cleng); - Bwrite(fil,&j,sizeof(j)); - Bwrite(fil,writebuf,cleng); - return 0; -} +int32_t dxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf, char *packbuf, uint32_t miplen) +{ + void *writebuf; + uint32_t j, k, offs, stride, cleng; + char *cptr; + + if ((pict->format == B_LITTLE32(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)) || + (pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT))) { offs = 0; stride = 8; } + else if ((pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)) || + (pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT))) { offs = 8; stride = 16; } + else { offs = 0; stride = 8; } + + if (stride == 16) //If DXT3... + { + //alpha_4x4 + cptr = midbuf; + for (k=0; k<8; k++) *cptr++ = pic[k]; + for (j=stride; (unsigned)j j-1) + { + cleng = j; + writebuf = midbuf; + } + else writebuf = packbuf; + } + else + { + cleng = (miplen/stride)<<3; + writebuf = midbuf; + } + j = B_LITTLE32(cleng); + Bwrite(fil,&j,sizeof(j)); + Bwrite(fil,writebuf,cleng); + } + + //rgb0,rgb1 + cptr = midbuf; + for (k=0; k<=2; k+=2) + for (j=0; (unsigned)j j-1) + { + cleng = j; + writebuf = midbuf; + } + else writebuf = packbuf; + } + else + { + cleng = (miplen/stride)<<2; + writebuf = midbuf; + } + j = B_LITTLE32(cleng); + Bwrite(fil,&j,sizeof(j)); + Bwrite(fil,writebuf,cleng); + + //index_4x4 + cptr = midbuf; + for (j=0; (unsigned)j>0)&3) + (((c2[1]>>0)&3)<<2) + (((c2[2]>>0)&3)<<4) + (((c2[3]>>0)&3)<<6); + cptr[1] = ((c2[0]>>2)&3) + (((c2[1]>>2)&3)<<2) + (((c2[2]>>2)&3)<<4) + (((c2[3]>>2)&3)<<6); + cptr[2] = ((c2[0]>>4)&3) + (((c2[1]>>4)&3)<<2) + (((c2[2]>>4)&3)<<4) + (((c2[3]>>4)&3)<<6); + cptr[3] = ((c2[0]>>6)&3) + (((c2[1]>>6)&3)<<2) + (((c2[2]>>6)&3)<<4) + (((c2[3]>>6)&3)<<6); + cptr += 4; + } + if (glusetexcache == 2) + { + j = (miplen/stride)<<2; + cleng = qlz_compress(midbuf,packbuf,j,state_compress); + if (cleng == 0 || cleng > j-1) + { + cleng = j; + writebuf = midbuf; + } + else writebuf = packbuf; + } + else + { + cleng = (miplen/stride)<<2; + writebuf = midbuf; + } + j = B_LITTLE32(cleng); + Bwrite(fil,&j,sizeof(j)); + Bwrite(fil,writebuf,cleng); + return 0; +} int32_t dedxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf, char *packbuf, int32_t ispacked) {