From 53335f20ecbaa689240bb631babea91e961f137d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Sep 2019 22:02:45 +0200 Subject: [PATCH] - Blood merge # Conflicts: # source/build/include/polymost.h # source/build/src/build.cpp # source/build/src/engine.cpp # source/build/src/polymost.cpp # source/build/src/voxmodel.cpp --- source/build/include/baselayer.h | 11 +++ source/build/include/build.h | 39 +++++++- source/build/include/buildtypes.h | 13 ++- source/build/include/cache1d.h | 3 + source/build/include/mdsprite.h | 1 + source/build/include/palette.h | 4 + source/build/include/polymost.h | 2 + source/build/include/sdlayer.h | 2 +- source/build/src/baselayer.cpp | 18 ++++ source/build/src/cache1d.cpp | 18 +++- source/build/src/defs.cpp | 24 +++++ source/build/src/engine.cpp | 146 +++++++++++++++++++++++++++-- source/build/src/engine_priv.h | 19 +++- source/build/src/palette.cpp | 62 ++++++++++++- source/build/src/polymost.cpp | 149 ++++++++++++++++++++++++------ source/build/src/sdlayer.cpp | 13 ++- source/build/src/tiles.cpp | 20 ++-- source/build/src/voxmodel.cpp | 113 ++++++++++++++++++++++ source/sw/src/game.cpp | 2 +- 19 files changed, 602 insertions(+), 57 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 052478c47..9f5a2d4b4 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -143,6 +143,14 @@ char CONSTEXPR const g_keyAsciiTable[128] = { 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +char CONSTEXPR const g_keyAsciiTableShift[128] = { + 0 , 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', + '{', '}', 0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', + '>', '?', 0, '*', 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', + '+', '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + extern char keystatus[NUMKEYS]; extern char g_keyFIFO[KEYFIFOSIZ]; extern char g_keyAsciiFIFO[KEYFIFOSIZ]; @@ -218,6 +226,7 @@ void joySetCallback(void (*callback)(int32_t,int32_t)); const char *keyGetName(int32_t num); const char *joyGetName(int32_t what, int32_t num); // what: 0=axis, 1=button, 2=hat +char keyGetScan(void); char keyGetChar(void); #define keyBufferWaiting() (g_keyAsciiPos != g_keyAsciiEnd) @@ -232,6 +241,7 @@ static FORCE_INLINE void keyBufferInsert(char code) g_keyAsciiEnd = ((g_keyAsciiEnd+1)&(KEYFIFOSIZ-1)); } +void keyFlushScans(void); void keyFlushChars(void); void mouseInit(void); @@ -239,6 +249,7 @@ void mouseUninit(void); int32_t mouseReadAbs(vec2_t *pResult, vec2_t const *pInput); void mouseGrabInput(bool grab); void mouseLockToWindow(char a); +void mouseMoveToCenter(void); int32_t mouseReadButtons(void); void mouseReadPos(int32_t *x, int32_t *y); diff --git a/source/build/include/build.h b/source/build/include/build.h index c1063abc4..58634e2c5 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -50,6 +50,8 @@ enum rendmode_t { #define MAXWALLSV7 8192 #define MAXSPRITESV7 4096 +#define MAXVOXMIPS 5 + #if !defined GEKKO && !defined __OPENDINGUX__ # define MAXSECTORS MAXSECTORSV8 # define MAXWALLS MAXWALLSV8 @@ -106,7 +108,7 @@ enum rendmode_t { #define MAXSTATUS 1024 #define MAXPLAYERS 16 // Maximum number of component tiles in a multi-psky: -#define MAXPSKYTILES 8 +#define MAXPSKYTILES 16 #define MAXSPRITESONSCREEN 2560 #define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites @@ -845,6 +847,7 @@ typedef struct { uint8_t num; // animate number int8_t xofs, yofs; uint8_t sf; // anim. speed and flags + uint8_t extra; } picanm_t; EXTERN picanm_t picanm[MAXTILES]; typedef struct { int16_t newtile; int16_t owner; } rottile_t; @@ -1069,7 +1072,7 @@ void tileSetSize(int32_t picnum, int16_t dasizx, int16_t dasizy); int32_t artReadHeader(buildvfs_kfd fil, char const *fn, artheader_t *local); int32_t artReadHeaderFromBuffer(uint8_t const *buf, artheader_t *local); int32_t artCheckUnitFileHeader(uint8_t const *buf, int32_t length); -void tileConvertAnimFormat(int32_t picnum); +void tileConvertAnimFormat(int32_t const picnum, int32_t const picanmdisk); void artReadManifest(buildvfs_kfd fil, artheader_t const *local); void artPreloadFile(buildvfs_kfd fil, artheader_t const *local); int32_t artLoadFiles(const char *filename, int32_t askedsize); @@ -1079,6 +1082,7 @@ bool tileLoad(int16_t tilenume); void tileLoadData(int16_t tilenume, int32_t dasiz, char *buffer); int32_t tileCRC(int16_t tileNum); void artConvertRGB(palette_t *pic, uint8_t const *buf, int32_t bufsizx, int32_t sizx, int32_t sizy); +void tileUpdatePicSiz(int32_t picnum); int32_t qloadkvx(int32_t voxindex, const char *filename); void vox_undefine(int32_t const); @@ -1100,7 +1104,10 @@ void renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz); void renderRestoreTarget(void); void renderPrepareMirror(int32_t dax, int32_t day, fix16_t daang, int16_t dawall, int32_t *tposx, int32_t *tposy, fix16_t *tang); +void renderPrepareMirrorOld(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, + int16_t dawall, int16_t dasector, int32_t *tposx, int32_t *tposy, fix16_t *tang); void renderCompleteMirror(void); +void renderCompleteMirrorOld(void); int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fix16_t daang, fix16_t dahoriz, int16_t dacursectnum); @@ -1155,6 +1162,7 @@ void bfirst_search_try(int16_t * const list, uint8_t * const bitmap, int32_t * c void getzrange(const vec3_t *pos, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz, int32_t *florhit, int32_t walldist, uint32_t cliptype) ATTRIBUTE((nonnull(1,3,4,5,6))); +extern vec2_t hitscangoal; int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz, hitdata_t *hitinfo, uint32_t cliptype) ATTRIBUTE((nonnull(1,6))); void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange, @@ -1164,6 +1172,10 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, int32_t y2, int32_t z2, int16_t sect2); void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) ATTRIBUTE((nonnull(3))); +inline void updatesectorbreadth(int32_t const x, int32_t const y, int16_t *sectnum) ATTRIBUTE((nonnull(3))) +{ + updatesector(x, y, sectnum); +} void updatesectorexclude(int32_t const x, int32_t const y, int16_t * const sectnum, const uint8_t * const excludesectbitmap) ATTRIBUTE((nonnull(3,4))); void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) ATTRIBUTE((nonnull(4))); @@ -1375,6 +1387,10 @@ extern int32_t r_downsize; extern int32_t r_downsizevar; extern int32_t mdtims, omdtims; extern int32_t glrendmode; + +extern int32_t r_rortexture; +extern int32_t r_rortexturerange; +extern int32_t r_rorphase; #endif void hicinit(void); @@ -1552,6 +1568,25 @@ extern int32_t rintersect(int32_t x1, int32_t y1, int32_t z1, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *intx, int32_t *inty, int32_t *intz); +extern int32_t(*animateoffs_replace)(int const tilenum, int fakevar); +extern void(*paletteLoadFromDisk_replace)(void); +extern int32_t(*getpalookup_replace)(int32_t davis, int32_t dashade); +extern void(*initspritelists_replace)(void); +extern int32_t(*insertsprite_replace)(int16_t sectnum, int16_t statnum); +extern int32_t(*deletesprite_replace)(int16_t spritenum); +extern int32_t(*changespritesect_replace)(int16_t spritenum, int16_t newsectnum); +extern int32_t(*changespritestat_replace)(int16_t spritenum, int16_t newstatnum); +extern void(*loadvoxel_replace)(int32_t voxel); +#ifdef USE_OPENGL +extern void(*PolymostProcessVoxels_Callback)(void); +#endif + +extern int32_t automapping; +extern int32_t bloodhack; +extern int32_t blooddemohack; +extern intptr_t voxoff[MAXVOXELS][MAXVOXMIPS]; // used in KenBuild +extern int8_t voxreserve[(MAXVOXELS+7)>>3]; + #ifdef __cplusplus } #endif diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index fafea2146..7d2c7e767 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -165,8 +165,17 @@ typedef struct StructTracker(Sprite, uint8_t) xrepeat, yrepeat; StructTracker(Sprite, int8_t) xoffset, yoffset; StructTracker(Sprite, int16_t) sectnum, statnum; - StructTracker(Sprite, int16_t) ang, owner, xvel, yvel, zvel; - StructTracker(Sprite, int16_t) lotag, hitag; + StructTracker(Sprite, int16_t) ang, owner; + union { + StructTracker(Sprite, int16_t) xvel; + StructTracker(Sprite, int16_t) index; + }; + StructTracker(Sprite, int16_t) yvel, zvel; + union { + StructTracker(Sprite, int16_t) lotag; + StructTracker(Sprite, int16_t) type; + }; + StructTracker(Sprite, int16_t) hitag; StructTracker(Sprite, int16_t) extra; } StructName(spritetypev7); diff --git a/source/build/include/cache1d.h b/source/build/include/cache1d.h index 1a8dc17ea..e9b08b883 100644 --- a/source/build/include/cache1d.h +++ b/source/build/include/cache1d.h @@ -96,10 +96,12 @@ int32_t findfrompath(const char *fn, char **where); buildvfs_kfd openfrompath(const char *fn, int32_t flags, int32_t mode); buildvfs_FILE fopenfrompath(const char *fn, const char *mode); +extern char g_modDir[BMAX_PATH]; extern int32_t numgroupfiles; int initgroupfile(const char *filename); void uninitgroupfile(void); buildvfs_kfd kopen4load(const char *filename, char searchfirst); // searchfirst: 0 = anywhere, 1 = first group, 2 = any group +buildvfs_kfd kopen4loadfrommod(const char *filename, char searchfirst); int32_t kread(buildvfs_kfd handle, void *buffer, int32_t leng); #define kread_and_test(handle, buffer, leng) EDUKE32_PREDICT_FALSE(kread((handle), (buffer), (leng)) != (leng)) int32_t klseek(buildvfs_kfd handle, int32_t offset, int32_t whence); @@ -145,6 +147,7 @@ typedef struct _CACHE1D_FIND_REC { int32_t type, source; struct _CACHE1D_FIND_REC *next, *prev, *usera, *userb; } CACHE1D_FIND_REC; +int32_t klistaddentry(CACHE1D_FIND_REC **rec, const char *name, int32_t type, int32_t source); void klistfree(CACHE1D_FIND_REC *rec); CACHE1D_FIND_REC *klistpath(const char *path, const char *mask, int32_t type); diff --git a/source/build/include/mdsprite.h b/source/build/include/mdsprite.h index e2aa8ed9c..46e463223 100644 --- a/source/build/include/mdsprite.h +++ b/source/build/include/mdsprite.h @@ -221,6 +221,7 @@ EXTERN voxmodel_t *voxmodels[MAXVOXELS]; void voxfree(voxmodel_t *m); voxmodel_t *voxload(const char *filnam); +voxmodel_t *loadkvxfrombuf(const char *buffer, int32_t length); int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr); int md3postload_polymer(md3model_t* m); diff --git a/source/build/include/palette.h b/source/build/include/palette.h index 04780f7e3..b14b0c886 100644 --- a/source/build/include/palette.h +++ b/source/build/include/palette.h @@ -50,6 +50,7 @@ extern palette_t curpalette[256], curpalettefaded[256], palfadergb; extern char palfadedelta; extern void fullscreen_tint_gl(uint8_t r, uint8_t g, uint8_t b, uint8_t f); +extern void fullscreen_tint_gl_blood(void); extern void videoFadeToBlack(int32_t moreopaquep); void paletteMakeLookupTable(int32_t palnum, const char *remapbuf, uint8_t r, uint8_t g, uint8_t b, char noFloorPal); void paletteSetColorTable(int32_t id, uint8_t const *table); @@ -60,6 +61,9 @@ int32_t paletteSetLookupTable(int32_t palnum, const uint8_t *shtab); void paletteFreeLookupTable(int32_t palnum); void videoSetPalette(char dabrightness, uint8_t dapalid, uint8_t flags); void videoFadePalette(uint8_t r, uint8_t g, uint8_t b, uint8_t offset); +#ifdef USE_OPENGL +void videoTintBlood(int32_t r, int32_t g, int32_t b); +#endif extern int32_t realmaxshade; extern float frealmaxshade; diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index 95d374841..6cf1e3ddd 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -6,6 +6,7 @@ #include "baselayer.h" // glinfo #include "glad/glad.h" #include "hightile.h" +#include "mdsprite.h" void Polymost_CacheHitList(uint8_t* hash); @@ -87,6 +88,7 @@ extern uint8_t alphahackarray[MAXTILES]; extern int32_t r_usenewshading; extern int32_t r_npotwallmode; extern int32_t r_brightnesshack; +extern int32_t polymostcenterhoriz; extern int16_t globalpicnum; diff --git a/source/build/include/sdlayer.h b/source/build/include/sdlayer.h index 041ec8209..4bf12c25d 100644 --- a/source/build/include/sdlayer.h +++ b/source/build/include/sdlayer.h @@ -61,7 +61,7 @@ int32_t SDL_WaitEventTimeout(SDL_Event *event, int32_t timeout); } \ } -#define SDL_CHECKMODE(w, h) ((w < MAXXDIM) && (h < MAXYDIM) && (w >= MINXDIM) && (h >= MINYDIM) && (((float)w/(float)h) >= 1.3f)) +#define SDL_CHECKMODE(w, h) ((w < MAXXDIM) && (h < MAXYDIM) && (w >= MINXDIM) && (h >= MINYDIM) && (((float)w/(float)h) >= 1.2f)) #define SDL_CHECKFSMODES(w, h) \ if (w == 0 && h == 0) \ diff --git a/source/build/src/baselayer.cpp b/source/build/src/baselayer.cpp index b23b1ae89..61ed1f973 100644 --- a/source/build/src/baselayer.cpp +++ b/source/build/src/baselayer.cpp @@ -25,6 +25,7 @@ char inputdevices = 0; char keystatus[NUMKEYS]; char g_keyFIFO[KEYFIFOSIZ]; char g_keyAsciiFIFO[KEYFIFOSIZ]; +uint8_t g_keyFIFOpos; uint8_t g_keyFIFOend; uint8_t g_keyAsciiPos; uint8_t g_keyAsciiEnd; @@ -49,6 +50,23 @@ void keySetState(int32_t key, int32_t state) } } +char keyGetScan(void) +{ + if (g_keyFIFOpos == g_keyFIFOend) + return 0; + + char const c = g_keyFIFO[g_keyFIFOpos]; + g_keyFIFOpos = ((g_keyFIFOpos + 2) & (KEYFIFOSIZ - 1)); + + return c; +} + +void keyFlushScans(void) +{ + Bmemset(&g_keyFIFO,0,sizeof(g_keyFIFO)); + g_keyFIFOpos = g_keyFIFOend = 0; +} + // // character-based input functions // diff --git a/source/build/src/cache1d.cpp b/source/build/src/cache1d.cpp index 610539c06..68b1a00b4 100644 --- a/source/build/src/cache1d.cpp +++ b/source/build/src/cache1d.cpp @@ -1092,6 +1092,22 @@ int32_t kopen4load(const char *filename, char searchfirst) return h; } +char g_modDir[BMAX_PATH] = "/"; + +int32_t kopen4loadfrommod(const char *fileName, char searchfirst) +{ + int kFile = -1; + + if (g_modDir[0] != '/' || g_modDir[1] != 0) + { + static char staticFileName[BMAX_PATH]; + Bsnprintf(staticFileName, sizeof(staticFileName), "%s/%s", g_modDir, fileName); + kFile = kopen4load(staticFileName, searchfirst); + } + + return (kFile < 0) ? kopen4load(fileName, searchfirst) : kFile; +} + int32_t kread_internal(int32_t handle, void *buffer, int32_t leng, const uint8_t *arraygrp, const intptr_t *arrayhan, int32_t *arraypos) { int32_t filenum = arrayhan[handle]; @@ -1275,7 +1291,7 @@ static void kclose_grp(int32_t handle) } #endif -static int32_t klistaddentry(CACHE1D_FIND_REC **rec, const char *name, int32_t type, int32_t source) +int32_t klistaddentry(CACHE1D_FIND_REC **rec, const char *name, int32_t type, int32_t source) { CACHE1D_FIND_REC *r = NULL, *attach = NULL; diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 643779774..d22d99782 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -121,6 +121,7 @@ enum scripttoken_t T_DST_COLOR, T_ONE_MINUS_DST_COLOR, T_SHADERED, T_SHADEGREEN, T_SHADEBLUE, T_SHADEFACTOR, + T_RFFDEFINEID, T_IFCRC, }; @@ -402,6 +403,8 @@ static int32_t defsparser(scriptfile *script) { "undefpalookuprange", T_UNDEFPALOOKUPRANGE }, { "undefblendtablerange", T_UNDEFBLENDTABLERANGE }, { "shadefactor", T_SHADEFACTOR }, + + { "rffdefineid", T_RFFDEFINEID }, // dummy }; while (1) @@ -1306,6 +1309,9 @@ static int32_t defsparser(scriptfile *script) if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn))) break; //voxel filename + while (nextvoxid < MAXVOXELS && (voxreserve[nextvoxid>>3]&(1<<(nextvoxid&7)))) + nextvoxid++; + if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS)) { initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS); @@ -1838,6 +1844,9 @@ static int32_t defsparser(scriptfile *script) if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn))) break; //voxel filename + while (nextvoxid < MAXVOXELS && (voxreserve[nextvoxid>>3]&(1<<(nextvoxid&7)))) + nextvoxid++; + if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS)) { initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS); @@ -3634,6 +3643,21 @@ static int32_t defsparser(scriptfile *script) paletteloaded &= ~PALETTE_TRANSLUC; } break; + case T_RFFDEFINEID: + { + char *dummy; + int dummy2; + + if (scriptfile_getstring(script, &dummy)) + break; + if (scriptfile_getstring(script, &dummy)) + break; + if (scriptfile_getnumber(script, &dummy2)) + break; + if (scriptfile_getstring(script, &dummy)) + break; + } + break; default: initprintf("Unknown token.\n"); break; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 3c4d9f143..b8aea2999 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -97,7 +97,7 @@ uint8_t globalr = 255, globalg = 255, globalb = 255; int16_t pskybits_override = -1; -//void loadvoxel(int32_t voxindex) { UNREFERENCED_PARAMATER(voxindex); } +void (*loadvoxel_replace)(int32_t voxindex) = NULL; int16_t tiletovox[MAXTILES]; int32_t usevoxels = 1; #ifdef USE_OPENGL @@ -111,12 +111,12 @@ int32_t novoxmips = 1; #define MAXXSIZ 256 #define MAXYSIZ 256 #define MAXZSIZ 255 -#define MAXVOXMIPS 5 #ifdef EDUKE32_TOUCH_DEVICES # define DISTRECIPSIZ (65536+256) #else # define DISTRECIPSIZ 131072 #endif +int8_t voxreserve[(MAXVOXELS+7)>>3]; intptr_t voxoff[MAXVOXELS][MAXVOXMIPS]; // used in KenBuild static char voxlock[MAXVOXELS][MAXVOXMIPS]; int32_t voxscale[MAXVOXELS]; @@ -341,6 +341,8 @@ static FORCE_INLINE int32_t yax_islockededge(int32_t line, int32_t cf) //// bunch getters/setters int16_t yax_getbunch(int16_t i, int16_t cf) { + if (bloodhack) + return -1; if (editstatus==0) return yax_bunchnum[i][cf]; @@ -417,6 +419,8 @@ void yax_setbunches(int16_t i, int16_t cb, int16_t fb) //// nextwall getters/setters int16_t yax_getnextwall(int16_t wal, int16_t cf) { + if (bloodhack) + return -1; if (editstatus==0) return yax_nextwall[wal][cf]; @@ -1646,7 +1650,14 @@ static inline int findUnusedTile(void) static void classicScanSector(int16_t startsectnum) { if (startsectnum < 0) + { return; + } + + if (automapping) + { + show2dsector[startsectnum>>3] |= pow2char[startsectnum&7]; + } sectorborder[0] = startsectnum; int32_t sectorbordercnt = 1; @@ -2299,8 +2310,14 @@ static void prepwall(int32_t z, uwallptr_t wal) // // animateoffs (internal) // -int32_t animateoffs(int const tilenum) +int32_t (*animateoffs_replace)(int const tilenum, int fakevar) = NULL; +int32_t animateoffs(int const tilenum, int fakevar) { + if (animateoffs_replace) + { + return animateoffs_replace(tilenum, fakevar); + } + int const animnum = picanm[tilenum].num; if (animnum <= 0) @@ -4829,6 +4846,10 @@ static void classicDrawSprite(int32_t snum) cstat |= 512; else cstat &= ~512; + + // Blood's transparency table is inverted + if (bloodhack) + cstat ^= 512; } tspr->cstat = cstat; @@ -5728,14 +5749,15 @@ draw_as_face_sprite: if (lwall[x] < swall[x]) break; if (x == rx) return; } -/* + + if (loadvoxel_replace) for (i=0; i>6); } - if (xdimen != oxdimen && voxoff[0][0]) + if (xdimen != oxdimen +#ifndef PLAYING_BLOOD + && voxoff[0][0] +#endif + ) { if (distrecip == NULL) distrecip = (uint32_t *)Xaligned_alloc(16, DISTRECIPSIZ * sizeof(uint32_t)); @@ -7342,8 +7368,11 @@ LISTFN_STATIC void do_deletespritestat(int16_t deleteme) // // insertsprite // +int32_t(*insertsprite_replace)(int16_t sectnum, int16_t statnum) = NULL; int32_t insertsprite(int16_t sectnum, int16_t statnum) { + if (insertsprite_replace) + return insertsprite_replace(sectnum, statnum); // TODO: guard against bad sectnum? int32_t const newspritenum = insertspritestat(statnum); @@ -7362,8 +7391,11 @@ int32_t insertsprite(int16_t sectnum, int16_t statnum) // // deletesprite // +int32_t (*deletesprite_replace)(int16_t spritenum) = NULL; int32_t deletesprite(int16_t spritenum) { + if (deletesprite_replace) + return deletesprite_replace(spritenum); Bassert((sprite[spritenum].statnum == MAXSTATUS) == (sprite[spritenum].sectnum == MAXSECTORS)); @@ -7395,8 +7427,11 @@ int32_t deletesprite(int16_t spritenum) // // changespritesect // +int32_t (*changespritesect_replace)(int16_t spritenum, int16_t newsectnum) = NULL; int32_t changespritesect(int16_t spritenum, int16_t newsectnum) { + if (changespritesect_replace) + return changespritesect_replace(spritenum, newsectnum); // XXX: NOTE: MAXSECTORS is allowed if ((newsectnum < 0 || newsectnum > MAXSECTORS) || (sprite[spritenum].sectnum == MAXSECTORS)) return -1; @@ -7413,8 +7448,11 @@ int32_t changespritesect(int16_t spritenum, int16_t newsectnum) // // changespritestat // +int32_t (*changespritestat_replace)(int16_t spritenum, int16_t newstatnum) = NULL; int32_t changespritestat(int16_t spritenum, int16_t newstatnum) { + if (changespritestat_replace) + return changespritestat_replace(spritenum, newstatnum); // XXX: NOTE: MAXSTATUS is allowed if ((newstatnum < 0 || newstatnum > MAXSTATUS) || (sprite[spritenum].statnum == MAXSTATUS)) return -1; // can't set the statnum of a sprite not in the world @@ -7919,8 +7957,14 @@ void engineUnInit(void) // // initspritelists // +void (*initspritelists_replace)(void) = NULL; void initspritelists(void) { + if (initspritelists_replace) + { + initspritelists_replace(); + return; + } int32_t i; // initial list state for statnum lists: @@ -8542,7 +8586,7 @@ killsprite: if (tspriteptr[k]->x == tspriteptr[l]->x && tspriteptr[k]->y == tspriteptr[l]->y && (tspriteptr[k]->cstat & 48) == (tspriteptr[l]->cstat & 48) && - tspriteptr[k]->owner < tspriteptr[l]->owner) + (bloodhack ? tspriteptr[k]->statnum < tspriteptr[l]->statnum : tspriteptr[k]->owner < tspriteptr[l]->owner)) { swapptr(&tspriteptr[k], &tspriteptr[l]); vec3_t tv3 = spritesxyz[k]; @@ -8688,7 +8732,11 @@ killsprite: get_wallspr_points((uspriteptr_t)tspr, &xx[0], &xx[1], &yy[0], &yy[1]); +#ifndef PLAYING_BLOOD if ((tspr->cstat & 48) == 0) +#else + if ((tspr->cstat & 48) != 16) +#endif tspriteptr[i]->ang = oang; } @@ -9960,6 +10008,7 @@ static void videoAllocateBuffers(void) } #ifdef USE_OPENGL +void (*PolymostProcessVoxels_Callback)(void) = NULL; static void PolymostProcessVoxels(void) { if (!g_haveVoxels) @@ -11696,6 +11745,46 @@ void renderPrepareMirror(int32_t dax, int32_t day, fix16_t daang, int16_t dawall inpreparemirror = 1; } +static int32_t mirthoriz, mirbakdaz; +static int16_t mirbakdasector; + +void renderPrepareMirrorOld(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, + int16_t dawall, int16_t dasector, int32_t *tposx, int32_t *tposy, fix16_t *tang) +{ + mirrorrender = 1; + const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x-x; + const int32_t y = wall[dawall].y, dy = wall[wall[dawall].point2].y-y; + + const int32_t j = dx*dx + dy*dy; + if (j == 0) + return; + + int i = ((dax-x)*dx + (day-y)*dy)<<1; + + *tposx = (x<<1) + scale(dx,i,j) - dax; + *tposy = (y<<1) + scale(dy,i,j) - day; + *tang = (fix16_from_int(getangle(dx, dy) << 1) - daang) & 0x7FFFFFF; + + if (videoGetRenderMode() != REND_CLASSIC) + { + inpreparemirror = 1; + return; + } + + videoBeginDrawing(); + mirbakdaz = daz; mirbakdasector = dasector; + if ((daz > sector[dasector].ceilingz) && (daz < sector[dasector].floorz)) + { + //Draw pink pixels on horizon to get mirror l&r bounds. + mirthoriz = scale(dahoriz - fix16_from_int(100), windowxy2.x - windowxy1.x, fix16_from_int(320)) + ((windowxy1.y + windowxy2.y) >> 1); + if ((daz << 1) > sector[dasector].ceilingz + sector[dasector].floorz) + mirthoriz--; else mirthoriz++; + mirthoriz = min(max(mirthoriz, windowxy1.y), windowxy2.y); + clearbufbyte((char*)frameplace + ylookup[mirthoriz] + windowxy1.x, windowxy2.x - windowxy1.x + 1, 0xffffffff); + } + videoEndDrawing(); +} + // // completemirror @@ -11755,6 +11844,47 @@ void renderCompleteMirror(void) videoEndDrawing(); } +void renderCompleteMirrorOld(void) +{ + mirrorrender = 0; +#ifdef USE_OPENGL + if (videoGetRenderMode() != REND_CLASSIC) + return; +#endif + + videoBeginDrawing(); + int32_t x1, y1, x2, y2, dy; + char *ptr; + + //Get pink pixels on horizon to get mirror l&r bounds. + x1 = 0; x2 = windowxy2.x - windowxy1.x; + if ((mirbakdaz > sector[mirbakdasector].ceilingz) && (mirbakdaz < sector[mirbakdasector].floorz)) + { + ptr = (char *)frameplace + ylookup[mirthoriz] + windowxy1.x; + while ((ptr[x1] == 255) && (x2 >= x1)) x1++; + while ((ptr[x2] == 255) && (x2 >= x1)) x2--; + if (x1 > 0) x1--; + if (x2 < windowxy2.x - windowxy1.x) x2++; + x2 |= 3; + if (x2 > windowxy2.x - windowxy1.x) x2 = windowxy2.x - windowxy1.x; + } + + if (x2 >= x1) //Flip window x-wise + { + ptr = (char *)frameplace + ylookup[windowxy1.y] + windowxy1.x; + y1 = windowxy2.x - windowxy1.x - x2; x2 -= x1; y2 = x2 + 1; + for (dy = windowxy2.y - windowxy1.y; dy >= 0; dy--) + { + copybufbyte(&ptr[x1 + 1], &tempbuf[0], y2); + tempbuf[x2] = tempbuf[x2 - 1]; + copybufreverse(&tempbuf[x2], &ptr[y1], y2); + ptr += ylookup[1]; + faketimerhandler(); + } + } + videoEndDrawing(); +} + // // sectorofwall diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index 604d4e047..4a135e6bb 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -270,11 +270,18 @@ int32_t wallfront(int32_t l1, int32_t l2); void set_globalang(fix16_t const ang); -int32_t animateoffs(int tilenum); -#define DO_TILE_ANIM(Picnum, Fakevar) do { \ - if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum); \ - if ((((Fakevar) & 16384) == 16384) && (globalorientation & CSTAT_WALL_ROTATE_90) && rottile[Picnum].newtile != -1) Picnum = rottile[Picnum].newtile; \ - } while (0) +int32_t animateoffs(int tilenum, int fakevar); + +template +inline void DO_TILE_ANIM(inttype &Picnum, int Fakevar) +{ +#ifndef PLAYING_BLOOD + if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum); +#else + Picnum += animateoffs(Picnum, Fakevar); +#endif + if (((Fakevar & 16384) == 16384) && (globalorientation & CSTAT_WALL_ROTATE_90) && rottile[Picnum].newtile != -1) Picnum = rottile[Picnum].newtile; +} static FORCE_INLINE int32_t bad_tspr(tspriteptr_t tspr) { @@ -288,6 +295,8 @@ static FORCE_INLINE int32_t bad_tspr(tspriteptr_t tspr) // static FORCE_INLINE int32_t getpalookup(int32_t davis, int32_t dashade) { + if (getpalookup_replace) + return getpalookup_replace(davis, dashade); return min(max(dashade + (davis >> 8), 0), numshades - 1); } diff --git a/source/build/src/palette.cpp b/source/build/src/palette.cpp index 690f59845..195be6cec 100644 --- a/source/build/src/palette.cpp +++ b/source/build/src/palette.cpp @@ -79,6 +79,50 @@ void fullscreen_tint_gl(uint8_t r, uint8_t g, uint8_t b, uint8_t f) glMatrixMode(GL_PROJECTION); glPopMatrix(); } + +int32_t tint_blood_r = 0, tint_blood_g = 0, tint_blood_b = 0; + +void fullscreen_tint_gl_blood(void) +{ + if (!(tint_blood_r|tint_blood_g|tint_blood_b)) + return; + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + polymost_setFogEnabled(false); + + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_BLEND); + + polymost_useColorOnly(true); + glColor4ub(max(tint_blood_r, 0), max(tint_blood_g, 0), max(tint_blood_b, 0), 255); + glBegin(GL_TRIANGLES); + glVertex2f(-2.5f, 1.f); + glVertex2f(2.5f, 1.f); + glVertex2f(.0f, -2.5f); + glEnd(); + glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); + glColor4ub(max(-tint_blood_r, 0), max(-tint_blood_g, 0), max(-tint_blood_b, 0), 255); + glBegin(GL_TRIANGLES); + glVertex2f(-2.5f, 1.f); + glVertex2f(2.5f, 1.f); + glVertex2f(.0f, -2.5f); + glEnd(); + glBlendEquation(GL_FUNC_ADD); + glColor4ub(0,0,0,0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + polymost_useColorOnly(false); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); +} #endif void videoFadeToBlack(int32_t moreopaquep) @@ -142,6 +186,8 @@ static void alloc_palookup(int32_t pal) static void maybe_alloc_palookup(int32_t palnum); +void (*paletteLoadFromDisk_replace)(void) = NULL; + // // loadpalette (internal) // @@ -155,7 +201,12 @@ void paletteLoadFromDisk(void) x = defaultglblend; #endif - buildvfs_kfd fil; + if (paletteLoadFromDisk_replace) + { + paletteLoadFromDisk_replace(); + return; + } + if ((fil = kopen4load("palette.dat", 0)) == buildvfs_kfd_invalid) return; @@ -841,3 +892,12 @@ void videoFadePalette(uint8_t r, uint8_t g, uint8_t b, uint8_t offset) g_lastpalettesum = lastpalettesum = newpalettesum; } + +#ifdef USE_OPENGL +void videoTintBlood(int32_t r, int32_t g, int32_t b) +{ + tint_blood_r = r; + tint_blood_g = g; + tint_blood_b = b; +} +#endif diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 7ca3e6d16..2b74ae563 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -52,11 +52,13 @@ int32_t r_enablepolymost2 = 0; int32_t r_pogoDebug = 0; int32_t r_usenewshading = 4; int32_t r_npotwallmode = 2; +int32_t polymostcenterhoriz = 100; static float gviewxrange; -static float ghoriz; +static float ghoriz, ghoriz2; +static float ghorizcorrect; double gxyaspect; -float gyxscale, ghalfx, grhalfxdown10, grhalfxdown10x; +float gyxscale, ghalfx, grhalfxdown10, grhalfxdown10x, ghalfy; float gcosang, gsinang, gcosang2, gsinang2; float gchang, gshang, gctang, gstang, gvisibility; float gtang = 0.f; @@ -97,6 +99,7 @@ int32_t gltexmiplevel = 0; // discards this many mipmap levels int32_t glprojectionhacks = 1; static FHardwareTexture *polymosttext = 0; int32_t glrendmode = REND_POLYMOST; +int32_t r_shadeinterpolate = 1; // This variable, and 'shadeforfullbrightpass' control the drawing of // fullbright tiles. Also see 'fullbrightloadingpass'. @@ -111,6 +114,12 @@ int32_t r_downsize = 0; int32_t r_downsizevar = -1; int32_t r_brightnesshack = 0; +int32_t r_rortexture = 0; +int32_t r_rortexturerange = 0; +int32_t r_rorphase = 0; + +int32_t r_yshearing = 0; + // used for fogcalc static float fogresult, fogresult2; coltypef fogcol, fogtable[MAXPALOOKUPS]; @@ -185,6 +194,8 @@ static float polymost1RotMatrix[16] = { 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f }; +static GLint polymost1ShadeInterpolateLoc = -1; +static float polymost1ShadeInterpolate = 1.f; static inline float float_trans(uint32_t maskprops, uint8_t blend) { @@ -279,7 +290,7 @@ void gltexapplyprops(void) //-------------------------------------------------------------------------------------------------- -float glox1, gloy1, glox2, gloy2, gloyxscale, gloxyaspect; +float glox1, gloy1, glox2, gloy2, gloyxscale, gloxyaspect, glohoriz2, glohorizcorrect, glotang; //Use this for both initialization and uninitialization of OpenGL. static int32_t gltexcacnum = -1; @@ -496,6 +507,7 @@ static void polymost_setCurrentShaderProgram(uint32_t programID) polymost1NPOTEmulationXOffsetLoc = glGetUniformLocation(polymost1CurrentShaderProgramID, "u_npotEmulationXOffset"); polymost1BrightnessLoc = glGetUniformLocation(polymost1CurrentShaderProgramID, "u_brightness"); polymost1RotMatrixLoc = glGetUniformLocation(polymost1CurrentShaderProgramID, "u_rotMatrix"); + polymost1ShadeInterpolateLoc = glGetUniformLocation(polymost1CurrentShaderProgramID, "u_shadeInterpolate"); //set the uniforms to the current values glUniform4f(polymost1TexturePosSizeLoc, polymost1TexturePosSize.x, polymost1TexturePosSize.y, polymost1TexturePosSize.z, polymost1TexturePosSize.w); @@ -515,6 +527,7 @@ static void polymost_setCurrentShaderProgram(uint32_t programID) glUniform1f(polymost1NPOTEmulationXOffsetLoc, polymost1NPOTEmulationXOffset); glUniform1f(polymost1BrightnessLoc, polymost1Brightness); glUniformMatrix4fv(polymost1RotMatrixLoc, 1, false, polymost1RotMatrix); + glUniform1f(polymost1ShadeInterpolateLoc, polymost1ShadeInterpolate); } void polymost_setTexturePosSize(vec4f_t const &texturePosSize) @@ -663,8 +676,14 @@ void polymost_npotEmulation(char npotEmulation, float factor, float xOffset) glUniform1f(polymost1NPOTEmulationXOffsetLoc, polymost1NPOTEmulationXOffset); } -void polymost_setBrightness(int brightness) +void polymost_shadeInterpolate(int32_t shadeInterpolate) { + if (currentShaderProgramID != polymost1CurrentShaderProgramID || shadeInterpolate == polymost1ShadeInterpolate) + return; + polymost1ShadeInterpolate = shadeInterpolate; + glUniform1f(polymost1ShadeInterpolateLoc, polymost1ShadeInterpolate); +} +void polymost_setBrightness(int brightness){ if (currentShaderProgramID == polymost1CurrentShaderProgramID) { polymost1Brightness = 8.f / (brightness+8.f); @@ -866,6 +885,7 @@ void polymost_glinit() uniform float u_npotEmulationFactor;\n\ uniform float u_npotEmulationXOffset;\n\ uniform float u_brightness;\n\ + uniform float u_shadeInterpolate;\n\ \n\ varying vec4 v_color;\n\ varying float v_distance;\n\ @@ -894,10 +914,15 @@ void polymost_glinit() texCoord = clamp(u_texturePosSize.zw*texCoord, u_halfTexelSize, u_texturePosSize.zw-u_halfTexelSize);\n\ vec4 color = texture2D(s_texture, u_texturePosSize.xy+texCoord);\n\ \n\ - float shade = clamp(floor(u_shade+u_visFactor*v_distance), c_zero, u_numShades-c_one)/u_numShades;\n\ - float colorIndex = texture2D(s_palswap, u_palswapPos+u_palswapSize*vec2(color.r, shade)).r;\n\ + float shade = clamp((u_shade+u_visFactor*v_distance), c_zero, u_numShades-c_one);\n\ + float shadeFrac = mod(shade, c_one);\n\ + float colorIndex = texture2D(s_palswap, u_palswapPos+u_palswapSize*vec2(color.r, floor(shade)/u_numShades)).r;\n\ colorIndex = c_basepalOffset + c_basepalScale*colorIndex;\n\ vec4 palettedColor = texture2D(s_palette, vec2(colorIndex, c_zero));\n\ + colorIndex = texture2D(s_palswap, u_palswapPos+u_palswapSize*vec2(color.r, (floor(shade)+c_one)/u_numShades)).r;\n\ + colorIndex = c_basepalOffset + c_basepalScale*colorIndex;\n\ + vec4 palettedColorNext = texture2D(s_palette, vec2(colorIndex, c_zero));\n\ + palettedColor.rgb = mix(palettedColor.rgb, palettedColorNext.rgb, shadeFrac*u_shadeInterpolate);\n\ float fullbright = mix(u_usePalette*palettedColor.a, c_zero, u_useColorOnly);\n\ palettedColor.a = c_one-floor(color.r);\n\ color = mix(color, palettedColor, u_usePalette);\n\ @@ -953,6 +978,7 @@ void polymost_glinit() uniform float u_npotEmulationFactor;\n\ uniform float u_npotEmulationXOffset;\n\ uniform float u_brightness;\n\ + uniform float u_shadeInterpolate;\n\ \n\ uniform float u_useDetailMapping;\n\ uniform float u_useGlowMapping;\n\ @@ -984,10 +1010,15 @@ void polymost_glinit() texCoord = clamp(u_texturePosSize.zw*texCoord, u_halfTexelSize, u_texturePosSize.zw-u_halfTexelSize);\n\ vec4 color = texture2D(s_texture, u_texturePosSize.xy+texCoord);\n\ \n\ - float shade = clamp(floor(u_shade+u_visFactor*v_distance), c_zero, u_numShades-c_one)/u_numShades;\n\ - float colorIndex = texture2D(s_palswap, u_palswapPos+u_palswapSize*vec2(color.r, shade)).r;\n\ + float shade = clamp((u_shade+u_visFactor*v_distance), c_zero, u_numShades-c_one);\n\ + float shadeFrac = mod(shade, c_one);\n\ + float colorIndex = texture2D(s_palswap, u_palswapPos+u_palswapSize*vec2(color.r, floor(shade)/u_numShades)).r;\n\ colorIndex = c_basepalOffset + c_basepalScale*colorIndex;\n\ vec4 palettedColor = texture2D(s_palette, vec2(colorIndex, c_zero));\n\ + colorIndex = texture2D(s_palswap, u_palswapPos+u_palswapSize*vec2(color.r, (floor(shade)+c_one)/u_numShades)).r;\n\ + colorIndex = c_basepalOffset + c_basepalScale*colorIndex;\n\ + vec4 palettedColorNext = texture2D(s_palette, vec2(colorIndex, c_zero));\n\ + palettedColor.rgb = mix(palettedColor.rgb, palettedColorNext.rgb, shadeFrac*u_shadeInterpolate);\n\ float fullbright = mix(u_usePalette*palettedColor.a, c_zero, u_useColorOnly);\n\ palettedColor.a = c_one-floor(color.r);\n\ color = mix(color, palettedColor, u_usePalette);\n\ @@ -1256,7 +1287,7 @@ void calc_and_apply_fog_factor(int32_t shade, int32_t vis, int32_t pal, float fa static float get_projhack_ratio(void) { - if (glprojectionhacks) + if (glprojectionhacks && !r_yshearing) { float const projhack_zoom = 1.4f * // adjust for the FOV, increasing the FOV reduces the zenith glitch @@ -1303,7 +1334,7 @@ static void resizeglcheck(void) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); #endif - if ((glox1 != windowxy1.x) || (gloy1 != windowxy1.y) || (glox2 != windowxy2.x) || (gloy2 != windowxy2.y) || (gloxyaspect != gxyaspect) || (gloyxscale != gyxscale)) + if ((glox1 != windowxy1.x) || (gloy1 != windowxy1.y) || (glox2 != windowxy2.x) || (gloy2 != windowxy2.y) || (gloxyaspect != gxyaspect) || (gloyxscale != gyxscale) || (glohoriz2 != ghoriz2) || (glohorizcorrect != ghorizcorrect) || (glotang != gtang)) { const int32_t ourxdimen = (windowxy2.x-windowxy1.x+1); float ratio = get_projhack_ratio(); @@ -1327,9 +1358,14 @@ static void resizeglcheck(void) gloxyaspect = gxyaspect; gloyxscale = gyxscale; + glohoriz2 = ghoriz2; + glohorizcorrect = ghorizcorrect; + glotang = gtang; m[0][0] = 1.f; m[1][1] = fxdimen / (fydimen * ratio); + m[2][0] = 2.f * ghoriz2 * gstang / fxdimen; + m[2][1] = 2.f * (ghoriz2 * gctang + ghorizcorrect) / fydimen; m[2][2] = (farclip + nearclip) / (farclip - nearclip); m[2][3] = 1.f; m[3][2] = -(2.f * farclip * nearclip) / (farclip - nearclip); @@ -2576,7 +2612,7 @@ do //update verts vt->SetVertex( (o.x - ghalfx) * r * grhalfxdown10x, - (ghoriz - o.y) * r * grhalfxdown10, + (ghalfy - o.y) * r * grhalfxdown10, r * (1.f / 1024.f)); } @@ -2600,7 +2636,7 @@ do //update verts vt->SetVertex( (px[i] - ghalfx) * r * grhalfxdown10x, - (ghoriz - py[i]) * r * grhalfxdown10, + (ghalfy - py[i]) * r * grhalfxdown10, r * (1.f / 1024.f)); } @@ -4180,15 +4216,25 @@ static void polymost_drawalls(int32_t const bunch) DO_TILE_ANIM(globalpicnum, sectnum); - int32_t dapskybits, dapyoffs, daptileyscale; - int8_t const * dapskyoff = getpsky(globalpicnum, NULL, &dapskybits, &dapyoffs, &daptileyscale); + int32_t dapyscale, dapskybits, dapyoffs, daptileyscale; + int8_t const * dapskyoff = getpsky(globalpicnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale); global_cf_fogpal = sec->fogpal; global_cf_shade = sec->floorshade, global_cf_pal = sec->floorpal; global_cf_z = sec->floorz; // REFACT global_cf_xpanning = sec->floorxpanning; global_cf_ypanning = sec->floorypanning, global_cf_heinum = sec->floorheinum; global_getzofslope_func = &getflorzofslope; - if (!(globalorientation&1)) + if (globalpicnum >= r_rortexture && globalpicnum < r_rortexture + r_rortexturerange && r_rorphase == 0) + { + xtex.d = (ryp0-ryp1)*gxyaspect / (x0-x1); + ytex.d = 0; + otex.d = ryp0*gxyaspect - xtex.d*x0; + + xtex.u = ytex.u = otex.u = 0; + xtex.v = ytex.v = otex.v = 0; + polymost_domost(x0, fy0, x1, fy1); + } + else if (!(globalorientation&1)) { int32_t fz = getflorzofslope(sectnum, globalposx, globalposy); if (globalposz <= fz) @@ -4216,6 +4262,10 @@ static void polymost_drawalls(int32_t const bunch) if (!usehightile || !hicfindskybox(globalpicnum, globalpal)) { + float const ghorizbak = ghoriz; + if (r_yshearing) + ghoriz = (qglobalhoriz*(1.f/65536.f)-float(ydimen>>1))*(dapyscale-65536.f)*(1.f/65536.f)+float(ydimen>>1); + float const dd = fxdimen*.0000001f; //Adjust sky depth based on screen size! float vv[2]; float t = (float)((1<<(picsiz[globalpicnum]&15))<= 0); + + ghoriz = ghorizbak; } else //NOTE: code copied from ceiling code... lots of duplicated stuff :/ { @@ -4509,14 +4561,24 @@ static void polymost_drawalls(int32_t const bunch) DO_TILE_ANIM(globalpicnum, sectnum); - dapskyoff = getpsky(globalpicnum, NULL, &dapskybits, &dapyoffs, &daptileyscale); + dapskyoff = getpsky(globalpicnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale); global_cf_fogpal = sec->fogpal; global_cf_shade = sec->ceilingshade, global_cf_pal = sec->ceilingpal; global_cf_z = sec->ceilingz; // REFACT global_cf_xpanning = sec->ceilingxpanning; global_cf_ypanning = sec->ceilingypanning, global_cf_heinum = sec->ceilingheinum; global_getzofslope_func = &getceilzofslope; - - if (!(globalorientation&1)) + + if (globalpicnum >= r_rortexture && globalpicnum < r_rortexture + r_rortexturerange && r_rorphase == 0) + { + xtex.d = (ryp0-ryp1)*gxyaspect / (x0-x1); + ytex.d = 0; + otex.d = ryp0*gxyaspect - xtex.d*x0; + + xtex.u = ytex.u = otex.u = 0; + xtex.v = ytex.v = otex.v = 0; + polymost_domost(x1, cy1, x0, cy0); + } + else if (!(globalorientation&1)) { int32_t cz = getceilzofslope(sectnum, globalposx, globalposy); if (globalposz >= cz) @@ -4544,6 +4606,10 @@ static void polymost_drawalls(int32_t const bunch) if (!usehightile || !hicfindskybox(globalpicnum, globalpal)) { + float const ghorizbak = ghoriz; + if (r_yshearing) + ghoriz = (qglobalhoriz*(1.f/65536.f)-float(ydimen>>1))*(dapyscale-65536.f)*(1.f/65536.f)+float(ydimen>>1); + float const dd = fxdimen*.0000001f; //Adjust sky depth based on screen size! float vv[2]; float t = (float)((1<<(picsiz[globalpicnum]&15))<= 0); + + ghoriz = ghorizbak; } else { @@ -5079,6 +5147,8 @@ void polymost_scansector(int32_t sectnum) { if (sectnum < 0) return; + if (automapping) show2dsector[sectnum>>3] |= pow2char[sectnum&7]; + sectorborder[0] = sectnum; int sectorbordercnt = 1; do @@ -5337,19 +5407,33 @@ void polymost_drawrooms() gcosang2 = gcosang * (fviewingrange * (1.0f/65536.f)); gsinang2 = gsinang * (fviewingrange * (1.0f/65536.f)); ghalfx = (float)(xdimen>>1); + ghalfy = (float)(ydimen>>1); grhalfxdown10 = 1.f/(ghalfx*1024.f); ghoriz = fix16_to_float(qglobalhoriz); + ghorizcorrect = fix16_to_float((100-polymostcenterhoriz)*divscale16(xdimenscale, viewingrange)); gvisibility = ((float)globalvisibility)*FOGSCALE; - resizeglcheck(); - //global cos/sin height angle - float r = (float)(ydimen>>1) - ghoriz; + if (r_yshearing) + { + gshang = 0.f; + gchang = 1.f; + ghoriz2 = (float)(ydimen>>1)-ghoriz-ghorizcorrect; + } + else + { + float r = (float)(ydimen>>1) - (ghoriz + ghorizcorrect); gshang = r/Bsqrtf(r*r+ghalfx*ghalfx); gchang = Bsqrtf(1.f-gshang*gshang); + ghoriz2 = 0.f; + } ghoriz = (float)(ydimen>>1); + resizeglcheck(); + + polymost_shadeInterpolate(r_shadeinterpolate); + //global cos/sin tilt angle gctang = cosf(gtang); gstang = sinf(gtang); @@ -5364,16 +5448,16 @@ void polymost_drawrooms() gstang = -gstang; //Generate viewport trapezoid (for handling screen up/down) - vec3f_t p[4] = { { 0-1, 0-1, 0 }, - { (float)(windowxy2.x + 1 - windowxy1.x + 2), 0-1, 0 }, - { (float)(windowxy2.x + 1 - windowxy1.x + 2), (float)(windowxy2.y + 1 - windowxy1.y + 2), 0 }, - { 0-1, (float)(windowxy2.y + 1 - windowxy1.y + 2), 0 } }; + vec3f_t p[4] = { { 0-1, 0-1+ghorizcorrect, 0 }, + { (float)(windowxy2.x + 1 - windowxy1.x + 2), 0-1+ghorizcorrect, 0 }, + { (float)(windowxy2.x + 1 - windowxy1.x + 2), (float)(windowxy2.y + 1 - windowxy1.y + 2)+ghorizcorrect, 0 }, + { 0-1, (float)(windowxy2.y + 1 - windowxy1.y + 2)+ghorizcorrect, 0 } }; for (auto & v : p) { //Tilt rotation (backwards) vec2f_t const o = { v.x-ghalfx, v.y-ghoriz }; - vec3f_t const o2 = { o.x*gctang + o.y*gstang, o.y*gctang - o.x*gstang, ghalfx }; + vec3f_t const o2 = { o.x*gctang + o.y*gstang, o.y*gctang - o.x*gstang + ghoriz2, ghalfx }; //Up/down rotation (backwards) v = { o2.x, o2.y * gchang + o2.z * gshang, o2.z * gchang - o2.y * gshang }; @@ -5405,7 +5489,7 @@ void polymost_drawrooms() if (n < 3) { glDepthFunc(GL_LEQUAL); videoEndDrawing(); return; } - float sx[4], sy[4]; + float sx[6], sy[6]; for (bssize_t i = 0; i < n; i++) { @@ -5497,6 +5581,12 @@ void polymost_drawrooms() polymost_drawalls(closest); + if (automapping) + { + for (int z = bunchfirst[closest]; z >= 0; z = bunchp2[z]) + show2dwall[thewall[z] >> 3] |= pow2char[thewall[z] & 7]; + } + numbunches--; bunchfirst[closest] = bunchfirst[numbunches]; bunchlast[closest] = bunchlast[numbunches]; @@ -6712,6 +6802,8 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 globalpal = (int32_t)((uint8_t)dapalnum); float const oghalfx = ghalfx; ghalfx = fxdim * .5f; + float const oghalfy = ghalfy; + ghalfy = fydim * .5f; float const ogrhalfxdown10 = grhalfxdown10; grhalfxdown10 = 1.f / (ghalfx * 1024.f); float const ogrhalfxdown10x = grhalfxdown10x; @@ -6927,6 +7019,7 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 globalshade = ogshade; globalpal = ogpal; ghalfx = oghalfx; + ghalfy = oghalfy; grhalfxdown10 = ogrhalfxdown10; grhalfxdown10x = ogrhalfxdown10x; ghoriz = oghoriz; @@ -7472,6 +7565,8 @@ void polymost_initosdfuncs(void) }, { "r_projectionhack", "enable/disable projection hack", (void *) &glprojectionhacks, CVAR_INT, 0, 1 }, + { "r_shadeinterpolate", "enable/disable shade interpolation", (void *) &r_shadeinterpolate, CVAR_INT, 0, 1 }, + { "r_yshearing", "enable/disable y-shearing", (void*)&r_yshearing, CVAR_INT, 0, 1 }, #ifdef __ANDROID__ diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index caf9bb35a..895a0e48a 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -972,6 +972,12 @@ void mouseLockToWindow(char a) SDL_ShowCursor((osd && osd->flags & OSD_CAPTURE) ? SDL_ENABLE : SDL_DISABLE); } +void mouseMoveToCenter(void) +{ + if (sdl_window) + SDL_WarpMouseInWindow(sdl_window, xdim / 2, ydim / 2); +} + // // setjoydeadzone() -- sets the dead and saturation zones for the joystick // @@ -1709,6 +1715,9 @@ void videoShowFrame(int32_t w) { if (palfadedelta) fullscreen_tint_gl(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); +#ifdef PLAYING_BLOOD + fullscreen_tint_gl_blood(); +#endif #ifdef __ANDROID__ AndroidDrawControls(); @@ -2216,10 +2225,10 @@ int32_t handleevents_pollsdl(void) { if (keyGetState(j)) { - keySetState(j, 0); if (keypresscallback) keypresscallback(j, 0); } + keySetState(j, 0); } } break; @@ -2229,10 +2238,10 @@ int32_t handleevents_pollsdl(void) { if (!keyGetState(code)) { - keySetState(code, 1); if (keypresscallback) keypresscallback(code, 1); } + keySetState(code, 1); } else { diff --git a/source/build/src/tiles.cpp b/source/build/src/tiles.cpp index 7b4203a29..d6b1ebcd7 100644 --- a/source/build/src/tiles.cpp +++ b/source/build/src/tiles.cpp @@ -39,7 +39,8 @@ static char ** g_bakFakeTileData; //static int32_t artsize = 0; static int32_t cachesize = 0; -static char artfilename[20]; +static char artfilename[BMAX_PATH]; +static char artfilenameformat[BMAX_PATH]; static char mapartfilename[BMAX_PATH]; // map-specific ART file name static int32_t mapartfnXXofs; // byte offset to 'XX' (the number part) in the above static int32_t artfilnum, artfilplc; @@ -462,14 +463,19 @@ static const char *artGetIndexedFileName(int32_t tilefilei) } else { - artfilename[7] = '0' + tilefilei%10; - artfilename[6] = '0' + (tilefilei/10)%10; - artfilename[5] = '0' + (tilefilei/100)%10; + Bsnprintf(artfilename, sizeof(artfilename), artfilenameformat, tilefilei); return artfilename; } } + +#ifndef PLAYING_BLOOD +auto kopen4loadfunc = kopen4load; +#else +auto kopen4loadfunc = kopen4loadfrommod; +#endif + // Returns: // 0: successfully read ART file // >0: error with the ART file @@ -481,7 +487,7 @@ static int32_t artReadIndexedFile(int32_t tilefilei) const int32_t permap = (tilefilei >= MAXARTFILES_BASE); // is it a per-map ART file? buildvfs_kfd fil; - if ((fil = kopen4load(fn, 0)) != buildvfs_kfd_invalid) + if ((fil = kopen4loadfunc(fn, 0)) != buildvfs_kfd_invalid) { artheader_t local; int const headerval = artReadHeader(fil, fn, &local); @@ -558,7 +564,7 @@ static int32_t artReadIndexedFile(int32_t tilefilei) // int32_t artLoadFiles(const char *filename, int32_t askedsize) { - Bstrncpyz(artfilename, filename, sizeof(artfilename)); + Bstrncpyz(artfilenameformat, filename, sizeof(artfilenameformat)); Bmemset(&tilesiz[0], 0, sizeof(vec2s_t) * MAXTILES); Bmemset(picanm, 0, sizeof(picanm)); @@ -684,7 +690,7 @@ void tileLoadData(int16_t tilenume, int32_t dasiz, char *buffer) char const *fn = artGetIndexedFileName(tfn); - artfil = kopen4load(fn, 0); + artfil = kopen4loadfunc(fn, 0); if (artfil == buildvfs_kfd_invalid) { diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index 443db0d8e..e9f5c3644 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -894,6 +894,119 @@ voxmodel_t *voxload(const char *filnam) return vm; } +voxmodel_t *loadkvxfrombuf(const char *kvxbuffer, int32_t length) +{ + int32_t i, mip1leng; + + if (!kvxbuffer) + return NULL; + + char *buffer = (char*)Xmalloc(length); + if (!buffer) + return NULL; + + Bmemcpy(buffer, kvxbuffer, length); + + int32_t *longptr = (int32_t*)buffer; + + mip1leng = *longptr++; mip1leng = B_LITTLE32(mip1leng); + if (mip1leng > length - 4) + { + // Invalid KVX file + Bfree(buffer); + return NULL; + } + memcpy(&voxsiz, longptr, sizeof(vec3_t)); + longptr += 3; +#if B_BIG_ENDIAN != 0 + voxsiz.x = B_LITTLE32(voxsiz.x); + voxsiz.y = B_LITTLE32(voxsiz.y); + voxsiz.z = B_LITTLE32(voxsiz.z); +#endif + i = *longptr++; voxpiv.x = (float)B_LITTLE32(i)*(1.f/256.f); + i = *longptr++; voxpiv.y = (float)B_LITTLE32(i)*(1.f/256.f); + i = *longptr++; voxpiv.z = (float)B_LITTLE32(i)*(1.f/256.f); + longptr += voxsiz.x+1; + + const int32_t ysizp1 = voxsiz.y+1; + i = voxsiz.x*ysizp1*sizeof(int16_t); + uint16_t *xyoffs = (uint16_t*)longptr; + + for (i=i/sizeof(int16_t)-1; i>=0; i--) + xyoffs[i] = B_LITTLE16(xyoffs[i]); + + const char *paloff = buffer+length-768; + int32_t pal[256]; + + for (bssize_t i=0; i<256; i++) + { + const char *c = &paloff[i*3]; +//#if B_BIG_ENDIAN != 0 + pal[i] = B_LITTLE32((c[0]<<18) + (c[1]<<10) + (c[2]<<2) + (i<<24)); +//#endif + } + + alloc_vbit(); + + for (vcolhashsizm1=4096; vcolhashsizm1<(mip1leng>>1); vcolhashsizm1<<=1) + { + /* do nothing */ + } + vcolhashsizm1--; //approx to numvoxs! + alloc_vcolhashead(); + + const char *cptr = buffer+28+((voxsiz.x+1)<<2)+((ysizp1*voxsiz.x)<<1); + + for (bssize_t x=0; xmdnum = 1; //VOXel model id + vm->scale = vm->bscale = 1.f; + vm->siz.x = voxsiz.x; vm->siz.y = voxsiz.y; vm->siz.z = voxsiz.z; + vm->piv.x = voxpiv.x; vm->piv.y = voxpiv.y; vm->piv.z = voxpiv.z; + vm->is8bit = 1; + + vm->texid = (uint32_t *)Xcalloc(MAXPALOOKUPS, sizeof(uint32_t)); + } + + DO_FREE_AND_NULL(shcntmal); + DO_FREE_AND_NULL(vbit); + DO_FREE_AND_NULL(vcol); + vnum = vmax = 0; + DO_FREE_AND_NULL(vcolhashead); + Bfree(buffer); + + return vm; +} //Draw voxel model as perfect cubes // Note: This is a hopeless mess that totally forfeits any chance of using a vertex buffer with its messy coordinate adjustments. :( diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 672a08bf5..ef8e063d9 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -1009,7 +1009,7 @@ InitGame(int32_t argc, char const * const * argv) //_outtext("\n\n\n\n\n\n\n\n"); //AnimateCacheCursor(); buildputs("Loading sound and graphics...\n"); - LoadImages("tiles000.art"); + LoadImages("tiles%03d.art"); // Now free it up for later use /*