diff --git a/CMakeLists.txt b/CMakeLists.txt index c02d52ac1..249113a75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -236,7 +236,7 @@ if( MSVC ) set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd" ) # Disable warnings for unsecure CRT functions from VC8+ - set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996 /DUNICODE /D_UNICODE /D_WIN32_WINNT=0x0600" ) + set( ALL_C_FLAGS "${ALL_C_FLAGS} /DUNICODE /D_UNICODE /D_WIN32_WINNT=0x0600 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS" ) # These must be silenced because the code is full of them. Expect some of undefined behavior hidden in this mess. :( #set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4244 /wd4018 /wd4267" ) @@ -287,7 +287,7 @@ else() if( APPLE ) - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9") + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12") if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" ) # If we're compiling with a custom GCC on the Mac (which we know since g++-4.2 doesn't support C++11) statically link libgcc. set( ALL_C_FLAGS "-static-libgcc" ) diff --git a/libraries/bzip2/CMakeLists.txt b/libraries/bzip2/CMakeLists.txt index 6ca7a4e6d..452954c8a 100644 --- a/libraries/bzip2/CMakeLists.txt +++ b/libraries/bzip2/CMakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required( VERSION 3.1.0 ) make_release_only() +if (MSVC) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4244" ) +endif() + add_definitions( -DBZ_NO_STDIO ) add_library( bz2 STATIC blocksort.c diff --git a/libraries/glslang/glslang/CMakeLists.txt b/libraries/glslang/glslang/CMakeLists.txt index 30b57c588..3ca4c1ce4 100644 --- a/libraries/glslang/glslang/CMakeLists.txt +++ b/libraries/glslang/glslang/CMakeLists.txt @@ -21,6 +21,10 @@ elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over. endif() +if (MSVC) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4146" ) +endif() + # Request C++11 if(${CMAKE_VERSION} VERSION_LESS 3.1) # CMake versions before 3.1 do not understand CMAKE_CXX_STANDARD diff --git a/libraries/jpeg/CMakeLists.txt b/libraries/jpeg/CMakeLists.txt index 40bc7004b..43ecdac39 100644 --- a/libraries/jpeg/CMakeLists.txt +++ b/libraries/jpeg/CMakeLists.txt @@ -6,6 +6,10 @@ if( DEM_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -fomit-frame-pointer" ) endif() +if (MSVC) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4267" ) +endif() + add_library( jpeg STATIC jaricom.c jcomapi.c diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 51784dbac..70b79a62f 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -688,7 +688,7 @@ set( NOT_COMPILED_SOURCE_FILES zcc-parse.c zcc-parse.h common/platform/win32/zutil.natvis - + common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.natvis games/blood/src/_polymost.cpp games/duke/src/_polymost.cpp games/sw/src/_polymost.cpp diff --git a/source/build/include/build.h b/source/build/include/build.h index 4107391a6..1adcf21b5 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -28,7 +28,7 @@ static_assert('\xff' == 255, "Char must be unsigned!"); # define EXTERN extern #endif -EXTERN int16_t sintable[2048]; +EXTERN int sintable[2048]; #include "buildtiles.h" #include "c_cvars.h" @@ -154,6 +154,32 @@ extern walltype wall[MAXWALLS]; extern spritetype sprite[MAXSPRITES]; EXTERN int leveltimer; +inline sectortype* spritetype::sector() const +{ + return &::sector[sectnum]; +} + +inline sectortype* walltype::nextSector() const +{ + return &::sector[nextsector]; +} + +inline walltype* walltype::nextWall() const +{ + return &::wall[nextwall]; +} + +inline walltype* walltype::point2Wall() const +{ + return &::wall[point2]; +} + +inline walltype* sectortype::firstWall() const +{ + return &wall[wallptr]; +} + + extern sectortype sectorbackup[MAXSECTORS]; extern walltype wallbackup[MAXWALLS]; @@ -187,6 +213,16 @@ EXTERN int32_t Numsprites; EXTERN int16_t numsectors, numwalls; EXTERN int32_t display_mirror; +inline bool validSectorIndex(int sectnum) +{ + return sectnum >= 0 && sectnum < numsectors; +} + +inline bool validWallIndex(int wallnum) +{ + return wallnum >= 0 && wallnum < numwalls; +} + EXTERN int32_t randomseed; EXTERN uint8_t paletteloaded; @@ -343,7 +379,8 @@ int32_t engineInit(void); void engineUnInit(void); void initspritelists(void); -void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum); +void ValidateSprite(spritetype& spr); +void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *daang, int *dacursectnum); void loadMapBackup(const char* filename); void G_LoadMapHack(const char* filename, const unsigned char*); @@ -392,17 +429,18 @@ 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); int32_t inside(int32_t x, int32_t y, int sectnum); -void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0); +void dragpoint(int pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0); int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in, int32_t vx, int32_t vy, int32_t vz, vec3_t * const intp, int32_t strictly_smaller_than_p); #define MAXUPDATESECTORDIST 1536 #define INITIALUPDATESECTORDIST 256 -void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) ATTRIBUTE((nonnull(3))); -void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) ATTRIBUTE((nonnull(4))); -void updatesectorneighbor(int32_t const x, int32_t const y, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(3))); -void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4))); +void updatesector(int const x, int const y, int * const sectnum) ATTRIBUTE((nonnull(3))); +void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int * const sectnum) ATTRIBUTE((nonnull(4))); + +void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(3))); +void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4))); int findwallbetweensectors(int sect1, int sect2); inline int sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; } @@ -427,12 +465,6 @@ inline constexpr uint32_t uhypsq(int32_t const dx, int32_t const dy) return (uint32_t)dx*dx + (uint32_t)dy*dy; } -inline int32_t logapproach(int32_t const val, int32_t const targetval) -{ - int32_t const dif = targetval - val; - return (dif>>1) ? val + (dif>>1) : targetval; -} - void rotatepoint(vec2_t const pivot, vec2_t p, int16_t const daang, vec2_t * const p2) ATTRIBUTE((nonnull(4))); inline void rotatepoint(int px, int py, int ptx, int pty, int daang, int* resx, int* resy) { @@ -446,6 +478,17 @@ inline void rotatepoint(int px, int py, int ptx, int pty, int daang, int* resx, int32_t lastwall(int16_t point); int32_t nextsectorneighborz(int16_t sectnum, int32_t refz, int16_t topbottom, int16_t direction); +inline sectortype* nextsectorneighborzptr(int16_t sectnum, int32_t refz, int16_t topbottom, int16_t direction) +{ + auto sect = nextsectorneighborz(sectnum, refz, topbottom, direction); + return sect == -1? nullptr : §or[sect]; +} + +inline sectortype* nextsectorneighborzptr(sectortype* sectp, int32_t refz, int16_t topbottom, int16_t direction) +{ + auto sect = nextsectorneighborz(int(sectp - sector), refz, topbottom, direction); + return sect == -1? nullptr : §or[sect]; +} int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day) ATTRIBUTE((nonnull(1))); int32_t getflorzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day) ATTRIBUTE((nonnull(1))); @@ -629,50 +672,6 @@ static inline int64_t compat_maybe_truncate_to_int32(int64_t val) return enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? (int32_t)val : val; } -static inline int32_t clipmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist, - int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1,2,3,4))); - -static inline int32_t clipmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist, - int32_t ceildist, int32_t flordist, uint32_t cliptype) -{ - vec3_t vector = { *x, *y, *z }; - - int32_t result = clipmove(&vector, sectnum, xvect, yvect, walldist, ceildist, flordist, cliptype); - - *x = vector.x; - *y = vector.y; - *z = vector.z; - - return result; -} - -static inline int32_t pushmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t walldist, - int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1,2,3,4))); - -static inline int32_t pushmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t walldist, - int32_t ceildist, int32_t flordist, uint32_t cliptype) -{ - vec3_t vector = { *x, *y, *z }; - - int32_t result = pushmove(&vector, sectnum, walldist, ceildist, flordist, cliptype); - - *x = vector.x; - *y = vector.y; - *z = vector.z; - - return result; -} - -static inline void getzrange_old(int32_t x, int32_t y, int32_t z, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz, - int32_t *florhit, int32_t walldist, uint32_t cliptype) ATTRIBUTE((nonnull(5,6,7,8))); - -static inline void getzrange_old(int32_t x, int32_t y, int32_t z, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz, - int32_t *florhit, int32_t walldist, uint32_t cliptype) -{ - const vec3_t vector = { x, y, z }; - getzrange(&vector, sectnum, ceilz, ceilhit, florz, florhit, walldist, cliptype); -} - static inline int32_t setspritez_old(int16_t spritenum, int32_t x, int32_t y, int32_t z) { const vec3_t vector = { x, y, z }; diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 7a3b792ad..c58f9fd94 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -51,6 +51,7 @@ enum //40 bytes +struct walltype; struct sectortype { int16_t wallptr, wallnum; @@ -87,6 +88,7 @@ struct sectortype void addfloorypan(float add) { floorypan_ = fmodf(floorypan_ + add + 512, 256); } // +512 is for handling negative offsets void addceilingxpan(float add) { ceilingxpan_ = fmodf(ceilingxpan_ + add + 512, 256); } // +512 is for handling negative offsets void addceilingypan(float add) { ceilingypan_ = fmodf(ceilingypan_ + add + 512, 256); } // +512 is for handling negative offsets + walltype *firstWall() const; }; //cstat: @@ -134,6 +136,10 @@ struct walltype void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets + sectortype* nextSector() const; + walltype* nextWall() const; + walltype* point2Wall() const; + bool twoSided() const { return nextsector >= 0; } #if 0 // make sure we do not accidentally copy this @@ -362,6 +368,8 @@ struct spritetype { return interpolatedangle(oang, ang, smoothratio, 16); } + + sectortype* sector() const; }; using tspritetype = spritetype; diff --git a/source/build/include/clip.h b/source/build/include/clip.h index 2d2d7330e..6c1761614 100644 --- a/source/build/include/clip.h +++ b/source/build/include/clip.h @@ -29,35 +29,11 @@ inline int clipinsidebox(int x, int y, int wall, int dist) } int clipinsideboxline(int x, int y, int x1, int y1, int x2, int y2, int walldist); -extern int32_t clipmoveboxtracenum; -int32_t clipmove(vec3_t *const pos, int16_t *const sectnum, int32_t xvect, int32_t yvect, int32_t const walldist, int32_t const ceildist, - int32_t const flordist, uint32_t const cliptype) ATTRIBUTE((nonnull(1, 2))); +int32_t clipmove(vec3_t *const pos, int *const sectnum, int32_t xvect, int32_t yvect, int32_t const walldist, int32_t const ceildist, + int32_t const flordist, uint32_t const cliptype, int clipmoveboxtracenum = 3) ATTRIBUTE((nonnull(1, 2))); -inline int clipmove(int* x, int* y, int* z, short* sect, int xv, int yv, int wal, int ceil, int flor, int ct) -{ - vec3_t xyz = { *x,*y,*z }; - int retval = clipmove(&xyz, sect, xv, yv, wal, ceil, flor, ct); - *x = xyz.x; - *y = xyz.y; - *z = xyz.z; - return retval; -} - -int32_t clipmovex(vec3_t *const pos, int16_t *const sectnum, int32_t xvect, int32_t yvect, int32_t const walldist, int32_t const ceildist, - int32_t const flordist, uint32_t const cliptype, uint8_t const noslidep) ATTRIBUTE((nonnull(1, 2))); -int pushmove(vec3_t *const vect, int16_t *const sectnum, int32_t const walldist, int32_t const ceildist, int32_t const flordist, +int pushmove(vec3_t *const vect, int *const sectnum, int32_t const walldist, int32_t const ceildist, int32_t const flordist, uint32_t const cliptype, bool clear = true) ATTRIBUTE((nonnull(1, 2))); -inline int pushmove(int* x, int* y, int* z, int16_t* const sectnum, int32_t const walldist, int32_t const ceildist, int32_t const flordist, - uint32_t const cliptype, bool clear = true) -{ - vec3_t v = { *x,*y,*z }; - auto r = pushmove(&v, sectnum, walldist, ceildist, flordist, cliptype, clear); - *x = v.x; - *y = v.y; - *z = v.z; - return r; -} - #endif diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index 40bb31d11..89ffe393a 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -43,7 +43,7 @@ void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, int32_t* tposx, int32_t* tposy, fixed_t* tang); void renderCompleteMirror(void); -int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int16_t dacursectnum); +int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int dacursectnum, bool fromoutside); void renderDrawMasks(void); diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 17a0282ea..07bdbd68c 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -101,8 +101,6 @@ static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t *y3 = *y2 + ofs.y, *y4 = *y1 + ofs.y; } -int32_t clipmoveboxtracenum = 3; - // // clipinsidebox // @@ -217,7 +215,7 @@ inline void clipmove_tweak_pos(const vec3_t *pos, int32_t gx, int32_t gy, int32_ // Returns: should clip? static int cliptestsector(int const dasect, int const nextsect, int32_t const flordist, int32_t const ceildist, vec2_t const pos, int32_t const posz) { - assert((unsigned)dasect < (unsigned)numsectors && (unsigned)nextsect < (unsigned)numsectors); + assert(validSectorIndex(dasect) && validSectorIndex(nextsect)); auto const sec2 = (usectorptr_t)§or[nextsect]; @@ -272,22 +270,6 @@ static int cliptestsector(int const dasect, int const nextsect, int32_t const fl dacz2 > dacz+CLIPCURBHEIGHT)); // ceilings check the same conditions ^^^^^ } -int32_t clipmovex(vec3_t *pos, int16_t *sectnum, - int32_t xvect, int32_t yvect, - int32_t const walldist, int32_t const ceildist, int32_t const flordist, uint32_t const cliptype, - uint8_t const noslidep) -{ - const int32_t oboxtracenum = clipmoveboxtracenum; - - if (noslidep) - clipmoveboxtracenum = 1; - int32_t ret = clipmove(pos, sectnum, xvect, yvect, - walldist, ceildist, flordist, cliptype); - clipmoveboxtracenum = oboxtracenum; - - return ret; -} - // // raytrace (internal) // @@ -394,7 +376,7 @@ static int get_floorspr_clipyou(vec2_t const v1, vec2_t const v2, vec2_t const v return clipyou; } -static void clipupdatesector(vec2_t const pos, int16_t * const sectnum, int walldist) +static void clipupdatesector(vec2_t const pos, int * const sectnum, int walldist) { #if 0 if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE) @@ -469,8 +451,8 @@ static void clipupdatesector(vec2_t const pos, int16_t * const sectnum, int wall // // clipmove // -int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int32_t yvect, - int32_t const walldist, int32_t const ceildist, int32_t const flordist, uint32_t const cliptype) +int32_t clipmove(vec3_t * const pos, int * const sectnum, int32_t xvect, int32_t yvect, + int32_t const walldist, int32_t const ceildist, int32_t const flordist, uint32_t const cliptype, int clipmoveboxtracenum) { if ((xvect|yvect) == 0 || *sectnum < 0) return 0; @@ -742,13 +724,13 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int vec2_t const clipr = { clipit[hitwall].x2 - clipit[hitwall].x1, clipit[hitwall].y2 - clipit[hitwall].y1 }; // clamp to the max value we can utilize without reworking the scaling below // this works around the overflow issue that affects dukedc2.map - int32_t const templl = (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)clipr.x * clipr.x + (int64_t)clipr.y * clipr.y), INT32_MIN, INT32_MAX); + int32_t const templl = (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)clipr.x * clipr.x + (int64_t)clipr.y * clipr.y), INT32_MIN, INT32_MAX); if (templl > 0) { // I don't know if this one actually overflows or not, but I highly doubt it hurts to check int32_t const templl2 - = (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)(goal.x - vec.x) * clipr.x + (int64_t)(goal.y - vec.y) * clipr.y), INT32_MIN, INT32_MAX); + = (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)(goal.x - vec.x) * clipr.x + (int64_t)(goal.y - vec.y) * clipr.y), INT32_MIN, INT32_MAX); int32_t const i = (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829 || (abs(templl2)>>11) < templl) ? (int)DivScaleL(templl2, templl, 20) : 0; @@ -789,7 +771,9 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int } if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE) - clipupdatesector(vec, sectnum, rad); + { + clipupdatesector(vec, sectnum, rad); + } pos->x = vec.x; pos->y = vec.y; @@ -851,7 +835,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int // // pushmove // -int pushmove(vec3_t *const vect, int16_t *const sectnum, +int pushmove(vec3_t *const vect, int *const sectnum, int32_t const walldist, int32_t const ceildist, int32_t const flordist, uint32_t const cliptype, bool clear /*= true*/) { int bad; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 76212efcd..da1d36df4 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -207,7 +207,7 @@ static int32_t engineLoadTables(void) int32_t i; for (i=0; i<=512; i++) - sintable[i] = bsinf(i); + sintable[i] = int(sin(i * BAngRadian) * +SINTABLEUNIT); for (i=513; i<1024; i++) sintable[i] = sintable[1024-i]; for (i=1024; i<2048; i++) @@ -702,35 +702,10 @@ void initspritelists(void) // // See http://fabiensanglard.net/duke3d/build_engine_internals.php, // "Inside details" for the idea behind the algorithm. -int32_t inside_ps(int32_t x, int32_t y, int16_t sectnum) + +int32_t inside(int32_t x, int32_t y, int sectnum) { - if (sectnum >= 0 && sectnum < numsectors) - { - int32_t cnt = 0; - auto wal = (uwallptr_t)&wall[sector[sectnum].wallptr]; - int wallsleft = sector[sectnum].wallnum; - - do - { - vec2_t v1 = { wal->x - x, wal->y - y }; - auto const &wal2 = *(uwallptr_t)&wall[wal->point2]; - vec2_t v2 = { wal2.x - x, wal2.y - y }; - - if ((v1.y^v2.y) < 0) - cnt ^= (((v1.x^v2.x) < 0) ? (v1.x*v2.y= 0)); - - wal++; - } - while (--wallsleft); - - return cnt; - } - - return -1; -} -int32_t inside_old(int32_t x, int32_t y, int16_t sectnum) -{ - if (sectnum >= 0 && sectnum < numsectors) + if (validSectorIndex(sectnum)) { uint32_t cnt = 0; auto wal = (uwallptr_t)&wall[sector[sectnum].wallptr]; @@ -763,71 +738,6 @@ int32_t inside_old(int32_t x, int32_t y, int16_t sectnum) return -1; } -int32_t inside(int32_t x, int32_t y, int sectnum) -{ - switch (enginecompatibility_mode) - { - case ENGINECOMPATIBILITY_NONE: - break; - case ENGINECOMPATIBILITY_19950829: - return inside_ps(x, y, sectnum); - default: - return inside_old(x, y, sectnum); - } - if ((unsigned)sectnum < (unsigned)numsectors) - { - uint32_t cnt1 = 0, cnt2 = 0; - - auto wal = (uwallptr_t)&wall[sector[sectnum].wallptr]; - int wallsleft = sector[sectnum].wallnum; - - do - { - // Get the x and y components of the [tested point]-->[wall - // point{1,2}] vectors. - vec2_t v1 = { wal->x - x, wal->y - y }; - auto const &wal2 = *(uwallptr_t)&wall[wal->point2]; - vec2_t v2 = { wal2.x - x, wal2.y - y }; - - // First, test if the point is EXACTLY_ON_WALL_POINT. - if ((v1.x|v1.y) == 0 || (v2.x|v2.y)==0) - return 1; - - // If their signs differ[*], ... - // - // [*] where '-' corresponds to <0 and '+' corresponds to >=0. - // Equivalently, the branch is taken iff - // y1 != y2 AND y_m <= y < y_M, - // where y_m := min(y1, y2) and y_M := max(y1, y2). - if ((v1.y^v2.y) < 0) - cnt1 ^= (((v1.x^v2.x) >= 0) ? v1.x : (v1.x*v2.y-v2.x*v1.y)^v2.y); - - v1.y--; - v2.y--; - - // Now, do the same comparisons, but with the interval half-open on - // the other side! That is, take the branch iff - // y1 != y2 AND y_m < y <= y_M, - // For a rectangular sector, without EXACTLY_ON_WALL_POINT, this - // would still leave the lower left and upper right points - // "outside" the sector. - if ((v1.y^v2.y) < 0) - { - v1.x--; - v2.x--; - - cnt2 ^= (((v1.x^v2.x) >= 0) ? v1.x : (v1.x*v2.y-v2.x*v1.y)^v2.y); - } - - wal++; - } - while (--wallsleft); - - return (cnt1|cnt2)>>31; - } - - return -1; -} int32_t getangle(int32_t xvect, int32_t yvect) { @@ -878,7 +788,7 @@ int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyo // int32_t setsprite(int16_t spritenum, const vec3_t *newpos) { - int16_t tempsectnum = sprite[spritenum].sectnum; + int tempsectnum = sprite[spritenum].sectnum; if (newpos != &sprite[spritenum].pos) sprite[spritenum].pos = *newpos; @@ -895,7 +805,7 @@ int32_t setsprite(int16_t spritenum, const vec3_t *newpos) int32_t setspritez(int16_t spritenum, const vec3_t *newpos) { - int16_t tempsectnum = sprite[spritenum].sectnum; + int tempsectnum = sprite[spritenum].sectnum; if ((void const *)newpos != (void *)&sprite[spritenum]) sprite[spritenum].pos = *newpos; @@ -1177,7 +1087,7 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange, // flags: // 1: don't reset walbitmap[] (the bitmap of already dragged vertices) // 2: In the editor, do wall[].cstat |= (1<<14) also for the lastwall(). -void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags) +void dragpoint(int pointhighlight, int32_t dax, int32_t day, uint8_t flags) { int32_t i, numyaxwalls=0; static int16_t yaxwalls[MAXWALLS]; @@ -1356,9 +1266,9 @@ int findwallbetweensectors(int sect1, int sect2) // // updatesector[z] // -void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) +void updatesector(int32_t const x, int32_t const y, int * const sectnum) { - int16_t sect = *sectnum; + int sect = *sectnum; updatesectorneighbor(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST); if (sect != -1) SET_AND_RETURN(*sectnum, sect); @@ -1373,54 +1283,23 @@ void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) } -// new: if *sectnum >= MAXSECTORS, *sectnum-=MAXSECTORS is considered instead -// as starting sector and the 'initial' z check is skipped -// (not initial anymore because it follows the sector updating due to TROR) - -void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) +void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int* const sectnum) { - if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE) - { - if ((uint32_t)(*sectnum) < 2*MAXSECTORS) - { - int32_t nofirstzcheck = 0; + int32_t cz, fz; + getzsofslope(*sectnum, x, y, &cz, &fz); - if (*sectnum >= MAXSECTORS) - { - *sectnum -= MAXSECTORS; - nofirstzcheck = 1; - } - - // this block used to be outside the "if" and caused crashes in Polymost Mapster32 - int32_t cz, fz; - getzsofslope(*sectnum, x, y, &cz, &fz); - - if (nofirstzcheck || (z >= cz && z <= fz)) - if (inside_p(x, y, *sectnum)) - return; - - walltype const * wal = &wall[sector[*sectnum].wallptr]; - int wallsleft = sector[*sectnum].wallnum; - do - { - // YAX: TODO: check neighboring sectors here too? - int const next = wal->nextsector; - if (next>=0 && inside_z_p(x,y,z, next)) - SET_AND_RETURN(*sectnum, next); - - wal++; - } - while (--wallsleft); - } - } - else - { - int16_t sect = *sectnum; - updatesectorneighborz(x, y, z, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST); - if (sect != -1) - SET_AND_RETURN(*sectnum, sect); - } + walltype const * wal = &wall[sector[*sectnum].wallptr]; + int wallsleft = sector[*sectnum].wallnum; + do + { + int const next = wal->nextsector; + if (next>=0 && inside_z_p(x,y,z, next)) + SET_AND_RETURN(*sectnum, next); + wal++; + } + while (--wallsleft); + // we need to support passing in a sectnum of -1, unfortunately for (int i = numsectors - 1; i >= 0; --i) if (inside_z_p(x, y, z, i)) @@ -1429,11 +1308,11 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * *sectnum = -1; } -void updatesectorneighbor(int32_t const x, int32_t const y, int16_t * const sectnum, int32_t initialMaxDistance /*= INITIALUPDATESECTORDIST*/, int32_t maxDistance /*= MAXUPDATESECTORDIST*/) +void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum, int32_t initialMaxDistance /*= INITIALUPDATESECTORDIST*/, int32_t maxDistance /*= MAXUPDATESECTORDIST*/) { int const initialsectnum = *sectnum; - if ((unsigned)initialsectnum < (unsigned)numsectors && getsectordist({x, y}, initialsectnum) <= initialMaxDistance) + if ((validSectorIndex(initialsectnum)) && getsectordist({x, y}, initialsectnum) <= initialMaxDistance) { if (inside_p(x, y, initialsectnum)) return; @@ -1465,53 +1344,6 @@ void updatesectorneighbor(int32_t const x, int32_t const y, int16_t * const sect *sectnum = -1; } -void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum, int32_t initialMaxDistance /*= 0*/, int32_t maxDistance /*= 0*/) -{ - bool nofirstzcheck = false; - - if (*sectnum >= MAXSECTORS && *sectnum - MAXSECTORS < numsectors) - { - *sectnum -= MAXSECTORS; - nofirstzcheck = true; - } - - uint32_t const correctedsectnum = (unsigned)*sectnum; - - if (correctedsectnum < (unsigned)numsectors && getsectordist({x, y}, correctedsectnum) <= initialMaxDistance) - { - int32_t cz, fz; - getzsofslope(correctedsectnum, x, y, &cz, &fz); - - if ((nofirstzcheck || (z >= cz && z <= fz)) && inside_p(x, y, *sectnum)) - return; - - static int16_t sectlist[MAXSECTORS]; - static uint8_t sectbitmap[(MAXSECTORS+7)>>3]; - int16_t nsecs; - - bfirst_search_init(sectlist, sectbitmap, &nsecs, MAXSECTORS, correctedsectnum); - - for (int sectcnt=0; sectcntwallptr; - int const endwall = sec->wallptr + sec->wallnum; - auto uwal = (uwallptr_t)&wall[startwall]; - - for (int j=startwall; jnextsector >= 0 && getsectordist({x, y}, uwal->nextsector) <= maxDistance) - bfirst_search_try(sectlist, sectbitmap, &nsecs, uwal->nextsector); - } - } - - *sectnum = -1; -} - // // rotatepoint // diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index e20f47bf9..da370a1ce 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -981,10 +981,8 @@ static int32_t global_cf_shade, global_cf_pal, global_cf_fogpal; static float (*global_getzofslope_func)(usectorptr_t, float, float); static void polymost_internal_nonparallaxed(vec2f_t n0, vec2f_t n1, float ryp0, float ryp1, float x0, float x1, - float y0, float y1, int32_t sectnum) + float y0, float y1, int32_t sectnum, bool have_floor) { - int const have_floor = sectnum & MAXSECTORS; - sectnum &= ~MAXSECTORS; auto const sec = (usectorptr_t)§or[sectnum]; // comments from floor code: @@ -1622,7 +1620,7 @@ static void polymost_drawalls(int32_t const bunch) { int32_t fz = getflorzofslope(sectnum, globalposx, globalposy); if (globalposz <= fz) - polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, fy0, fy1, sectnum | MAXSECTORS); + polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, fy0, fy1, sectnum, true); } else if ((nextsectnum < 0) || (!(sector[nextsectnum].floorstat&1))) { @@ -1675,7 +1673,7 @@ static void polymost_drawalls(int32_t const bunch) { int32_t cz = getceilzofslope(sectnum, globalposx, globalposy); if (globalposz >= cz) - polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, cy0, cy1, sectnum); + polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, cy0, cy1, sectnum, false); } else if ((nextsectnum < 0) || (!(sector[nextsectnum].ceilingstat&1))) { @@ -3307,7 +3305,7 @@ void renderCompleteMirror(void) EXTERN_CVAR(Int, gl_fogmode) int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, - fixed_t daang, fixed_t dahoriz, int16_t dacursectnum) + fixed_t daang, fixed_t dahoriz, int dacursectnum, bool fromoutside) { pm_spritesortcnt = 0; checkRotatedWalls(); @@ -3316,9 +3314,7 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, // Update starting sector number (common to classic and Polymost). // ADJUST_GLOBALCURSECTNUM. - if (dacursectnum >= MAXSECTORS) - dacursectnum -= MAXSECTORS; - else + if (!fromoutside) { int i = dacursectnum; updatesector(daposx, daposy, &dacursectnum); @@ -3894,7 +3890,7 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate) GLInterface.EnableBlend(true); // else GLInterface.EnableBlend(false); } else pc[3] = 1.f; - GLInterface.SetShade(std::max(0, globalshade), numshades); + GLInterface.SetShade(max(0, globalshade), numshades); //------------ //transform to Build coords diff --git a/source/common/2d/v_2ddrawer.cpp b/source/common/2d/v_2ddrawer.cpp index 612eef005..182712349 100644 --- a/source/common/2d/v_2ddrawer.cpp +++ b/source/common/2d/v_2ddrawer.cpp @@ -33,7 +33,7 @@ */ #include -#include "templates.h" + #include "v_2ddrawer.h" #include "vectors.h" #include "vm.h" @@ -455,7 +455,7 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms) // Note that this only works for unflipped and unrotated full textures. if (parms.windowleft > 0 || parms.windowright < parms.texwidth) { - double wi = std::min(parms.windowright, parms.texwidth); + double wi = min(parms.windowright, parms.texwidth); x += parms.windowleft * xscale; w -= (parms.texwidth - wi + parms.windowleft) * xscale; diff --git a/source/common/2d/v_2ddrawer.h b/source/common/2d/v_2ddrawer.h index 74d5935a6..ab87085f5 100644 --- a/source/common/2d/v_2ddrawer.h +++ b/source/common/2d/v_2ddrawer.h @@ -132,7 +132,7 @@ public: RenderCommand() { - memset(this, 0, sizeof(*this)); + memset((void*)this, 0, sizeof(*this)); } // If these fields match, two draw commands can be batched. @@ -306,8 +306,8 @@ public: void UploadData(F2DDrawer::TwoDVertex *vertices, int vertcount, int *indices, int indexcount) { - mVertexBuffer->SetData(vertcount * sizeof(*vertices), vertices, false); - mIndexBuffer->SetData(indexcount * sizeof(unsigned int), indices, false); + mVertexBuffer->SetData(vertcount * sizeof(*vertices), vertices, BufferUsageType::Stream); + mIndexBuffer->SetData(indexcount * sizeof(unsigned int), indices, BufferUsageType::Stream); } std::pair GetBufferObjects() const diff --git a/source/common/2d/v_draw.cpp b/source/common/2d/v_draw.cpp index 9c53e754b..4a99b8cac 100644 --- a/source/common/2d/v_draw.cpp +++ b/source/common/2d/v_draw.cpp @@ -36,7 +36,7 @@ #include #include "v_draw.h" #include "vm.h" -#include "templates.h" + #include "texturemanager.h" #include "r_videoscale.h" #include "c_cvars.h" @@ -151,8 +151,8 @@ int GetUIScale(F2DDrawer *drawer, int altval) // block scales that result in something larger than the current screen. int vmax = drawer->GetHeight() / 200; int hmax = drawer->GetWidth() / 320; - int max = MAX(vmax, hmax); - return MAX(1,MIN(scaleval, max)); + int max = std::max(vmax, hmax); + return std::max(1,min(scaleval, max)); } // The new console font is twice as high, so the scaling calculation must factor that in. @@ -172,8 +172,8 @@ int GetConScale(F2DDrawer* drawer, int altval) // block scales that result in something larger than the current screen. int vmax = drawer->GetHeight() / 400; int hmax = drawer->GetWidth() / 640; - int max = MAX(vmax, hmax); - return MAX(1, MIN(scaleval, max)); + int max = std::max(vmax, hmax); + return std::max(1, min(scaleval, max)); } @@ -357,7 +357,7 @@ DEFINE_ACTION_FUNCTION(_Screen, GetClipRect) if (numret > 1) ret[1].SetInt(y); if (numret > 2) ret[2].SetInt(w); if (numret > 3) ret[3].SetInt(h); - return MIN(numret, 4); + return min(numret, 4); } @@ -460,7 +460,7 @@ DEFINE_ACTION_FUNCTION(_Screen, GetFullscreenRect) if (numret >= 2) ret[1].SetFloat(rect.top); if (numret >= 3) ret[2].SetFloat(rect.width); if (numret >= 4) ret[3].SetFloat(rect.height); - return MIN(numret, 4); + return min(numret, 4); } @@ -905,7 +905,7 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double break; case DTA_Alpha: - parms->Alpha = (float)(MIN(1., ListGetDouble(tags))); + parms->Alpha = (float)(min(1., ListGetDouble(tags))); break; case DTA_AlphaChannel: @@ -1090,7 +1090,7 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double break; case DTA_ShadowAlpha: - //parms->shadowAlpha = (float)MIN(1., ListGetDouble(tags)); + //parms->shadowAlpha = (float)min(1., ListGetDouble(tags)); break; case DTA_ShadowColor: @@ -1286,10 +1286,10 @@ static void VirtualToRealCoords(F2DDrawer *drawer, double Width, double Height, { case 1: default: - myratio = MIN(64.0f / 27.0f, myratio); + myratio = min(64.0f / 27.0f, myratio); break; case 0: - myratio = MIN(16.0f / 9.0f, myratio); + myratio = min(16.0f / 9.0f, myratio); case -1: break; } @@ -1348,7 +1348,7 @@ DEFINE_ACTION_FUNCTION(_Screen, VirtualToRealCoords) VirtualToRealCoords(twod, x, y, w, h, vw, vh, vbottom, handleaspect); if (numret >= 1) ret[0].SetVector2(DVector2(x, y)); if (numret >= 2) ret[1].SetVector2(DVector2(w, h)); - return MIN(numret, 2); + return min(numret, 2); } void VirtualToRealCoordsInt(F2DDrawer *drawer, int &x, int &y, int &w, int &h, @@ -1529,8 +1529,9 @@ DEFINE_ACTION_FUNCTION(_Screen, Dim) PARAM_INT(y1); PARAM_INT(w); PARAM_INT(h); + PARAM_INT(style); if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); - Dim(twod, color, float(amount), x1, y1, w, h); + Dim(twod, color, float(amount), x1, y1, w, h, &LegacyRenderStyles[style]); return 0; } @@ -1593,7 +1594,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawLineFrame) void V_CalcCleanFacs(int designwidth, int designheight, int realwidth, int realheight, int* cleanx, int* cleany, int* _cx1, int* _cx2) { if (designheight < 240 && realheight >= 480) designheight = 240; - *cleanx = *cleany = std::min(realwidth / designwidth, realheight / designheight); + *cleanx = *cleany = min(realwidth / designwidth, realheight / designheight); } diff --git a/source/common/audio/music/i_music.cpp b/source/common/audio/music/i_music.cpp index b73c630ca..26989992d 100644 --- a/source/common/audio/music/i_music.cpp +++ b/source/common/audio/music/i_music.cpp @@ -43,7 +43,7 @@ #include "m_argv.h" #include "filesystem.h" #include "c_dispatch.h" -#include "templates.h" + #include "stats.h" #include "cmdlib.h" #include "c_cvars.h" diff --git a/source/common/audio/sound/oalsound.cpp b/source/common/audio/sound/oalsound.cpp index 252688572..4ef36cb4d 100644 --- a/source/common/audio/sound/oalsound.cpp +++ b/source/common/audio/sound/oalsound.cpp @@ -36,7 +36,7 @@ #include #include "c_cvars.h" -#include "templates.h" + #include "oalsound.h" #include "c_dispatch.h" #include "v_text.h" @@ -579,7 +579,7 @@ OpenALSoundRenderer::OpenALSoundRenderer() // Make sure one source is capable of stereo output with the rest doing // mono, without running out of voices attribs.Push(ALC_MONO_SOURCES); - attribs.Push(std::max(snd_channels, 2) - 1); + attribs.Push(max(snd_channels, 2) - 1); attribs.Push(ALC_STEREO_SOURCES); attribs.Push(1); if(ALC.SOFT_HRTF) @@ -681,7 +681,7 @@ OpenALSoundRenderer::OpenALSoundRenderer() // At least Apple's OpenAL implementation returns zeroes, // although it can generate reasonable number of sources. - const int numChannels = std::max(snd_channels, 2); + const int numChannels = max(snd_channels, 2); int numSources = numMono + numStereo; if (0 == numSources) @@ -689,7 +689,7 @@ OpenALSoundRenderer::OpenALSoundRenderer() numSources = numChannels; } - Sources.Resize(std::min(numChannels, numSources)); + Sources.Resize(min(numChannels, numSources)); for(unsigned i = 0;i < Sources.Size();i++) { alGenSources(1, &Sources[i]); @@ -1346,7 +1346,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener float gain = GetRolloff(rolloff, dist * distscale); // Don't let the ref distance go to 0, or else distance attenuation is // lost with the inverse distance model. - alSourcef(source, AL_REFERENCE_DISTANCE, std::max(gain*dist, 0.0004f)); + alSourcef(source, AL_REFERENCE_DISTANCE, max(gain*dist, 0.0004f)); alSourcef(source, AL_MAX_DISTANCE, std::numeric_limits::max()); alSourcef(source, AL_ROLLOFF_FACTOR, 1.f); } @@ -1466,9 +1466,9 @@ void OpenALSoundRenderer::ChannelPitch(FISoundChannel *chan, float pitch) ALuint source = GET_PTRID(chan->SysChannel); if (WasInWater && !(chan->ChanFlags & CHANF_UI)) - alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f)*PITCH_MULT); + alSourcef(source, AL_PITCH, max(pitch, 0.0001f)*PITCH_MULT); else - alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f)); + alSourcef(source, AL_PITCH, max(pitch, 0.0001f)); } void OpenALSoundRenderer::StopChannel(FISoundChannel *chan) @@ -1622,7 +1622,7 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh { float dist = sqrtf(dist_sqr); float gain = GetRolloff(&chan->Rolloff, dist * chan->DistanceScale); - alSourcef(source, AL_REFERENCE_DISTANCE, std::max(gain*dist, 0.0004f)); + alSourcef(source, AL_REFERENCE_DISTANCE, max(gain*dist, 0.0004f)); } alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE); diff --git a/source/common/audio/sound/s_environment.cpp b/source/common/audio/sound/s_environment.cpp index d2e52e21a..c5f1a5cf7 100644 --- a/source/common/audio/sound/s_environment.cpp +++ b/source/common/audio/sound/s_environment.cpp @@ -34,7 +34,7 @@ #include "s_soundinternal.h" #include "sc_man.h" -#include "templates.h" + #include "cmdlib.h" diff --git a/source/common/audio/sound/s_reverbedit.cpp b/source/common/audio/sound/s_reverbedit.cpp index 25993a400..398d4f2f5 100644 --- a/source/common/audio/sound/s_reverbedit.cpp +++ b/source/common/audio/sound/s_reverbedit.cpp @@ -36,7 +36,7 @@ #include "s_soundinternal.h" #include "sc_man.h" #include "cmdlib.h" -#include "templates.h" + #include "filesystem.h" #include "i_system.h" #include "printf.h" diff --git a/source/common/audio/sound/s_sound.cpp b/source/common/audio/sound/s_sound.cpp index a9da5fdd3..cf42a7d8f 100644 --- a/source/common/audio/sound/s_sound.cpp +++ b/source/common/audio/sound/s_sound.cpp @@ -36,7 +36,7 @@ #include #include -#include "templates.h" + #include "s_soundinternal.h" #include "m_swap.h" #include "superfasthash.h" @@ -407,7 +407,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, sfx = &S_sfx[sound_id]; // Scale volume according to SNDINFO data. - volume = std::min(volume * sfx->Volume, 1.f); + volume = min(volume * sfx->Volume, 1.f); if (volume <= 0) return NULL; @@ -847,7 +847,7 @@ bool SoundEngine::CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_ CalcPosVel(chan, &chanorigin, NULL); // scale the limit distance with the attenuation. An attenuation of 0 means the limit distance is infinite and all sounds within the level are inside the limit. - float attn = std::min(chan->DistanceScale, attenuation); + float attn = min(chan->DistanceScale, attenuation); if (attn <= 0 || (chanorigin - pos).LengthSquared() <= limit_range / attn) { count++; @@ -1074,8 +1074,8 @@ void SoundEngine::ChangeSoundPitch(int sourcetype, const void *source, int chann void SoundEngine::SetPitch(FSoundChan *chan, float pitch) { assert(chan != nullptr); - GSnd->ChannelPitch(chan, std::max(0.0001f, pitch)); - chan->Pitch = std::max(1, int(float(DEFAULT_PITCH) * pitch)); + GSnd->ChannelPitch(chan, max(0.0001f, pitch)); + chan->Pitch = max(1, int(float(DEFAULT_PITCH) * pitch)); } //========================================================================== diff --git a/source/common/console/c_bind.cpp b/source/common/console/c_bind.cpp index f44e47603..1bca5072c 100644 --- a/source/common/console/c_bind.cpp +++ b/source/common/console/c_bind.cpp @@ -41,7 +41,7 @@ #include "c_dispatch.h" #include "configfile.h" #include "filesystem.h" -#include "templates.h" + #include "i_time.h" #include "printf.h" #include "sc_man.h" diff --git a/source/common/console/c_buttons.cpp b/source/common/console/c_buttons.cpp index 0ea14dd46..860824ca5 100644 --- a/source/common/console/c_buttons.cpp +++ b/source/common/console/c_buttons.cpp @@ -34,7 +34,7 @@ */ #include "c_buttons.h" -#include "templates.h" + #include "c_dispatch.h" #include "printf.h" #include "cmdlib.h" diff --git a/source/common/console/c_commandbuffer.cpp b/source/common/console/c_commandbuffer.cpp index bf459350f..b079d7f76 100644 --- a/source/common/console/c_commandbuffer.cpp +++ b/source/common/console/c_commandbuffer.cpp @@ -144,7 +144,7 @@ void FCommandBuffer::MakeStartPosGood() { // The cursor is in front of the visible part of the line n = CursorPosCells; } - StartPosCells = std::max(0, n); + StartPosCells = max(0, n); bool overflow; StartPos = CharsForCells(StartPosCells, &overflow); if (overflow) diff --git a/source/common/console/c_console.cpp b/source/common/console/c_console.cpp index 5cafbb080..b40708808 100644 --- a/source/common/console/c_console.cpp +++ b/source/common/console/c_console.cpp @@ -34,7 +34,7 @@ #include -#include "templates.h" + #include "version.h" #include "c_bind.h" #include "c_console.h" @@ -856,7 +856,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) { // Scroll console buffer down if (ev->subtype == EV_GUI_WheelDown) { - RowAdjust = std::max (0, RowAdjust - 3); + RowAdjust = max (0, RowAdjust - 3); } else { diff --git a/source/common/console/c_dispatch.cpp b/source/common/console/c_dispatch.cpp index ce9f2cef7..004c5be3e 100644 --- a/source/common/console/c_dispatch.cpp +++ b/source/common/console/c_dispatch.cpp @@ -39,7 +39,7 @@ #include #include -#include "templates.h" + #include "cmdlib.h" #include "c_console.h" #include "c_dispatch.h" @@ -1092,7 +1092,7 @@ void C_SearchForPullins(FExecList *exec, const char *file, FCommandLine &argv) lastSlash1 = strrchr(file, '/'); lastSlash2 = strrchr(file, '\\'); - lastSlash = MAX(lastSlash1, lastSlash2); + lastSlash = max(lastSlash1, lastSlash2); #endif for (int i = 1; i < argv.argc(); ++i) diff --git a/source/common/console/c_tabcomplete.cpp b/source/common/console/c_tabcomplete.cpp index ca8339062..eccd64b03 100644 --- a/source/common/console/c_tabcomplete.cpp +++ b/source/common/console/c_tabcomplete.cpp @@ -273,7 +273,7 @@ bool C_TabCompleteList () } } nummatches++; - maxwidth = std::max (maxwidth, strlen (TabCommands[i].TabName.GetChars())); + maxwidth = max (maxwidth, strlen (TabCommands[i].TabName.GetChars())); } } if (nummatches > 1) diff --git a/source/common/cutscenes/movieplayer.cpp b/source/common/cutscenes/movieplayer.cpp index e69773695..04cf6a2ca 100644 --- a/source/common/cutscenes/movieplayer.cpp +++ b/source/common/cutscenes/movieplayer.cpp @@ -562,7 +562,7 @@ public: } flags = flags_; Smacker_GetFrameSize(hSMK, nWidth, nHeight); - pFrame.Resize(nWidth * nHeight + std::max(nWidth, nHeight)); + pFrame.Resize(nWidth * nHeight + max(nWidth, nHeight)); float frameRate = Smacker_GetFrameRate(hSMK); nFrameNs = uint64_t(1'000'000'000 / frameRate); nFrames = Smacker_GetNumFrames(hSMK); diff --git a/source/common/cutscenes/playmve.cpp b/source/common/cutscenes/playmve.cpp index 242997e26..a24d6292d 100644 --- a/source/common/cutscenes/playmve.cpp +++ b/source/common/cutscenes/playmve.cpp @@ -49,7 +49,7 @@ #include "v_draw.h" #include "s_music.h" #include "cmdlib.h" -#include "templates.h" + diff --git a/source/common/engine/i_net.cpp b/source/common/engine/i_net.cpp index 94388656f..64fd4acaf 100644 --- a/source/common/engine/i_net.cpp +++ b/source/common/engine/i_net.cpp @@ -75,7 +75,7 @@ #include "cmdlib.h" #include "printf.h" #include "i_interface.h" -#include "templates.h" + #include "i_net.h" diff --git a/source/common/engine/palettecontainer.cpp b/source/common/engine/palettecontainer.cpp index 41a92735d..73fb2bdb9 100644 --- a/source/common/engine/palettecontainer.cpp +++ b/source/common/engine/palettecontainer.cpp @@ -37,7 +37,7 @@ #include "m_crc32.h" #include "printf.h" #include "colormatcher.h" -#include "templates.h" + #include "palettecontainer.h" #include "files.h" @@ -565,9 +565,9 @@ bool FRemapTable::AddDesaturation(int start, int end, double r1, double g1, doub GPalette.BaseColors[c].g * 143 + GPalette.BaseColors[c].b * 37) / 256.0; - PalEntry pe = PalEntry( MIN(255, int(r1 + intensity*r2)), - MIN(255, int(g1 + intensity*g2)), - MIN(255, int(b1 + intensity*b2))); + PalEntry pe = PalEntry( min(255, int(r1 + intensity*r2)), + min(255, int(g1 + intensity*g2)), + min(255, int(b1 + intensity*b2))); int cc = GPalette.Remap[c]; diff --git a/source/common/engine/renderstyle.cpp b/source/common/engine/renderstyle.cpp index 1a29292ea..e31538b4f 100644 --- a/source/common/engine/renderstyle.cpp +++ b/source/common/engine/renderstyle.cpp @@ -32,7 +32,7 @@ ** */ -#include "templates.h" +#include "basics.h" #include "renderstyle.h" #include "c_cvars.h" diff --git a/source/common/engine/sc_man.cpp b/source/common/engine/sc_man.cpp index f24f25d92..29b0b445b 100644 --- a/source/common/engine/sc_man.cpp +++ b/source/common/engine/sc_man.cpp @@ -40,11 +40,11 @@ #include "engineerrors.h" #include "sc_man.h" #include "cmdlib.h" -#include "templates.h" + #include "printf.h" #include "name.h" #include "v_text.h" -#include "templates.h" + #include "zstring.h" #include "name.h" #include diff --git a/source/common/filesystem/file_rff.cpp b/source/common/filesystem/file_rff.cpp index c69b50246..e8c4fce81 100644 --- a/source/common/filesystem/file_rff.cpp +++ b/source/common/filesystem/file_rff.cpp @@ -34,7 +34,7 @@ */ #include "resourcefile.h" -#include "templates.h" + #include "printf.h" //========================================================================== @@ -219,7 +219,7 @@ int FRFFLump::FillCache() if (Flags & LUMPF_COMPRESSED) { - int cryptlen = MIN (LumpSize, 256); + int cryptlen = min (LumpSize, 256); uint8_t *data = (uint8_t *)Cache; for (int i = 0; i < cryptlen; ++i) diff --git a/source/common/filesystem/file_zip.cpp b/source/common/filesystem/file_zip.cpp index db5bdf902..812e61783 100644 --- a/source/common/filesystem/file_zip.cpp +++ b/source/common/filesystem/file_zip.cpp @@ -36,7 +36,7 @@ #include #include "file_zip.h" #include "cmdlib.h" -#include "templates.h" + #include "printf.h" #include "w_zip.h" @@ -124,7 +124,7 @@ static uint32_t Zip_FindCentralDir(FileReader &fin) uint32_t uPosFound=0; FileSize = (uint32_t)fin.GetLength(); - uMaxBack = MIN(0xffff, FileSize); + uMaxBack = min(0xffff, FileSize); uBackRead = 4; while (uBackRead < uMaxBack) @@ -137,7 +137,7 @@ static uint32_t Zip_FindCentralDir(FileReader &fin) uBackRead += BUFREADCOMMENT; uReadPos = FileSize - uBackRead; - uReadSize = MIN((BUFREADCOMMENT + 4), (FileSize - uReadPos)); + uReadSize = min((BUFREADCOMMENT + 4), (FileSize - uReadPos)); if (fin.Seek(uReadPos, FileReader::SeekSet) != 0) break; diff --git a/source/common/fonts/font.cpp b/source/common/fonts/font.cpp index 5edd09eb1..9dc4fee33 100644 --- a/source/common/fonts/font.cpp +++ b/source/common/fonts/font.cpp @@ -40,7 +40,7 @@ #include #include -#include "templates.h" + #include "m_swap.h" #include "v_font.h" #include "printf.h" @@ -936,7 +936,7 @@ int FFont::StringWidth(const uint8_t *string, int spacing) const } } - return std::max(maxw, w); + return max(maxw, w); } //========================================================================== diff --git a/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index 0042f48c3..a9c6d1cf6 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -39,7 +39,7 @@ #include #include -#include "templates.h" + #include "m_swap.h" #include "v_font.h" #include "filesystem.h" diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 6940d8282..7a3758e64 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -50,7 +50,7 @@ #include "texturemanager.h" #include "printf.h" #include "i_interface.h" -#include "templates.h" + bool CheckSkipGameOptionBlock(FScanner& sc); diff --git a/source/common/objects/dobjgc.cpp b/source/common/objects/dobjgc.cpp index 58b27c4b7..91cfafaef 100644 --- a/source/common/objects/dobjgc.cpp +++ b/source/common/objects/dobjgc.cpp @@ -57,7 +57,7 @@ // HEADER FILES ------------------------------------------------------------ #include "dobject.h" -#include "templates.h" + #include "c_dispatch.h" #include "menu.h" #include "stats.h" @@ -348,7 +348,7 @@ static size_t SingleStep() State = GCS_Finalize; } //assert(old >= AllocBytes); - Estimate -= MAX(0, old - AllocBytes); + Estimate -= max(0, old - AllocBytes); return (GCSWEEPMAX - finalize_count) * GCSWEEPCOST + finalize_count * GCFINALIZECOST; } @@ -625,7 +625,7 @@ CCMD(gc) } else { - GC::Pause = MAX(1,atoi(argv[2])); + GC::Pause = max(1,atoi(argv[2])); } } else if (stricmp(argv[1], "stepmul") == 0) @@ -636,7 +636,7 @@ CCMD(gc) } else { - GC::StepMul = MAX(100, atoi(argv[2])); + GC::StepMul = max(100, atoi(argv[2])); } } } diff --git a/source/common/platform/posix/cocoa/i_input.mm b/source/common/platform/posix/cocoa/i_input.mm index 6782eca78..ebda85a2e 100644 --- a/source/common/platform/posix/cocoa/i_input.mm +++ b/source/common/platform/posix/cocoa/i_input.mm @@ -284,11 +284,11 @@ uint8_t ModifierToDIK(const uint32_t modifier) { switch (modifier) { - case NSAlphaShiftKeyMask: return DIK_CAPITAL; - case NSShiftKeyMask: return DIK_LSHIFT; - case NSControlKeyMask: return DIK_LCONTROL; - case NSAlternateKeyMask: return DIK_LMENU; - case NSCommandKeyMask: return DIK_LWIN; + case NSEventModifierFlagCapsLock: return DIK_CAPITAL; + case NSEventModifierFlagShift: return DIK_LSHIFT; + case NSEventModifierFlagControl: return DIK_LCONTROL; + case NSEventModifierFlagOption: return DIK_LMENU; + case NSEventModifierFlagCommand: return DIK_LWIN; } return 0; @@ -296,20 +296,20 @@ uint8_t ModifierToDIK(const uint32_t modifier) int16_t ModifierFlagsToGUIKeyModifiers(NSEvent* theEvent) { - const NSUInteger modifiers([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask); - return ((modifiers & NSShiftKeyMask ) ? GKM_SHIFT : 0) - | ((modifiers & NSControlKeyMask ) ? GKM_CTRL : 0) - | ((modifiers & NSAlternateKeyMask) ? GKM_ALT : 0) - | ((modifiers & NSCommandKeyMask ) ? GKM_META : 0); + const NSUInteger modifiers([theEvent modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask); + return ((modifiers & NSEventModifierFlagShift ) ? GKM_SHIFT : 0) + | ((modifiers & NSEventModifierFlagControl) ? GKM_CTRL : 0) + | ((modifiers & NSEventModifierFlagOption ) ? GKM_ALT : 0) + | ((modifiers & NSEventModifierFlagCommand) ? GKM_META : 0); } bool ShouldGenerateGUICharEvent(NSEvent* theEvent) { - const NSUInteger modifiers([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask); - return !(modifiers & NSControlKeyMask) - && !(modifiers & NSAlternateKeyMask) - && !(modifiers & NSCommandKeyMask) - && !(modifiers & NSFunctionKeyMask); + const NSUInteger modifiers([theEvent modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask); + return !(modifiers & NSEventModifierFlagControl) + && !(modifiers & NSEventModifierFlagOption) + && !(modifiers & NSEventModifierFlagCommand) + && !(modifiers & NSEventModifierFlagFunction); } @@ -373,7 +373,7 @@ void ProcessKeyboardEventInMenu(NSEvent* theEvent) unichar realchar; event.type = EV_GUI_Event; - event.subtype = NSKeyDown == [theEvent type] ? EV_GUI_KeyDown : EV_GUI_KeyUp; + event.subtype = NSEventTypeKeyDown == [theEvent type] ? EV_GUI_KeyDown : EV_GUI_KeyUp; event.data2 = GetCharacterFromNSEvent(theEvent, &realchar); event.data3 = ModifierFlagsToGUIKeyModifiers(theEvent); @@ -505,8 +505,8 @@ void ProcessKeyboardEvent(NSEvent* theEvent) if (k_allowfullscreentoggle && (kVK_ANSI_F == keyCode) - && (NSCommandKeyMask & [theEvent modifierFlags]) - && (NSKeyDown == [theEvent type]) + && (NSEventModifierFlagCommand & [theEvent modifierFlags]) + && (NSEventTypeKeyDown == [theEvent type]) && !isARepeat) { ToggleFullscreen = !ToggleFullscreen; @@ -521,7 +521,7 @@ void ProcessKeyboardEvent(NSEvent* theEvent) { event_t event = {}; - event.type = NSKeyDown == [theEvent type] ? EV_KeyDown : EV_KeyUp; + event.type = NSEventTypeKeyDown == [theEvent type] ? EV_KeyDown : EV_KeyUp; event.data1 = KEYCODE_TO_DIK[ keyCode ]; if (0 != event.data1) @@ -542,7 +542,7 @@ void ProcessKeyboardFlagsEvent(NSEvent* theEvent) } static const uint32_t FLAGS_MASK = - NSDeviceIndependentModifierFlagsMask & ~NSNumericPadKeyMask; + NSEventModifierFlagDeviceIndependentFlagsMask & ~NSEventModifierFlagNumericPad; const uint32_t modifiers = [theEvent modifierFlags] & FLAGS_MASK; static uint32_t oldModifiers = 0; @@ -611,12 +611,12 @@ void ProcessMouseButtonEvent(NSEvent* theEvent) switch (cocoaEventType) { - case NSLeftMouseDown: event.subtype = EV_GUI_LButtonDown; break; - case NSRightMouseDown: event.subtype = EV_GUI_RButtonDown; break; - case NSOtherMouseDown: event.subtype = EV_GUI_MButtonDown; break; - case NSLeftMouseUp: event.subtype = EV_GUI_LButtonUp; break; - case NSRightMouseUp: event.subtype = EV_GUI_RButtonUp; break; - case NSOtherMouseUp: event.subtype = EV_GUI_MButtonUp; break; + case NSEventTypeLeftMouseDown: event.subtype = EV_GUI_LButtonDown; break; + case NSEventTypeRightMouseDown: event.subtype = EV_GUI_RButtonDown; break; + case NSEventTypeOtherMouseDown: event.subtype = EV_GUI_MButtonDown; break; + case NSEventTypeLeftMouseUp: event.subtype = EV_GUI_LButtonUp; break; + case NSEventTypeRightMouseUp: event.subtype = EV_GUI_RButtonUp; break; + case NSEventTypeOtherMouseUp: event.subtype = EV_GUI_MButtonUp; break; default: break; } @@ -628,15 +628,15 @@ void ProcessMouseButtonEvent(NSEvent* theEvent) { switch (cocoaEventType) { - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: + case NSEventTypeLeftMouseDown: + case NSEventTypeRightMouseDown: + case NSEventTypeOtherMouseDown: event.type = EV_KeyDown; break; - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseUp: event.type = EV_KeyUp; break; @@ -644,7 +644,7 @@ void ProcessMouseButtonEvent(NSEvent* theEvent) break; } - event.data1 = MIN(KEY_MOUSE1 + [theEvent buttonNumber], NSInteger(KEY_MOUSE8)); + event.data1 = min(KEY_MOUSE1 + [theEvent buttonNumber], NSInteger(KEY_MOUSE8)); D_PostEvent(&event); } @@ -694,36 +694,36 @@ void I_ProcessEvent(NSEvent* event) switch (eventType) { - case NSMouseMoved: + case NSEventTypeMouseMoved: ProcessMouseMoveEvent(event); break; - case NSLeftMouseDown: - case NSLeftMouseUp: - case NSRightMouseDown: - case NSRightMouseUp: - case NSOtherMouseDown: - case NSOtherMouseUp: + case NSEventTypeLeftMouseDown: + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseDown: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseDown: + case NSEventTypeOtherMouseUp: ProcessMouseButtonEvent(event); break; - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: + case NSEventTypeLeftMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeOtherMouseDragged: ProcessMouseButtonEvent(event); ProcessMouseMoveEvent(event); break; - case NSScrollWheel: + case NSEventTypeScrollWheel: ProcessMouseWheelEvent(event); break; - case NSKeyDown: - case NSKeyUp: + case NSEventTypeKeyDown: + case NSEventTypeKeyUp: ProcessKeyboardEvent(event); break; - case NSFlagsChanged: + case NSEventTypeFlagsChanged: ProcessKeyboardFlagsEvent(event); break; diff --git a/source/common/platform/posix/cocoa/i_joystick.cpp b/source/common/platform/posix/cocoa/i_joystick.cpp index 9a003acac..2bbfedb1d 100644 --- a/source/common/platform/posix/cocoa/i_joystick.cpp +++ b/source/common/platform/posix/cocoa/i_joystick.cpp @@ -39,7 +39,7 @@ #include "i_system.h" #include "m_argv.h" #include "m_joy.h" -#include "templates.h" + #include "v_text.h" #include "printf.h" #include "keydef.h" diff --git a/source/common/platform/posix/cocoa/i_main.mm b/source/common/platform/posix/cocoa/i_main.mm index ea7040ee5..727edef78 100644 --- a/source/common/platform/posix/cocoa/i_main.mm +++ b/source/common/platform/posix/cocoa/i_main.mm @@ -73,23 +73,6 @@ void Mac_I_FatalError(const char* const message) } -#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000 - -// Available since 10.9 with no public declaration/definition until 10.10 - -struct NSOperatingSystemVersion -{ - NSInteger majorVersion; - NSInteger minorVersion; - NSInteger patchVersion; -}; - -@interface NSProcessInfo(OperatingSystemVersion) -- (NSOperatingSystemVersion)operatingSystemVersion; -@end - -#endif // before 10.10 - static bool ReadSystemVersionFromPlist(NSOperatingSystemVersion& version) { #if MAC_OS_X_VERSION_MAX_ALLOWED < 110000 @@ -169,9 +152,6 @@ void I_DetectOS() case 10: switch (version.minorVersion) { - case 9: name = "OS X Mavericks"; break; - case 10: name = "OS X Yosemite"; break; - case 11: name = "OS X El Capitan"; break; case 12: name = "macOS Sierra"; break; case 13: name = "macOS High Sierra"; break; case 14: name = "macOS Mojave"; break; @@ -196,9 +176,7 @@ void I_DetectOS() sysctlbyname("hw.model", model, &size, nullptr, 0); const char* const architecture = -#ifdef __i386__ - "32-bit Intel"; -#elif defined __x86_64__ +#ifdef __x86_64__ "64-bit Intel"; #elif defined __aarch64__ "64-bit ARM"; @@ -396,7 +374,7 @@ extern bool AppActive; while (true) { - NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate dateWithTimeIntervalSinceNow:0] inMode:NSDefaultRunLoopMode dequeue:YES]; @@ -449,7 +427,7 @@ NSMenuItem* CreateApplicationMenu() [[menu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"] - setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask]; + setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand]; [menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; diff --git a/source/common/platform/posix/cocoa/i_video.mm b/source/common/platform/posix/cocoa/i_video.mm index a306433b8..8f730e488 100644 --- a/source/common/platform/posix/cocoa/i_video.mm +++ b/source/common/platform/posix/cocoa/i_video.mm @@ -121,8 +121,8 @@ namespace const NSInteger LEVEL_FULLSCREEN = NSMainMenuWindowLevel + 1; const NSInteger LEVEL_WINDOWED = NSNormalWindowLevel; - const NSUInteger STYLE_MASK_FULLSCREEN = NSBorderlessWindowMask; - const NSUInteger STYLE_MASK_WINDOWED = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask; + const NSUInteger STYLE_MASK_FULLSCREEN = NSWindowStyleMaskBorderless; + const NSUInteger STYLE_MASK_WINDOWED = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable; } @@ -969,7 +969,7 @@ bool I_GetVulkanPlatformExtensions(unsigned int *count, const char **names) else { const bool result = *count >= extensionCount; - *count = std::min(*count, extensionCount); + *count = min(*count, extensionCount); for (unsigned int i = 0; i < *count; ++i) { diff --git a/source/common/platform/posix/cocoa/st_console.mm b/source/common/platform/posix/cocoa/st_console.mm index b4c0878c8..1c45776e6 100644 --- a/source/common/platform/posix/cocoa/st_console.mm +++ b/source/common/platform/posix/cocoa/st_console.mm @@ -104,7 +104,7 @@ FConsoleWindow::FConsoleWindow() NSString* const title = [NSString stringWithFormat:@"%s %s - Console", GAMENAME, GetVersionString()]; [m_window initWithContentRect:initialRect - styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask + styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO]; [m_window setMinSize:[m_window frame].size]; @@ -348,7 +348,7 @@ void FConsoleWindow::SetTitleText() NSTextField* titleText = [[NSTextField alloc] initWithFrame:titleTextRect]; [titleText setStringValue:[NSString stringWithCString:GameStartupInfo.Name.GetChars() encoding:NSISOLatin1StringEncoding]]; - [titleText setAlignment:NSCenterTextAlignment]; + [titleText setAlignment:NSTextAlignmentCenter]; [titleText setTextColor:RGB(GameStartupInfo.FgColor)]; [titleText setBackgroundColor:RGB(GameStartupInfo.BkColor)]; [titleText setFont:[NSFont fontWithName:@"Trebuchet MS Bold" size:18.0f]]; @@ -434,7 +434,7 @@ void FConsoleWindow::NetInit(const char* const message, const int playerCount) // Text with connected/total players count m_netCountText = [[NSTextField alloc] initWithFrame:NSMakeRect(428.0f, 64.0f, 72.0f, 16.0f)]; [m_netCountText setAutoresizingMask:NSViewMinXMargin]; - [m_netCountText setAlignment:NSRightTextAlignment]; + [m_netCountText setAlignment:NSTextAlignmentRight]; [m_netCountText setDrawsBackground:NO]; [m_netCountText setSelectable:NO]; [m_netCountText setBordered:NO]; @@ -510,7 +510,7 @@ void FConsoleWindow::NetProgress(const int count) if (m_netMaxPos > 1) { [m_netCountText setStringValue:[NSString stringWithFormat:@"%d / %d", m_netCurPos, m_netMaxPos]]; - [m_netProgressBar setDoubleValue:MIN(m_netCurPos, m_netMaxPos)]; + [m_netProgressBar setDoubleValue:min(m_netCurPos, m_netMaxPos)]; } } diff --git a/source/common/platform/posix/osx/iwadpicker_cocoa.mm b/source/common/platform/posix/osx/iwadpicker_cocoa.mm index e4740ea2a..4ff7d737b 100644 --- a/source/common/platform/posix/osx/iwadpicker_cocoa.mm +++ b/source/common/platform/posix/osx/iwadpicker_cocoa.mm @@ -194,7 +194,7 @@ static NSArray* GetKnownExtensions() [openPanel setResolvesAliases:YES]; [openPanel setAllowedFileTypes:GetKnownExtensions()]; - if (NSOKButton == [openPanel runModal]) + if (NSModalResponseOK == [openPanel runModal]) { NSArray* files = [openPanel URLs]; NSMutableString* parameters = [NSMutableString string]; @@ -259,7 +259,7 @@ static NSArray* GetKnownExtensions() id windowTitle = [NSString stringWithFormat:@"%s %s", GAMENAME, GetVersionString()]; NSRect frame = NSMakeRect(0, 0, 440, 450); - window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]; + window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSWindowStyleMaskTitled backing:NSBackingStoreBuffered defer:NO]; [window setTitle:windowTitle]; NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(18, 384, 402, 50)]; diff --git a/source/common/platform/posix/sdl/i_joystick.cpp b/source/common/platform/posix/sdl/i_joystick.cpp index fe4b25eb6..0fa33ba63 100644 --- a/source/common/platform/posix/sdl/i_joystick.cpp +++ b/source/common/platform/posix/sdl/i_joystick.cpp @@ -34,7 +34,7 @@ #include "basics.h" #include "cmdlib.h" -#include "templates.h" + #include "m_joy.h" #include "keydef.h" diff --git a/source/common/platform/win32/base_sysfb.cpp b/source/common/platform/win32/base_sysfb.cpp index 3cb8858a3..9c9bb4a54 100644 --- a/source/common/platform/win32/base_sysfb.cpp +++ b/source/common/platform/win32/base_sysfb.cpp @@ -39,7 +39,7 @@ #include "gl_sysfb.h" #include "hardware.h" -#include "templates.h" + #include "version.h" #include "c_console.h" #include "v_video.h" diff --git a/source/common/platform/win32/gl_sysfb.cpp b/source/common/platform/win32/gl_sysfb.cpp index 17822d213..8aa266883 100644 --- a/source/common/platform/win32/gl_sysfb.cpp +++ b/source/common/platform/win32/gl_sysfb.cpp @@ -39,7 +39,7 @@ #include "gl_sysfb.h" #include "hardware.h" -#include "templates.h" + #include "version.h" #include "c_console.h" #include "v_video.h" diff --git a/source/common/platform/win32/hardware.cpp b/source/common/platform/win32/hardware.cpp index 3cadc1ced..13e799594 100644 --- a/source/common/platform/win32/hardware.cpp +++ b/source/common/platform/win32/hardware.cpp @@ -111,9 +111,9 @@ void I_InitGraphics () // todo: implement ATI version of this. this only works for nvidia notebooks, for now. currentgpuswitch = vid_gpuswitch; if (currentgpuswitch == 1) - putenv("SHIM_MCCOMPAT=0x800000001"); // discrete + _putenv("SHIM_MCCOMPAT=0x800000001"); // discrete else if (currentgpuswitch == 2) - putenv("SHIM_MCCOMPAT=0x800000000"); // integrated + _putenv("SHIM_MCCOMPAT=0x800000000"); // integrated // If the focus window is destroyed, it doesn't go back to the active window. // (e.g. because the net pane was up, and a button on it had focus) diff --git a/source/common/platform/win32/i_crash.cpp b/source/common/platform/win32/i_crash.cpp index 90c0658f1..df2a6241e 100644 --- a/source/common/platform/win32/i_crash.cpp +++ b/source/common/platform/win32/i_crash.cpp @@ -34,6 +34,7 @@ // HEADER FILES ------------------------------------------------------------ +#pragma warning(disable:4996) #define WIN32_LEAN_AND_MEAN #include #include diff --git a/source/common/platform/win32/i_dijoy.cpp b/source/common/platform/win32/i_dijoy.cpp index 79b6fcf8f..e4021cc10 100644 --- a/source/common/platform/win32/i_dijoy.cpp +++ b/source/common/platform/win32/i_dijoy.cpp @@ -45,7 +45,7 @@ #include "i_input.h" #include "d_eventbase.h" -#include "templates.h" + #include "gameconfigfile.h" #include "cmdlib.h" #include "v_text.h" diff --git a/source/common/platform/win32/i_rawps2.cpp b/source/common/platform/win32/i_rawps2.cpp index 2a7547f3e..90e575a71 100644 --- a/source/common/platform/win32/i_rawps2.cpp +++ b/source/common/platform/win32/i_rawps2.cpp @@ -38,7 +38,7 @@ #include "i_input.h" #include "d_eventbase.h" -#include "templates.h" + #include "gameconfigfile.h" #include "m_argv.h" #include "cmdlib.h" diff --git a/source/common/platform/win32/i_system.cpp b/source/common/platform/win32/i_system.cpp index 103b26f31..0ec546567 100644 --- a/source/common/platform/win32/i_system.cpp +++ b/source/common/platform/win32/i_system.cpp @@ -45,6 +45,7 @@ // HEADER FILES ------------------------------------------------------------ +#pragma warning(disable:4996) #include #include #include @@ -73,7 +74,7 @@ #include "i_input.h" #include "c_dispatch.h" -#include "templates.h" + #include "gameconfigfile.h" #include "v_font.h" #include "i_system.h" @@ -778,7 +779,7 @@ static HCURSOR CreateAlphaCursor(FBitmap &source, int leftofs, int topofs) // Find closest integer scale factor for the monitor DPI HDC screenDC = GetDC(0); int dpi = GetDeviceCaps(screenDC, LOGPIXELSX); - int scale = std::max((dpi + 96 / 2 - 1) / 96, 1); + int scale = max((dpi + 96 / 2 - 1) / 96, 1); ReleaseDC(0, screenDC); memset(&bi, 0, sizeof(bi)); diff --git a/source/common/platform/win32/i_xinput.cpp b/source/common/platform/win32/i_xinput.cpp index 7085de82f..2e8b79dc3 100644 --- a/source/common/platform/win32/i_xinput.cpp +++ b/source/common/platform/win32/i_xinput.cpp @@ -40,7 +40,7 @@ #include "i_input.h" #include "d_eventbase.h" -#include "templates.h" + #include "gameconfigfile.h" #include "m_argv.h" #include "cmdlib.h" diff --git a/source/common/platform/win32/st_start.cpp b/source/common/platform/win32/st_start.cpp index f36371a9b..71ff4b1cd 100644 --- a/source/common/platform/win32/st_start.cpp +++ b/source/common/platform/win32/st_start.cpp @@ -41,7 +41,7 @@ #include "st_start.h" #include "cmdlib.h" -#include "templates.h" + #include "i_system.h" #include "i_input.h" #include "hardware.h" @@ -351,7 +351,7 @@ void FBasicStartupScreen :: NetProgress(int count) mysnprintf (buf, countof(buf), "%d/%d", NetCurPos, NetMaxPos); SetDlgItemTextA (NetStartPane, IDC_NETSTARTCOUNT, buf); - SendDlgItemMessage (NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, std::min(NetCurPos, NetMaxPos), 0); + SendDlgItemMessage (NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, min(NetCurPos, NetMaxPos), 0); } } diff --git a/source/common/platform/win32/st_start_util.cpp b/source/common/platform/win32/st_start_util.cpp index 8c6074863..bfad11662 100644 --- a/source/common/platform/win32/st_start_util.cpp +++ b/source/common/platform/win32/st_start_util.cpp @@ -831,7 +831,7 @@ void FStrifeStartupScreen::DrawStuff(int old_laser, int new_laser) ST_LASERSPACE_X + new_laser, ST_LASERSPACE_Y, ST_LASER_WIDTH, ST_LASER_HEIGHT); // The bot jumps up and down like crazy. - y = std::max(0, (new_laser >> 1) % 5 - 2); + y = max(0, (new_laser >> 1) % 5 - 2); if (y > 0) { ST_Util_ClearBlock(bitmap_info, 0xF0, ST_BOT_X, ST_BOT_Y, ST_BOT_WIDTH, y); diff --git a/source/common/platform/win32/win32basevideo.cpp b/source/common/platform/win32/win32basevideo.cpp index fc2ae67c4..b579b21f3 100644 --- a/source/common/platform/win32/win32basevideo.cpp +++ b/source/common/platform/win32/win32basevideo.cpp @@ -35,7 +35,7 @@ #include #include "hardware.h" -#include "templates.h" + #include "version.h" #include "c_console.h" #include "v_video.h" diff --git a/source/common/platform/win32/win32glvideo.cpp b/source/common/platform/win32/win32glvideo.cpp index abc9768cc..3508f07da 100644 --- a/source/common/platform/win32/win32glvideo.cpp +++ b/source/common/platform/win32/win32glvideo.cpp @@ -40,7 +40,7 @@ #include "gl_sysfb.h" #include "hardware.h" -#include "templates.h" + #include "version.h" #include "c_console.h" #include "v_video.h" diff --git a/source/common/platform/win32/zutil.natvis b/source/common/platform/win32/zutil.natvis index 156594329..9a257a7cf 100644 --- a/source/common/platform/win32/zutil.natvis +++ b/source/common/platform/win32/zutil.natvis @@ -25,6 +25,17 @@ + + Size = {Count} + + Count + + Count + (value_type*)Array + + + + Size = {Count} diff --git a/source/common/rendering/gl/gl_buffers.cpp b/source/common/rendering/gl/gl_buffers.cpp index 47970b401..9338fee98 100644 --- a/source/common/rendering/gl/gl_buffers.cpp +++ b/source/common/rendering/gl/gl_buffers.cpp @@ -76,16 +76,20 @@ void GLBuffer::Bind() } -void GLBuffer::SetData(size_t size, const void *data, bool staticdata) +void GLBuffer::SetData(size_t size, const void *data, BufferUsageType usage) { Bind(); - if (data != nullptr) + if (usage == BufferUsageType::Static) { - glBufferData(mUseType, size, data, staticdata? GL_STATIC_DRAW : GL_STREAM_DRAW); + glBufferData(mUseType, size, data, GL_STATIC_DRAW); } - else + else if (usage == BufferUsageType::Stream) { - mPersistent = screen->BuffersArePersistent() && !staticdata; + glBufferData(mUseType, size, data, GL_STREAM_DRAW); + } + else if (usage == BufferUsageType::Persistent) + { + mPersistent = screen->BuffersArePersistent(); if (mPersistent) { glBufferStorage(mUseType, size, nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); @@ -93,10 +97,15 @@ void GLBuffer::SetData(size_t size, const void *data, bool staticdata) } else { - glBufferData(mUseType, size, nullptr, staticdata ? GL_STATIC_DRAW : GL_STREAM_DRAW); + glBufferData(mUseType, size, nullptr, GL_STREAM_DRAW); map = nullptr; } - if (!staticdata) nomap = false; + nomap = false; + } + else if (usage == BufferUsageType::Mappable) + { + glBufferData(mUseType, size, nullptr, GL_STATIC_DRAW); + map = nullptr; } buffersize = size; InvalidateBufferState(); @@ -134,7 +143,7 @@ void GLBuffer::Unmap() void *GLBuffer::Lock(unsigned int size) { // This initializes this buffer as a static object with no data. - SetData(size, nullptr, true); + SetData(size, nullptr, BufferUsageType::Mappable); return glMapBufferRange(mUseType, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT); } @@ -158,7 +167,7 @@ void GLBuffer::Resize(size_t newsize) glUnmapBuffer(mUseType); glGenBuffers(1, &mBufferId); - SetData(newsize, nullptr, false); + SetData(newsize, nullptr, BufferUsageType::Persistent); glBindBuffer(GL_COPY_READ_BUFFER, oldbuffer); // copy contents and delete the old buffer. diff --git a/source/common/rendering/gl/gl_buffers.h b/source/common/rendering/gl/gl_buffers.h index 0141ece5f..d0c2b62c8 100644 --- a/source/common/rendering/gl/gl_buffers.h +++ b/source/common/rendering/gl/gl_buffers.h @@ -24,7 +24,7 @@ protected: GLBuffer(int usetype); ~GLBuffer(); - void SetData(size_t size, const void *data, bool staticdata) override; + void SetData(size_t size, const void *data, BufferUsageType usage) override; void SetSubData(size_t offset, size_t size, const void *data) override; void Map() override; void Unmap() override; diff --git a/source/common/rendering/gl/gl_debug.cpp b/source/common/rendering/gl/gl_debug.cpp index c6c3adbfc..38625e73d 100644 --- a/source/common/rendering/gl/gl_debug.cpp +++ b/source/common/rendering/gl/gl_debug.cpp @@ -19,7 +19,7 @@ ** 3. This notice may not be removed or altered from any source distribution. */ -#include "templates.h" + #include "gl_system.h" #include "gl_debug.h" #include "stats.h" diff --git a/source/common/rendering/gl/gl_framebuffer.cpp b/source/common/rendering/gl/gl_framebuffer.cpp index 668965a11..4e1af90b2 100644 --- a/source/common/rendering/gl/gl_framebuffer.cpp +++ b/source/common/rendering/gl/gl_framebuffer.cpp @@ -36,7 +36,7 @@ #include "gl_system.h" #include "v_video.h" #include "m_png.h" -#include "templates.h" + #include "i_time.h" #include "gl_interface.h" diff --git a/source/common/rendering/gl/gl_hwtexture.cpp b/source/common/rendering/gl/gl_hwtexture.cpp index 0043a67b8..a23ef82cc 100644 --- a/source/common/rendering/gl/gl_hwtexture.cpp +++ b/source/common/rendering/gl/gl_hwtexture.cpp @@ -34,7 +34,7 @@ */ #include "gl_system.h" -#include "templates.h" + #include "c_cvars.h" #include "hw_material.h" diff --git a/source/common/rendering/gl/gl_postprocess.cpp b/source/common/rendering/gl/gl_postprocess.cpp index 949fee4b0..f5ec0bfae 100644 --- a/source/common/rendering/gl/gl_postprocess.cpp +++ b/source/common/rendering/gl/gl_postprocess.cpp @@ -33,7 +33,7 @@ #include "flatvertices.h" #include "r_videoscale.h" #include "v_video.h" -#include "templates.h" + #include "hw_vrmodes.h" #include "v_draw.h" diff --git a/source/common/rendering/gl/gl_postprocessstate.cpp b/source/common/rendering/gl/gl_postprocessstate.cpp index 2e6a04f05..e490e8708 100644 --- a/source/common/rendering/gl/gl_postprocessstate.cpp +++ b/source/common/rendering/gl/gl_postprocessstate.cpp @@ -19,7 +19,7 @@ ** 3. This notice may not be removed or altered from any source distribution. */ -#include "templates.h" + #include "gl_system.h" #include "gl_interface.h" #include "gl_postprocessstate.h" diff --git a/source/common/rendering/gl/gl_renderbuffers.cpp b/source/common/rendering/gl/gl_renderbuffers.cpp index a1d8899bb..08c3de3c1 100644 --- a/source/common/rendering/gl/gl_renderbuffers.cpp +++ b/source/common/rendering/gl/gl_renderbuffers.cpp @@ -30,7 +30,7 @@ #include "gl_postprocessstate.h" #include "gl_shaderprogram.h" #include "gl_buffers.h" -#include "templates.h" + #include EXTERN_CVAR(Int, gl_debug_level) @@ -952,7 +952,7 @@ void GLPPRenderState::Draw() { if (!shader->Uniforms) shader->Uniforms.reset(screen->CreateDataBuffer(POSTPROCESS_BINDINGPOINT, false, false)); - shader->Uniforms->SetData(Uniforms.Data.Size(), Uniforms.Data.Data()); + shader->Uniforms->SetData(Uniforms.Data.Size(), Uniforms.Data.Data(), BufferUsageType::Static); static_cast(shader->Uniforms.get())->BindBase(); } diff --git a/source/common/rendering/gl/gl_renderstate.cpp b/source/common/rendering/gl/gl_renderstate.cpp index c660fb98e..d742f35fd 100644 --- a/source/common/rendering/gl/gl_renderstate.cpp +++ b/source/common/rendering/gl/gl_renderstate.cpp @@ -25,7 +25,7 @@ ** */ -#include "templates.h" + #include "gl_system.h" #include "gl_interface.h" #include "hw_cvars.h" diff --git a/source/common/rendering/gl/gl_renderstate.h b/source/common/rendering/gl/gl_renderstate.h index 948255d71..9cfe3d7a2 100644 --- a/source/common/rendering/gl/gl_renderstate.h +++ b/source/common/rendering/gl/gl_renderstate.h @@ -107,7 +107,7 @@ public: void EnableDrawBuffers(int count, bool apply = false) override { - count = std::min(count, 3); + count = min(count, 3); if (mNumDrawBuffers != count) { static GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; diff --git a/source/common/rendering/gl/gl_shader.cpp b/source/common/rendering/gl/gl_shader.cpp index 2ef56a288..60c5677a6 100644 --- a/source/common/rendering/gl/gl_shader.cpp +++ b/source/common/rendering/gl/gl_shader.cpp @@ -49,6 +49,8 @@ #include #include +EXTERN_CVAR(Bool, r_skipmats) + namespace OpenGLRenderer { @@ -729,6 +731,9 @@ FShader *FShaderManager::BindEffect(int effect, EPassType passType) FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passType) { + if (r_skipmats && eff >= 3 && eff <= 4) + eff = 0; + if (passType < mPassShaders.Size()) return mPassShaders[passType]->Get(eff, alphateston); else diff --git a/source/common/rendering/gl/gl_shaderprogram.cpp b/source/common/rendering/gl/gl_shaderprogram.cpp index eb322fb94..2b6df3254 100644 --- a/source/common/rendering/gl/gl_shaderprogram.cpp +++ b/source/common/rendering/gl/gl_shaderprogram.cpp @@ -263,7 +263,7 @@ FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const // If we have 4.2, always use it because it adds important new syntax. if (maxGlslVersion < 420 && gl.glslversion >= 4.2f) maxGlslVersion = 420; - int shaderVersion = std::min((int)round(gl.glslversion * 10) * 10, maxGlslVersion); + int shaderVersion = min((int)round(gl.glslversion * 10) * 10, maxGlslVersion); patchedCode.AppendFormat("#version %d\n", shaderVersion); // TODO: Find some way to add extension requirements to the patching diff --git a/source/common/rendering/gl/gl_stereo3d.cpp b/source/common/rendering/gl/gl_stereo3d.cpp index 35bcf2fa0..5f3f41008 100644 --- a/source/common/rendering/gl/gl_stereo3d.cpp +++ b/source/common/rendering/gl/gl_stereo3d.cpp @@ -34,7 +34,7 @@ #include "gl_framebuffer.h" #include "gl_shaderprogram.h" #include "gl_buffers.h" -#include "templates.h" + EXTERN_CVAR(Int, vr_mode) EXTERN_CVAR(Float, vid_saturation) diff --git a/source/common/rendering/gles/gles_buffers.cpp b/source/common/rendering/gles/gles_buffers.cpp index f3ffcfcc6..de815ea34 100644 --- a/source/common/rendering/gles/gles_buffers.cpp +++ b/source/common/rendering/gles/gles_buffers.cpp @@ -93,8 +93,9 @@ void GLBuffer::Bind() } -void GLBuffer::SetData(size_t size, const void* data, bool staticdata) +void GLBuffer::SetData(size_t size, const void* data, BufferUsageType usage) { + bool staticdata = (usage == BufferUsageType::Static || usage == BufferUsageType::Mappable); if (isData || !gles.useMappedBuffers) { if (memory) @@ -175,7 +176,7 @@ void GLBuffer::Unmap() void *GLBuffer::Lock(unsigned int size) { // This initializes this buffer as a static object with no data. - SetData(size, nullptr, true); + SetData(size, nullptr, BufferUsageType::Mappable); if (!isData && gles.useMappedBuffers) { return glMapBufferRange(mUseType, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT); diff --git a/source/common/rendering/gles/gles_buffers.h b/source/common/rendering/gles/gles_buffers.h index 0bd205351..d9e01ece6 100644 --- a/source/common/rendering/gles/gles_buffers.h +++ b/source/common/rendering/gles/gles_buffers.h @@ -26,7 +26,7 @@ protected: GLBuffer(int usetype); ~GLBuffer(); - void SetData(size_t size, const void *data, bool staticdata) override; + void SetData(size_t size, const void *data, BufferUsageType usage) override; void SetSubData(size_t offset, size_t size, const void *data) override; void Map() override; void Unmap() override; diff --git a/source/common/rendering/gles/gles_framebuffer.cpp b/source/common/rendering/gles/gles_framebuffer.cpp index 3a74ee6bc..3391a6f02 100644 --- a/source/common/rendering/gles/gles_framebuffer.cpp +++ b/source/common/rendering/gles/gles_framebuffer.cpp @@ -36,7 +36,7 @@ #include "gles_system.h" #include "v_video.h" #include "m_png.h" -#include "templates.h" + #include "i_time.h" #include "gles_framebuffer.h" @@ -122,7 +122,7 @@ void OpenGLFrameBuffer::InitializeState() { static bool first=true; - mPipelineNbr = gl_pipeline_depth == 0? std::min(4, HW_MAX_PIPELINE_BUFFERS) : clamp(*gl_pipeline_depth, 1, HW_MAX_PIPELINE_BUFFERS); + mPipelineNbr = gl_pipeline_depth == 0? min(4, HW_MAX_PIPELINE_BUFFERS) : clamp(*gl_pipeline_depth, 1, HW_MAX_PIPELINE_BUFFERS); mPipelineType = 1; InitGLES(); diff --git a/source/common/rendering/gles/gles_hwtexture.cpp b/source/common/rendering/gles/gles_hwtexture.cpp index 00370481b..a342f24c2 100644 --- a/source/common/rendering/gles/gles_hwtexture.cpp +++ b/source/common/rendering/gles/gles_hwtexture.cpp @@ -34,7 +34,7 @@ */ #include "gles_system.h" -#include "templates.h" + #include "c_cvars.h" #include "hw_material.h" diff --git a/source/common/rendering/gles/gles_postprocess.cpp b/source/common/rendering/gles/gles_postprocess.cpp index 0e909da2d..bd78d294c 100644 --- a/source/common/rendering/gles/gles_postprocess.cpp +++ b/source/common/rendering/gles/gles_postprocess.cpp @@ -32,7 +32,7 @@ #include "flatvertices.h" #include "r_videoscale.h" #include "v_video.h" -#include "templates.h" + #include "hw_vrmodes.h" #include "v_draw.h" diff --git a/source/common/rendering/gles/gles_postprocessstate.cpp b/source/common/rendering/gles/gles_postprocessstate.cpp index 216406125..ea8921837 100644 --- a/source/common/rendering/gles/gles_postprocessstate.cpp +++ b/source/common/rendering/gles/gles_postprocessstate.cpp @@ -19,7 +19,7 @@ ** 3. This notice may not be removed or altered from any source distribution. */ -#include "templates.h" + #include "gles_system.h" #include "gles_postprocessstate.h" diff --git a/source/common/rendering/gles/gles_renderbuffers.cpp b/source/common/rendering/gles/gles_renderbuffers.cpp index 91f8ce462..1d8147ae1 100644 --- a/source/common/rendering/gles/gles_renderbuffers.cpp +++ b/source/common/rendering/gles/gles_renderbuffers.cpp @@ -28,7 +28,7 @@ #include "gles_postprocessstate.h" #include "gles_shaderprogram.h" #include "gles_buffers.h" -#include "templates.h" + #include EXTERN_CVAR(Int, gl_debug_level) diff --git a/source/common/rendering/gles/gles_renderstate.cpp b/source/common/rendering/gles/gles_renderstate.cpp index 0a9e4ca13..961ec8121 100644 --- a/source/common/rendering/gles/gles_renderstate.cpp +++ b/source/common/rendering/gles/gles_renderstate.cpp @@ -25,7 +25,7 @@ ** */ -#include "templates.h" + #include "gles_system.h" #include "hw_cvars.h" #include "flatvertices.h" diff --git a/source/common/rendering/gles/gles_renderstate.h b/source/common/rendering/gles/gles_renderstate.h index 7b7768541..4dd8516ec 100644 --- a/source/common/rendering/gles/gles_renderstate.h +++ b/source/common/rendering/gles/gles_renderstate.h @@ -109,7 +109,7 @@ public: void EnableDrawBuffers(int count, bool apply = false) override { /* - count = std::min(count, 3); + count = min(count, 3); if (mNumDrawBuffers != count) { static GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; diff --git a/source/common/rendering/gles/gles_shaderprogram.h b/source/common/rendering/gles/gles_shaderprogram.h index a8dc97428..e46418054 100644 --- a/source/common/rendering/gles/gles_shaderprogram.h +++ b/source/common/rendering/gles/gles_shaderprogram.h @@ -88,7 +88,7 @@ public: void SetData() { if (mBuffer != nullptr) - mBuffer->SetData(sizeof(T), &Values); + mBuffer->SetData(sizeof(T), &Values, BufferUsageType::Static); } IDataBuffer* GetBuffer() const diff --git a/source/common/rendering/hwrenderer/data/buffers.h b/source/common/rendering/hwrenderer/data/buffers.h index 586e5caa0..980adde5e 100644 --- a/source/common/rendering/hwrenderer/data/buffers.h +++ b/source/common/rendering/hwrenderer/data/buffers.h @@ -46,6 +46,14 @@ struct FVertexBufferAttribute int offset; }; +enum class BufferUsageType +{ + Static, // initial data is not null, staticdata is true + Stream, // initial data is not null, staticdata is false + Persistent, // initial data is null, staticdata is false + Mappable // initial data is null, staticdata is true +}; + class IBuffer { protected: @@ -57,7 +65,7 @@ public: IBuffer &operator=(const IBuffer &) = delete; virtual ~IBuffer() = default; - virtual void SetData(size_t size, const void *data, bool staticdata = true) = 0; + virtual void SetData(size_t size, const void *data, BufferUsageType type) = 0; virtual void SetSubData(size_t offset, size_t size, const void *data) = 0; virtual void *Lock(unsigned int size) = 0; virtual void Unlock() = 0; diff --git a/source/common/rendering/hwrenderer/data/flatvertices.cpp b/source/common/rendering/hwrenderer/data/flatvertices.cpp index 9a34b45ff..6fe258b26 100644 --- a/source/common/rendering/hwrenderer/data/flatvertices.cpp +++ b/source/common/rendering/hwrenderer/data/flatvertices.cpp @@ -81,7 +81,7 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height, int pipelineNbr): mIndexBuffer = screen->CreateIndexBuffer(); int data[4] = {}; - mIndexBuffer->SetData(4, data); // On Vulkan this may not be empty, so set some dummy defaults to avoid crashes. + mIndexBuffer->SetData(4, data, BufferUsageType::Static); // On Vulkan this may not be empty, so set some dummy defaults to avoid crashes. for (int n = 0; n < mPipelineNbr; n++) @@ -89,7 +89,7 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height, int pipelineNbr): mVertexBufferPipeline[n] = screen->CreateVertexBuffer(); unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); - mVertexBufferPipeline[n]->SetData(bytesize, nullptr, false); + mVertexBufferPipeline[n]->SetData(bytesize, nullptr, BufferUsageType::Persistent); static const FVertexBufferAttribute format[] = { { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) }, diff --git a/source/common/rendering/hwrenderer/data/hw_lightbuffer.cpp b/source/common/rendering/hwrenderer/data/hw_lightbuffer.cpp index e0283d58e..9f7bb66c2 100644 --- a/source/common/rendering/hwrenderer/data/hw_lightbuffer.cpp +++ b/source/common/rendering/hwrenderer/data/hw_lightbuffer.cpp @@ -64,7 +64,7 @@ FLightBuffer::FLightBuffer(int pipelineNbr): for (int n = 0; n < mPipelineNbr; n++) { mBufferPipeline[n] = screen->CreateDataBuffer(LIGHTBUF_BINDINGPOINT, mBufferType, false); - mBufferPipeline[n]->SetData(mByteSize, nullptr, false); + mBufferPipeline[n]->SetData(mByteSize, nullptr, BufferUsageType::Persistent); } Clear(); diff --git a/source/common/rendering/hwrenderer/data/hw_shadowmap.cpp b/source/common/rendering/hwrenderer/data/hw_shadowmap.cpp index c5e5fb09b..26eaa2d2c 100644 --- a/source/common/rendering/hwrenderer/data/hw_shadowmap.cpp +++ b/source/common/rendering/hwrenderer/data/hw_shadowmap.cpp @@ -117,7 +117,7 @@ void IShadowMap::UploadLights() if (mLightList == nullptr) mLightList = screen->CreateDataBuffer(LIGHTLIST_BINDINGPOINT, true, false); - mLightList->SetData(sizeof(float) * mLights.Size(), &mLights[0]); + mLightList->SetData(sizeof(float) * mLights.Size(), &mLights[0], BufferUsageType::Stream); } @@ -129,11 +129,11 @@ void IShadowMap::UploadAABBTree() if (!mNodesBuffer) mNodesBuffer = screen->CreateDataBuffer(LIGHTNODES_BINDINGPOINT, true, false); - mNodesBuffer->SetData(mAABBTree->NodesSize(), mAABBTree->Nodes()); + mNodesBuffer->SetData(mAABBTree->NodesSize(), mAABBTree->Nodes(), BufferUsageType::Static); if (!mLinesBuffer) mLinesBuffer = screen->CreateDataBuffer(LIGHTLINES_BINDINGPOINT, true, false); - mLinesBuffer->SetData(mAABBTree->LinesSize(), mAABBTree->Lines()); + mLinesBuffer->SetData(mAABBTree->LinesSize(), mAABBTree->Lines(), BufferUsageType::Static); } else if (mAABBTree->Update()) { diff --git a/source/common/rendering/hwrenderer/data/hw_skydome.cpp b/source/common/rendering/hwrenderer/data/hw_skydome.cpp index 5d5ee8000..9bbe5787f 100644 --- a/source/common/rendering/hwrenderer/data/hw_skydome.cpp +++ b/source/common/rendering/hwrenderer/data/hw_skydome.cpp @@ -98,7 +98,7 @@ std::pair& R_GetSkyCapColor(FGameTexture* tex) const uint32_t* buffer = (const uint32_t*)bitmap.GetPixels(); if (buffer) { - sky.Colors.first = averageColor((uint32_t*)buffer, w * MIN(30, h), 0); + sky.Colors.first = averageColor((uint32_t*)buffer, w * min(30, h), 0); if (h > 30) { sky.Colors.second = averageColor(((uint32_t*)buffer) + (h - 30) * w, w * 30, 0); @@ -130,7 +130,7 @@ FSkyVertexBuffer::FSkyVertexBuffer() { 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(FSkyVertex, color) } }; mVertexBuffer->SetFormat(1, 3, sizeof(FSkyVertex), format); - mVertexBuffer->SetData(mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], true); + mVertexBuffer->SetData(mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], BufferUsageType::Static); } FSkyVertexBuffer::~FSkyVertexBuffer() diff --git a/source/common/rendering/hwrenderer/data/hw_skydome.h b/source/common/rendering/hwrenderer/data/hw_skydome.h index 2e10869bb..71ad85a08 100644 --- a/source/common/rendering/hwrenderer/data/hw_skydome.h +++ b/source/common/rendering/hwrenderer/data/hw_skydome.h @@ -12,10 +12,7 @@ struct HWSkyPortal; struct HWDrawInfo; // 57 world units roughly represent one sky texel for the glTranslate call. -enum -{ - skyoffsetfactor = 57 -}; +const int skyoffsetfactor = 57; struct FSkyVertex { diff --git a/source/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp b/source/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp index c37306b8a..89a5a8436 100644 --- a/source/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp +++ b/source/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp @@ -43,7 +43,7 @@ HWViewpointBuffer::HWViewpointBuffer(int pipelineNbr): for (int n = 0; n < mPipelineNbr; n++) { mBufferPipeline[n] = screen->CreateDataBuffer(VIEWPOINT_BINDINGPOINT, false, true); - mBufferPipeline[n]->SetData(mByteSize, nullptr, false); + mBufferPipeline[n]->SetData(mByteSize, nullptr, BufferUsageType::Persistent); } Clear(); diff --git a/source/common/rendering/hwrenderer/data/shaderuniforms.h b/source/common/rendering/hwrenderer/data/shaderuniforms.h index 2543b52b1..92995fcaa 100644 --- a/source/common/rendering/hwrenderer/data/shaderuniforms.h +++ b/source/common/rendering/hwrenderer/data/shaderuniforms.h @@ -129,7 +129,7 @@ public: void SetData() { if (mBuffer != nullptr) - mBuffer->SetData(sizeof(T), &Values); + mBuffer->SetData(sizeof(T), &Values, BufferUsageType::Static); } IDataBuffer* GetBuffer() const diff --git a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp index 7a31ac416..5034b7935 100644 --- a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp @@ -26,7 +26,7 @@ #include "hwrenderer/postprocessing/hw_postprocessshader.h" #include #include "texturemanager.h" -#include "templates.h" + #include "stats.h" Postprocess hw_postprocess; @@ -326,9 +326,9 @@ void PPLensDistort::Render(PPRenderState *renderstate) // Scale factor to keep sampling within the input texture float r2 = aspect * aspect * 0.25f + 0.25f; float sqrt_r2 = sqrt(r2); - float f0 = 1.0f + MAX(r2 * (k[0] + kcube[0] * sqrt_r2), 0.0f); - float f2 = 1.0f + MAX(r2 * (k[2] + kcube[2] * sqrt_r2), 0.0f); - float f = MAX(f0, f2); + float f0 = 1.0f + max(r2 * (k[0] + kcube[0] * sqrt_r2), 0.0f); + float f2 = 1.0f + max(r2 * (k[2] + kcube[2] * sqrt_r2), 0.0f); + float f = max(f0, f2); float scale = 1.0f / f; LensUniforms uniforms; @@ -498,8 +498,8 @@ void PPCameraExposure::Render(PPRenderState *renderstate, int sceneWidth, int sc void PPCameraExposure::UpdateTextures(int width, int height) { - int firstwidth = MAX(width / 2, 1); - int firstheight = MAX(height / 2, 1); + int firstwidth = max(width / 2, 1); + int firstheight = max(height / 2, 1); if (ExposureLevels.size() > 0 && ExposureLevels[0].Viewport.width == firstwidth && ExposureLevels[0].Viewport.height == firstheight) { @@ -511,8 +511,8 @@ void PPCameraExposure::UpdateTextures(int width, int height) int i = 0; do { - width = MAX(width / 2, 1); - height = MAX(height / 2, 1); + width = max(width / 2, 1); + height = max(height / 2, 1); PPExposureLevel blevel; blevel.Viewport.left = 0; @@ -746,7 +746,7 @@ void PPAmbientOcclusion::Render(PPRenderState *renderstate, float m5, int sceneW LinearDepthUniforms linearUniforms; linearUniforms.SampleIndex = 0; linearUniforms.LinearizeDepthA = 1.0f / screen->GetZFar() - 1.0f / screen->GetZNear(); - linearUniforms.LinearizeDepthB = MAX(1.0f / screen->GetZNear(), 1.e-8f); + linearUniforms.LinearizeDepthB = max(1.0f / screen->GetZNear(), 1.e-8f); linearUniforms.InverseDepthRangeA = 1.0f; linearUniforms.InverseDepthRangeB = 0.0f; linearUniforms.Scale = sceneScale; @@ -894,7 +894,7 @@ void PPShadowMap::Update(PPRenderState* renderstate) ///////////////////////////////////////////////////////////////////////////// -CVAR(Bool, gl_custompost, true, 0) +CVAR(Bool, gl_custompost, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) void PPCustomShaders::Run(PPRenderState *renderstate, FString target) { diff --git a/source/common/rendering/i_modelvertexbuffer.h b/source/common/rendering/i_modelvertexbuffer.h index febec3c71..aea703c27 100644 --- a/source/common/rendering/i_modelvertexbuffer.h +++ b/source/common/rendering/i_modelvertexbuffer.h @@ -1,6 +1,6 @@ #pragma once -#include "templates.h" + struct FModelVertex { diff --git a/source/common/rendering/polyrenderer/backend/poly_buffers.cpp b/source/common/rendering/polyrenderer/backend/poly_buffers.cpp index 82c336e2a..10ebef0d0 100644 --- a/source/common/rendering/polyrenderer/backend/poly_buffers.cpp +++ b/source/common/rendering/polyrenderer/backend/poly_buffers.cpp @@ -56,7 +56,7 @@ void PolyBuffer::Reset() { } -void PolyBuffer::SetData(size_t size, const void *data, bool staticdata) +void PolyBuffer::SetData(size_t size, const void *data, BufferUsageType usage) { mData.resize(size); map = mData.data(); diff --git a/source/common/rendering/polyrenderer/backend/poly_buffers.h b/source/common/rendering/polyrenderer/backend/poly_buffers.h index 2f3d2cc74..c364586fa 100644 --- a/source/common/rendering/polyrenderer/backend/poly_buffers.h +++ b/source/common/rendering/polyrenderer/backend/poly_buffers.h @@ -20,7 +20,7 @@ public: static void ResetAll(); void Reset(); - void SetData(size_t size, const void *data, bool staticdata) override; + void SetData(size_t size, const void *data, BufferUsageType usage) override; void SetSubData(size_t offset, size_t size, const void *data) override; void Resize(size_t newsize) override; diff --git a/source/common/rendering/polyrenderer/backend/poly_framebuffer.cpp b/source/common/rendering/polyrenderer/backend/poly_framebuffer.cpp index a71523a46..683786570 100644 --- a/source/common/rendering/polyrenderer/backend/poly_framebuffer.cpp +++ b/source/common/rendering/polyrenderer/backend/poly_framebuffer.cpp @@ -111,7 +111,7 @@ void PolyFrameBuffer::InitializeState() mScreenQuad.VertexBuffer->SetFormat(1, 3, sizeof(ScreenQuadVertex), format); mScreenQuad.IndexBuffer = screen->CreateIndexBuffer(); - mScreenQuad.IndexBuffer->SetData(6 * sizeof(uint32_t), indices, false); + mScreenQuad.IndexBuffer->SetData(6 * sizeof(uint32_t), indices, BufferUsageType::Stream); CheckCanvas(); } @@ -219,8 +219,8 @@ void PolyFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::functionGetWidth(), image->GetWidth()); - bounds.height = std::min(tex->GetHeight(), image->GetHeight()); + bounds.width = min(tex->GetWidth(), image->GetWidth()); + bounds.height = min(tex->GetHeight(), image->GetHeight()); renderFunc(bounds); @@ -254,7 +254,7 @@ void PolyFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash, c { 0.0f, (float)mScreenViewport.height, 0.0f, 1.0f }, { (float)mScreenViewport.width, (float)mScreenViewport.height, 1.0f, 1.0f } }; - mScreenQuad.VertexBuffer->SetData(4 * sizeof(ScreenQuadVertex), vertices, false); + mScreenQuad.VertexBuffer->SetData(4 * sizeof(ScreenQuadVertex), vertices, BufferUsageType::Stream); mRenderState->SetVertexBuffer(mScreenQuad.VertexBuffer, 0, 0); mRenderState->SetIndexBuffer(mScreenQuad.IndexBuffer); diff --git a/source/common/rendering/polyrenderer/drawers/poly_thread.cpp b/source/common/rendering/polyrenderer/drawers/poly_thread.cpp index 338b12139..38faabafb 100644 --- a/source/common/rendering/polyrenderer/drawers/poly_thread.cpp +++ b/source/common/rendering/polyrenderer/drawers/poly_thread.cpp @@ -100,10 +100,10 @@ void PolyTriangleThreadData::SetScissor(int x, int y, int w, int h) void PolyTriangleThreadData::UpdateClip() { - clip.left = MAX(MAX(viewport_x, scissor.left), 0); - clip.top = MAX(MAX(viewport_y, scissor.top), 0); - clip.right = MIN(MIN(viewport_x + viewport_width, scissor.right), dest_width); - clip.bottom = MIN(MIN(viewport_y + viewport_height, scissor.bottom), dest_height); + clip.left = max(max(viewport_x, scissor.left), 0); + clip.top = max(max(viewport_y, scissor.top), 0); + clip.right = min(min(viewport_x + viewport_width, scissor.right), dest_width); + clip.bottom = min(min(viewport_y + viewport_height, scissor.bottom), dest_height); } void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPushConstants &constants) @@ -206,11 +206,11 @@ void PolyTriangleThreadData::SetStencil(int stencilRef, int op) StencilTestValue = stencilRef; if (op == SOP_Increment) { - StencilWriteValue = MIN(stencilRef + 1, (int)255); + StencilWriteValue = min(stencilRef + 1, (int)255); } else if (op == SOP_Decrement) { - StencilWriteValue = MAX(stencilRef - 1, (int)0); + StencilWriteValue = max(stencilRef - 1, (int)0); } else // SOP_Keep { @@ -453,8 +453,8 @@ void PolyTriangleThreadData::DrawShadedLine(const ShadedTriVertex *const* vert) { float clipdistance1 = clipdistance[0 * numclipdistances + p]; float clipdistance2 = clipdistance[1 * numclipdistances + p]; - if (clipdistance1 < 0.0f) t1 = MAX(-clipdistance1 / (clipdistance2 - clipdistance1), t1); - if (clipdistance2 < 0.0f) t2 = MIN(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), t2); + if (clipdistance1 < 0.0f) t1 = max(-clipdistance1 / (clipdistance2 - clipdistance1), t1); + if (clipdistance2 < 0.0f) t2 = min(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), t2); if (t1 >= t2) return; } @@ -792,8 +792,8 @@ int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *const* verts) // Clip halfspace if ((clipdistance1 >= 0.0f || clipdistance2 >= 0.0f) && outputverts + 1 < max_additional_vertices) { - float t1 = (clipdistance1 < 0.0f) ? MAX(-clipdistance1 / (clipdistance2 - clipdistance1), 0.0f) : 0.0f; - float t2 = (clipdistance2 < 0.0f) ? MIN(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), 1.0f) : 1.0f; + float t1 = (clipdistance1 < 0.0f) ? max(-clipdistance1 / (clipdistance2 - clipdistance1), 0.0f) : 0.0f; + float t2 = (clipdistance2 < 0.0f) ? min(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), 1.0f) : 1.0f; // add t1 vertex for (int k = 0; k < 3; k++) diff --git a/source/common/rendering/polyrenderer/drawers/poly_thread.h b/source/common/rendering/polyrenderer/drawers/poly_thread.h index 8d7b8bce6..abaa43e32 100644 --- a/source/common/rendering/polyrenderer/drawers/poly_thread.h +++ b/source/common/rendering/polyrenderer/drawers/poly_thread.h @@ -85,16 +85,16 @@ public: int skipped_by_thread(int first_line) { - int clip_first_line = MAX(first_line, numa_start_y); + int clip_first_line = max(first_line, numa_start_y); int core_skip = (num_cores - (clip_first_line - core) % num_cores) % num_cores; return clip_first_line + core_skip - first_line; } int count_for_thread(int first_line, int count) { - count = MIN(count, numa_end_y - first_line); + count = min(count, numa_end_y - first_line); int c = (count - skipped_by_thread(first_line) + num_cores - 1) / num_cores; - return MAX(c, 0); + return max(c, 0); } struct Scanline diff --git a/source/common/rendering/polyrenderer/drawers/screen_blend.cpp b/source/common/rendering/polyrenderer/drawers/screen_blend.cpp index afe540289..536acb7b0 100644 --- a/source/common/rendering/polyrenderer/drawers/screen_blend.cpp +++ b/source/common/rendering/polyrenderer/drawers/screen_blend.cpp @@ -336,10 +336,10 @@ void BlendColorAdd_Src_One(int y, int x0, int x1, PolyTriangleThreadData* thread uint32_t srcscale = APART(src); srcscale += srcscale >> 7; - uint32_t a = MIN((((APART(src) * srcscale) + 127) >> 8) + APART(dst), 255); - uint32_t r = MIN((((RPART(src) * srcscale) + 127) >> 8) + RPART(dst), 255); - uint32_t g = MIN((((GPART(src) * srcscale) + 127) >> 8) + GPART(dst), 255); - uint32_t b = MIN((((BPART(src) * srcscale) + 127) >> 8) + BPART(dst), 255); + uint32_t a = min((((APART(src) * srcscale) + 127) >> 8) + APART(dst), 255); + uint32_t r = min((((RPART(src) * srcscale) + 127) >> 8) + RPART(dst), 255); + uint32_t g = min((((GPART(src) * srcscale) + 127) >> 8) + GPART(dst), 255); + uint32_t b = min((((BPART(src) * srcscale) + 127) >> 8) + BPART(dst), 255); line[x] = MAKEARGB(a, r, g, b); } @@ -382,10 +382,10 @@ void BlendColorAdd_SrcCol_One(int y, int x0, int x1, PolyTriangleThreadData* thr srcscale_g += srcscale_g >> 7; srcscale_b += srcscale_b >> 7; - uint32_t a = MIN((((APART(src) * srcscale_a) + 127) >> 8) + APART(dst), 255); - uint32_t r = MIN((((RPART(src) * srcscale_r) + 127) >> 8) + RPART(dst), 255); - uint32_t g = MIN((((GPART(src) * srcscale_g) + 127) >> 8) + GPART(dst), 255); - uint32_t b = MIN((((BPART(src) * srcscale_b) + 127) >> 8) + BPART(dst), 255); + uint32_t a = min((((APART(src) * srcscale_a) + 127) >> 8) + APART(dst), 255); + uint32_t r = min((((RPART(src) * srcscale_r) + 127) >> 8) + RPART(dst), 255); + uint32_t g = min((((GPART(src) * srcscale_g) + 127) >> 8) + GPART(dst), 255); + uint32_t b = min((((BPART(src) * srcscale_b) + 127) >> 8) + BPART(dst), 255); line[x] = MAKEARGB(a, r, g, b); } @@ -514,10 +514,10 @@ void BlendColorRevSub_Src_One(int y, int x0, int x1, PolyTriangleThreadData* thr uint32_t srcscale = APART(src); srcscale += srcscale >> 7; - uint32_t a = MAX(APART(dst) - (((APART(src) * srcscale) + 127) >> 8), 0); - uint32_t r = MAX(RPART(dst) - (((RPART(src) * srcscale) + 127) >> 8), 0); - uint32_t g = MAX(GPART(dst) - (((GPART(src) * srcscale) + 127) >> 8), 0); - uint32_t b = MAX(BPART(dst) - (((BPART(src) * srcscale) + 127) >> 8), 0); + uint32_t a = max(APART(dst) - (((APART(src) * srcscale) + 127) >> 8), 0); + uint32_t r = max(RPART(dst) - (((RPART(src) * srcscale) + 127) >> 8), 0); + uint32_t g = max(GPART(dst) - (((GPART(src) * srcscale) + 127) >> 8), 0); + uint32_t b = max(BPART(dst) - (((BPART(src) * srcscale) + 127) >> 8), 0); line[x] = MAKEARGB(a, r, g, b); } diff --git a/source/common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp b/source/common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp index 5aa4855d6..bd5307792 100644 --- a/source/common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp +++ b/source/common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp @@ -124,7 +124,7 @@ static void WriteDynLightArray(int x0, int x1, PolyTriangleThreadData* thread) // L = light-pos // dist = sqrt(dot(L, L)) - // distance_attenuation = 1 - MIN(dist * (1/radius), 1) + // distance_attenuation = 1 - min(dist * (1/radius), 1) __m128 Lx = _mm_sub_ps(lightposX, _mm_loadu_ps(&worldposX[x])); __m128 Ly = _mm_sub_ps(lightposY, _mm_loadu_ps(&worldposY[x])); __m128 Lz = _mm_sub_ps(lightposZ, _mm_loadu_ps(&worldposZ[x])); @@ -179,7 +179,7 @@ static void WriteDynLightArray(int x0, int x1, PolyTriangleThreadData* thread) // L = light-pos // dist = sqrt(dot(L, L)) - // distance_attenuation = 1 - MIN(dist * (1/radius), 1) + // distance_attenuation = 1 - min(dist * (1/radius), 1) float Lx = lightposX - worldposX[x]; float Ly = lightposY - worldposY[x]; float Lz = lightposZ - worldposZ[x]; @@ -191,7 +191,7 @@ static void WriteDynLightArray(int x0, int x1, PolyTriangleThreadData* thread) float rcp_dist = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(dist2))); #endif float dist = dist2 * rcp_dist; - float distance_attenuation = 256.0f - MIN(dist * light_radius, 256.0f); + float distance_attenuation = 256.0f - min(dist * light_radius, 256.0f); // The simple light type float simple_attenuation = distance_attenuation; @@ -202,7 +202,7 @@ static void WriteDynLightArray(int x0, int x1, PolyTriangleThreadData* thread) Ly *= rcp_dist; Lz *= rcp_dist; float dotNL = worldnormalX * Lx + worldnormalY * Ly + worldnormalZ * Lz; - float point_attenuation = MAX(dotNL, 0.0f) * distance_attenuation; + float point_attenuation = max(dotNL, 0.0f) * distance_attenuation; uint32_t attenuation = (uint32_t)(is_attenuated ? (int32_t)point_attenuation : (int32_t)simple_attenuation); @@ -211,9 +211,9 @@ static void WriteDynLightArray(int x0, int x1, PolyTriangleThreadData* thread) lit_b += (BPART(light_color) * attenuation) >> 8; } - lit_r = MIN(lit_r, 255); - lit_g = MIN(lit_g, 255); - lit_b = MIN(lit_b, 255); + lit_r = min(lit_r, 255); + lit_g = min(lit_g, 255); + lit_b = min(lit_b, 255); lightarray[x] = MAKEARGB(lit_a, lit_r, lit_g, lit_b); // Palette version: @@ -255,7 +255,7 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar uint32_t* lightarray = thread->scanline.lightarray; for (int x = x0; x < x1; x++) { - uint32_t l = MIN(lightpos >> 8, 256); + uint32_t l = min(lightpos >> 8, 256); uint32_t r = vColorR[x]; uint32_t g = vColorG[x]; @@ -273,9 +273,9 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar g += (uint32_t)(constants->uDynLightColor.Y * 255.0f); b += (uint32_t)(constants->uDynLightColor.Z * 255.0f); - r = MIN(r, 255); - g = MIN(g, 255); - b = MIN(b, 255); + r = min(r, 255); + g = min(g, 255); + b = min(b, 255); } lightarray[x] = MAKEARGB(a, r, g, b); @@ -287,7 +287,7 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar uint32_t* lightarray = thread->scanline.lightarray; for (int x = x0; x < x1; x++) { - uint32_t l = MIN((FRACUNIT - clamp(shade - MIN(maxvis, lightpos), 0, maxlight)) >> 8, 256); + uint32_t l = min((FRACUNIT - clamp(shade - min(maxvis, lightpos), 0, maxlight)) >> 8, 256); uint32_t r = vColorR[x]; uint32_t g = vColorG[x]; uint32_t b = vColorB[x]; @@ -304,9 +304,9 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar g += (uint32_t)(constants->uDynLightColor.Y * 255.0f); b += (uint32_t)(constants->uDynLightColor.Z * 255.0f); - r = MIN(r, 255); - g = MIN(g, 255); - b = MIN(b, 255); + r = min(r, 255); + g = min(g, 255); + b = min(b, 255); } lightarray[x] = MAKEARGB(a, r, g, b); @@ -327,7 +327,7 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar uint32_t g = thread->scanline.vColorG[x]; uint32_t b = thread->scanline.vColorB[x]; - float fogdist = MAX(16.0f, w[x]); + float fogdist = max(16.0f, w[x]); float fogfactor = std::exp2(constants->uFogDensity * fogdist); // brightening around the player for light mode 2: @@ -365,9 +365,9 @@ static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* ar g += (uint32_t)(constants->uDynLightColor.Y * 255.0f); b += (uint32_t)(constants->uDynLightColor.Z * 255.0f); - r = MIN(r, 255); - g = MIN(g, 255); - b = MIN(b, 255); + r = min(r, 255); + g = min(g, 255); + b = min(b, 255); } lightarray[x] = MAKEARGB(a, r, g, b); diff --git a/source/common/rendering/polyrenderer/drawers/screen_shader.cpp b/source/common/rendering/polyrenderer/drawers/screen_shader.cpp index 7e225bef1..023142cb9 100644 --- a/source/common/rendering/polyrenderer/drawers/screen_shader.cpp +++ b/source/common/rendering/polyrenderer/drawers/screen_shader.cpp @@ -291,9 +291,9 @@ static void FuncNormal_AddColor(int x0, int x1, PolyTriangleThreadData* thread) uint32_t texel = fragcolor[x]; fragcolor[x] = MAKEARGB( APART(texel), - MIN(r + RPART(texel), (uint32_t)255), - MIN(g + GPART(texel), (uint32_t)255), - MIN(b + BPART(texel), (uint32_t)255)); + min(r + RPART(texel), (uint32_t)255), + min(g + GPART(texel), (uint32_t)255), + min(b + BPART(texel), (uint32_t)255)); } } @@ -309,9 +309,9 @@ static void FuncNormal_AddObjectColor(int x0, int x1, PolyTriangleThreadData* th uint32_t texel = fragcolor[x]; fragcolor[x] = MAKEARGB( APART(texel), - MIN((r * RPART(texel)) >> 8, (uint32_t)255), - MIN((g * GPART(texel)) >> 8, (uint32_t)255), - MIN((b * BPART(texel)) >> 8, (uint32_t)255)); + min((r * RPART(texel)) >> 8, (uint32_t)255), + min((g * GPART(texel)) >> 8, (uint32_t)255), + min((b * BPART(texel)) >> 8, (uint32_t)255)); } } @@ -331,9 +331,9 @@ static void FuncNormal_AddObjectColor2(int x0, int x1, PolyTriangleThreadData* t uint32_t texel = fragcolor[x]; fragcolor[x] = MAKEARGB( APART(texel), - MIN((r * RPART(texel)) >> 8, (uint32_t)255), - MIN((g * GPART(texel)) >> 8, (uint32_t)255), - MIN((b * BPART(texel)) >> 8, (uint32_t)255)); + min((r * RPART(texel)) >> 8, (uint32_t)255), + min((g * GPART(texel)) >> 8, (uint32_t)255), + min((b * BPART(texel)) >> 8, (uint32_t)255)); } } @@ -473,7 +473,7 @@ static void GetLightColor(int x0, int x1, PolyTriangleThreadData* thread) mulG += mulG >> 7; mulB += mulB >> 7; - float fogdist = MAX(16.0f, w[x]); + float fogdist = max(16.0f, w[x]); float fogfactor = std::exp2(uFogDensity * fogdist); uint32_t a = (APART(fg) * mulA + 127) >> 8; @@ -512,7 +512,7 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread) float fogfactor = 0.0f; if (constants->uFogEnabled != 0) { - fogdist = MAX(16.0f, w[x]); + fogdist = max(16.0f, w[x]); fogfactor = std::exp2(constants->uFogDensity * fogdist); } frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * vColor.a);*/ @@ -594,9 +594,9 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread) b = (BPART(fragcolor[x]) * b + 127) >> 8; // frag.rgb = frag.rgb + uFogColor.rgb; - r = MIN(r + fogR, (uint32_t)255); - g = MIN(g + fogG, (uint32_t)255); - b = MIN(b + fogB, (uint32_t)255); + r = min(r + fogR, (uint32_t)255); + g = min(g + fogG, (uint32_t)255); + b = min(b + fogB, (uint32_t)255); fragcolor[x] = MAKEARGB(a, r, g, b); } diff --git a/source/common/rendering/polyrenderer/drawers/screen_triangle.cpp b/source/common/rendering/polyrenderer/drawers/screen_triangle.cpp index 53c9afabe..dfa82fd2c 100644 --- a/source/common/rendering/polyrenderer/drawers/screen_triangle.cpp +++ b/source/common/rendering/polyrenderer/drawers/screen_triangle.cpp @@ -207,17 +207,17 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs* args, PolyTriangleThreadDat SortVertices(args, sortedVertices); int clipleft = thread->clip.left; - int cliptop = MAX(thread->clip.top, thread->numa_start_y); + int cliptop = max(thread->clip.top, thread->numa_start_y); int clipright = thread->clip.right; - int clipbottom = MIN(thread->clip.bottom, thread->numa_end_y); + int clipbottom = min(thread->clip.bottom, thread->numa_end_y); int topY = (int)(sortedVertices[0]->y + 0.5f); int midY = (int)(sortedVertices[1]->y + 0.5f); int bottomY = (int)(sortedVertices[2]->y + 0.5f); - topY = MAX(topY, cliptop); - midY = MIN(midY, clipbottom); - bottomY = MIN(bottomY, clipbottom); + topY = max(topY, cliptop); + midY = min(midY, clipbottom); + bottomY = min(bottomY, clipbottom); if (topY >= bottomY) return; diff --git a/source/common/rendering/r_thread.cpp b/source/common/rendering/r_thread.cpp index 0415bd40c..09ecde78b 100644 --- a/source/common/rendering/r_thread.cpp +++ b/source/common/rendering/r_thread.cpp @@ -21,7 +21,7 @@ */ #include -#include "templates.h" + #include "i_system.h" #include "filesystem.h" #include "v_video.h" diff --git a/source/common/rendering/r_thread.h b/source/common/rendering/r_thread.h index 87319cf0c..f1e49d416 100644 --- a/source/common/rendering/r_thread.h +++ b/source/common/rendering/r_thread.h @@ -27,7 +27,7 @@ #include #include #include -#include "templates.h" + #include "c_cvars.h" #include "basics.h" @@ -78,7 +78,7 @@ public: // The number of lines to skip to reach the first line to be rendered by this thread int skipped_by_thread(int first_line) { - int clip_first_line = MAX(first_line, numa_start_y); + int clip_first_line = max(first_line, numa_start_y); int core_skip = (num_cores - (clip_first_line - core) % num_cores) % num_cores; return clip_first_line + core_skip - first_line; } @@ -86,9 +86,9 @@ public: // The number of lines to be rendered by this thread int count_for_thread(int first_line, int count) { - count = MIN(count, numa_end_y - first_line); + count = min(count, numa_end_y - first_line); int c = (count - skipped_by_thread(first_line) + num_cores - 1) / num_cores; - return MAX(c, 0); + return max(c, 0); } // Calculate the dest address for the first line to be rendered by this thread diff --git a/source/common/rendering/r_videoscale.cpp b/source/common/rendering/r_videoscale.cpp index 1f5a7bb38..f94621e9d 100644 --- a/source/common/rendering/r_videoscale.cpp +++ b/source/common/rendering/r_videoscale.cpp @@ -34,7 +34,7 @@ #include "c_dispatch.h" #include "c_cvars.h" #include "v_video.h" -#include "templates.h" + #include "r_videoscale.h" #include "cmdlib.h" #include "v_draw.h" @@ -193,7 +193,7 @@ int ViewportScaledWidth(int width, int height) width = ((float)width/height > ActiveRatio(width, height)) ? (int)(height * ActiveRatio(width, height)) : width; height = ((float)width/height < ActiveRatio(width, height)) ? (int)(width / ActiveRatio(width, height)) : height; } - return (int)std::max((int32_t)min_width, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledWidth(width, height))); + return (int)max((int32_t)min_width, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledWidth(width, height))); } int ViewportScaledHeight(int width, int height) @@ -205,7 +205,7 @@ int ViewportScaledHeight(int width, int height) height = ((float)width/height < ActiveRatio(width, height)) ? (int)(width / ActiveRatio(width, height)) : height; width = ((float)width/height > ActiveRatio(width, height)) ? (int)(height * ActiveRatio(width, height)) : width; } - return (int)std::max((int32_t)min_height, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledHeight(width, height))); + return (int)max((int32_t)min_height, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledHeight(width, height))); } float ViewportPixelAspect() diff --git a/source/common/rendering/v_framebuffer.cpp b/source/common/rendering/v_framebuffer.cpp index d1f148f1b..c0ebb4c25 100644 --- a/source/common/rendering/v_framebuffer.cpp +++ b/source/common/rendering/v_framebuffer.cpp @@ -186,7 +186,7 @@ void DFrameBuffer::SetViewportRects(IntRect *bounds) int screenWidth = GetWidth(); int screenHeight = GetHeight(); float scaleX, scaleY; - scaleX = std::min(clientWidth / (float)screenWidth, clientHeight / ((float)screenHeight * ViewportPixelAspect())); + scaleX = min(clientWidth / (float)screenWidth, clientHeight / ((float)screenHeight * ViewportPixelAspect())); scaleY = scaleX * ViewportPixelAspect(); mOutputLetterbox.width = (int)round(screenWidth * scaleX); mOutputLetterbox.height = (int)round(screenHeight * scaleY); diff --git a/source/common/rendering/v_video.cpp b/source/common/rendering/v_video.cpp index 0d00c4c2e..4a8638593 100644 --- a/source/common/rendering/v_video.cpp +++ b/source/common/rendering/v_video.cpp @@ -61,7 +61,7 @@ #include "texturemanager.h" #include "i_interface.h" #include "v_draw.h" -#include "templates.h" + EXTERN_CVAR(Int, menu_resolution_custom_width) EXTERN_CVAR(Int, menu_resolution_custom_height) @@ -72,6 +72,8 @@ CVAR(Int, win_w, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, win_h, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +CVAR(Bool, r_skipmats, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) + // 0 means 'no pipelining' for non GLES2 and 4 elements for GLES2 CUSTOM_CVAR(Int, gl_pipeline_depth, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { @@ -250,7 +252,7 @@ void DCanvas::Resize(int width, int height, bool optimizepitch) } else { - Pitch = width + MAX(0, CPU.DataL1LineSize - 8); + Pitch = width + max(0, CPU.DataL1LineSize - 8); } } int bytes_per_pixel = Bgra ? 4 : 1; @@ -273,7 +275,7 @@ void V_UpdateModeSize (int width, int height) // This reference size is being used so that on 800x450 (small 16:9) a scale of 2 gets used. - CleanXfac = std::max(std::min(screen->GetWidth() / 400, screen->GetHeight() / 240), 1); + CleanXfac = max(min(screen->GetWidth() / 400, screen->GetHeight() / 240), 1); if (CleanXfac >= 4) CleanXfac--; // Otherwise we do not have enough space for the episode/skill menus in some languages. CleanYfac = CleanXfac; CleanWidth = screen->GetWidth() / CleanXfac; @@ -290,7 +292,7 @@ void V_UpdateModeSize (int width, int height) else if (w < 1920) factor = 2; else factor = int(factor * 0.7); - CleanYfac_1 = CleanXfac_1 = factor;// MAX(1, int(factor * 0.7)); + CleanYfac_1 = CleanXfac_1 = factor;// max(1, int(factor * 0.7)); CleanWidth_1 = width / CleanXfac_1; CleanHeight_1 = height / CleanYfac_1; diff --git a/source/common/rendering/vulkan/renderer/vk_postprocess.cpp b/source/common/rendering/vulkan/renderer/vk_postprocess.cpp index 9d1702834..dd8a22e95 100644 --- a/source/common/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/source/common/rendering/vulkan/renderer/vk_postprocess.cpp @@ -36,7 +36,7 @@ #include "flatvertices.h" #include "r_videoscale.h" #include "filesystem.h" -#include "templates.h" + EXTERN_CVAR(Int, gl_dither_bpc) diff --git a/source/common/rendering/vulkan/renderer/vk_renderbuffers.cpp b/source/common/rendering/vulkan/renderer/vk_renderbuffers.cpp index 75288a4f2..466acd5f4 100644 --- a/source/common/rendering/vulkan/renderer/vk_renderbuffers.cpp +++ b/source/common/rendering/vulkan/renderer/vk_renderbuffers.cpp @@ -27,7 +27,7 @@ #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" #include "hw_cvars.h" -#include "templates.h" + VkRenderBuffers::VkRenderBuffers() { @@ -239,13 +239,8 @@ void VkRenderBuffers::CreateShadowmap() ImageBuilder builder; builder.setSize(gl_shadowmap_quality, 1024); - builder.setFormat(SceneNormalFormat); + builder.setFormat(VK_FORMAT_R32_SFLOAT); builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); - if (!builder.isFormatSupported(fb->device, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) - { - SceneNormalFormat = VK_FORMAT_R8G8B8A8_UNORM; - builder.setFormat(SceneNormalFormat); - } Shadowmap.Image = builder.create(fb->device); Shadowmap.Image->SetDebugName("VkRenderBuffers.Shadowmap"); diff --git a/source/common/rendering/vulkan/renderer/vk_renderstate.cpp b/source/common/rendering/vulkan/renderer/vk_renderstate.cpp index d8314405d..95560a870 100644 --- a/source/common/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/source/common/rendering/vulkan/renderer/vk_renderstate.cpp @@ -26,7 +26,7 @@ #include "vulkan/renderer/vk_renderpass.h" #include "vulkan/renderer/vk_renderbuffers.h" #include "vulkan/textures/vk_hwtexture.h" -#include "templates.h" + #include "hw_skydome.h" #include "hw_viewpointuniforms.h" #include "hw_lightbuffer.h" @@ -37,6 +37,7 @@ #include "hwrenderer/data/shaderuniforms.h" CVAR(Int, vk_submit_size, 1000, 0); +EXTERN_CVAR(Bool, r_skipmats) VkRenderState::VkRenderState() { @@ -227,7 +228,7 @@ void VkRenderState::ApplyRenderPass(int dt) pipelineKey.ColorMask = mColorMask; pipelineKey.CullMode = mCullMode; pipelineKey.NumTextureLayers = mMaterial.mMaterial ? mMaterial.mMaterial->NumLayers() : 0; - pipelineKey.NumTextureLayers = std::max(pipelineKey.NumTextureLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS);// Always force minimum 8 textures as the shader requires it + pipelineKey.NumTextureLayers = max(pipelineKey.NumTextureLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS);// Always force minimum 8 textures as the shader requires it if (mSpecialEffect > EFF_NONE) { pipelineKey.SpecialEffect = mSpecialEffect; @@ -239,6 +240,8 @@ void VkRenderState::ApplyRenderPass(int dt) int effectState = mMaterial.mOverrideShader >= 0 ? mMaterial.mOverrideShader : (mMaterial.mMaterial ? mMaterial.mMaterial->GetShaderIndex() : 0); pipelineKey.SpecialEffect = EFF_NONE; pipelineKey.EffectState = mTextureEnabled ? effectState : SHADER_NoTexture; + if (r_skipmats && pipelineKey.EffectState >= 3 && pipelineKey.EffectState <= 4) + pipelineKey.EffectState = 0; pipelineKey.AlphaTest = mAlphaThreshold >= 0.f; } diff --git a/source/common/rendering/vulkan/renderer/vk_streambuffer.cpp b/source/common/rendering/vulkan/renderer/vk_streambuffer.cpp index b393867c3..5a40be371 100644 --- a/source/common/rendering/vulkan/renderer/vk_streambuffer.cpp +++ b/source/common/rendering/vulkan/renderer/vk_streambuffer.cpp @@ -30,7 +30,7 @@ VkStreamBuffer::VkStreamBuffer(size_t structSize, size_t count) mBlockSize = static_cast((structSize + screen->uniformblockalignment - 1) / screen->uniformblockalignment * screen->uniformblockalignment); UniformBuffer = (VKDataBuffer*)GetVulkanFrameBuffer()->CreateDataBuffer(-1, false, false); - UniformBuffer->SetData(mBlockSize * count, nullptr, false); + UniformBuffer->SetData(mBlockSize * count, nullptr, BufferUsageType::Persistent); } VkStreamBuffer::~VkStreamBuffer() diff --git a/source/common/rendering/vulkan/system/vk_buffers.cpp b/source/common/rendering/vulkan/system/vk_buffers.cpp index 420be91f1..420b19f87 100644 --- a/source/common/rendering/vulkan/system/vk_buffers.cpp +++ b/source/common/rendering/vulkan/system/vk_buffers.cpp @@ -46,8 +46,13 @@ VKBuffer::~VKBuffer() mBuffer->Unmap(); auto fb = GetVulkanFrameBuffer(); - if (fb && mBuffer) - fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + if (fb) + { + if (mBuffer) + fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + if (mStaging) + fb->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + } } void VKBuffer::ResetAll() @@ -64,67 +69,91 @@ void VKBuffer::Reset() mStaging.reset(); } -void VKBuffer::SetData(size_t size, const void *data, bool staticdata) +void VKBuffer::SetData(size_t size, const void *data, BufferUsageType usage) { auto fb = GetVulkanFrameBuffer(); - size = std::max(size, (size_t)16); // For supporting zero byte buffers + size_t bufsize = max(size, (size_t)16); // For supporting zero byte buffers - if (staticdata) + // If SetData is called multiple times we have to keep the old buffers alive as there might still be draw commands referencing them + if (mBuffer) { + fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + mBuffer = {}; + } + if (mStaging) + { + fb->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + mStaging = {}; + } + + if (usage == BufferUsageType::Static || usage == BufferUsageType::Stream) + { + // Note: we could recycle buffers here for the stream usage type to improve performance + mPersistent = false; - { - BufferBuilder builder; - builder.setUsage(VK_BUFFER_USAGE_TRANSFER_DST_BIT | mBufferType, VMA_MEMORY_USAGE_GPU_ONLY); - builder.setSize(size); - mBuffer = builder.create(fb->device); - } + BufferBuilder builder; + builder.setUsage(VK_BUFFER_USAGE_TRANSFER_DST_BIT | mBufferType, VMA_MEMORY_USAGE_GPU_ONLY); + builder.setSize(bufsize); + mBuffer = builder.create(fb->device); - { - BufferBuilder builder; - builder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY); - builder.setSize(size); - mStaging = builder.create(fb->device); - } + BufferBuilder builder2; + builder2.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY); + builder2.setSize(bufsize); + mStaging = builder2.create(fb->device); - void *dst = mStaging->Map(0, size); - memcpy(dst, data, size); - mStaging->Unmap(); + if (data) + { + void* dst = mStaging->Map(0, bufsize); + memcpy(dst, data, size); + mStaging->Unmap(); + } fb->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get()); } - else + else if (usage == BufferUsageType::Persistent) { - mPersistent = screen->BuffersArePersistent(); + mPersistent = true; BufferBuilder builder; - builder.setUsage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, mPersistent ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT : 0); + builder.setUsage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); builder.setMemoryType( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - builder.setSize(size); + builder.setSize(bufsize); mBuffer = builder.create(fb->device); - if (mPersistent) + map = mBuffer->Map(0, bufsize); + if (data) + memcpy(map, data, size); + } + else if (usage == BufferUsageType::Mappable) + { + mPersistent = false; + + BufferBuilder builder; + builder.setUsage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, 0); + builder.setMemoryType( + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + builder.setSize(bufsize); + mBuffer = builder.create(fb->device); + + if (data) { - map = mBuffer->Map(0, size); - if (data) - memcpy(map, data, size); - } - else if (data) - { - void *dst = mBuffer->Map(0, size); + void* dst = mBuffer->Map(0, bufsize); memcpy(dst, data, size); mBuffer->Unmap(); } } + buffersize = size; } void VKBuffer::SetSubData(size_t offset, size_t size, const void *data) { - size = std::max(size, (size_t)16); // For supporting zero byte buffers + size = max(size, (size_t)16); // For supporting zero byte buffers auto fb = GetVulkanFrameBuffer(); if (mStaging) @@ -145,7 +174,7 @@ void VKBuffer::SetSubData(size_t offset, size_t size, const void *data) void VKBuffer::Resize(size_t newsize) { - newsize = std::max(newsize, (size_t)16); // For supporting zero byte buffers + newsize = max(newsize, (size_t)16); // For supporting zero byte buffers auto fb = GetVulkanFrameBuffer(); @@ -193,7 +222,7 @@ void VKBuffer::Unmap() void *VKBuffer::Lock(unsigned int size) { - size = std::max(size, (unsigned int)16); // For supporting zero byte buffers + size = max(size, (unsigned int)16); // For supporting zero byte buffers if (!mBuffer) { @@ -214,7 +243,7 @@ void VKBuffer::Unlock() if (!mBuffer) { map = nullptr; - SetData(mStaticUpload.Size(), mStaticUpload.Data(), true); + SetData(mStaticUpload.Size(), mStaticUpload.Data(), BufferUsageType::Static); mStaticUpload.Clear(); } else if (!mPersistent) diff --git a/source/common/rendering/vulkan/system/vk_buffers.h b/source/common/rendering/vulkan/system/vk_buffers.h index d85391b3c..78f850148 100644 --- a/source/common/rendering/vulkan/system/vk_buffers.h +++ b/source/common/rendering/vulkan/system/vk_buffers.h @@ -19,7 +19,7 @@ public: static void ResetAll(); void Reset(); - void SetData(size_t size, const void *data, bool staticdata) override; + void SetData(size_t size, const void *data, BufferUsageType usage) override; void SetSubData(size_t offset, size_t size, const void *data) override; void Resize(size_t newsize) override; diff --git a/source/common/rendering/vulkan/system/vk_builders.h b/source/common/rendering/vulkan/system/vk_builders.h index af9cbc3eb..0b053e8d8 100644 --- a/source/common/rendering/vulkan/system/vk_builders.h +++ b/source/common/rendering/vulkan/system/vk_builders.h @@ -571,7 +571,7 @@ inline BufferBuilder::BufferBuilder() inline void BufferBuilder::setSize(size_t size) { - bufferInfo.size = std::max(size, (size_t)16); + bufferInfo.size = max(size, (size_t)16); } inline void BufferBuilder::setUsage(VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocFlags) diff --git a/source/common/rendering/vulkan/system/vk_device.cpp b/source/common/rendering/vulkan/system/vk_device.cpp index ae2b9900f..be83d8937 100644 --- a/source/common/rendering/vulkan/system/vk_device.cpp +++ b/source/common/rendering/vulkan/system/vk_device.cpp @@ -220,6 +220,7 @@ void VulkanDevice::CreateAllocator() allocinfo.flags = VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT; allocinfo.physicalDevice = PhysicalDevice.Device; allocinfo.device = device; + allocinfo.instance = instance; allocinfo.preferredLargeHeapBlockSize = 64 * 1024 * 1024; if (vmaCreateAllocator(&allocinfo, &allocator) != VK_SUCCESS) VulkanError("Unable to create allocator"); @@ -376,9 +377,11 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess seenMessages.insert(msg); const char *typestr; + bool showcallstack = false; if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { typestr = "vulkan error"; + showcallstack = true; } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { @@ -397,11 +400,12 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess typestr = "vulkan"; } - Printf("\n"); + if (showcallstack) + Printf("\n"); Printf(TEXTCOLOR_RED "[%s] ", typestr); Printf(TEXTCOLOR_WHITE "%s\n", msg.GetChars()); - if (vk_debug_callstack) + if (vk_debug_callstack && showcallstack) { FString callstack = JitCaptureStackTrace(0, true); if (!callstack.IsEmpty()) diff --git a/source/common/rendering/vulkan/system/vk_framebuffer.cpp b/source/common/rendering/vulkan/system/vk_framebuffer.cpp index 4d08212ec..e189f4b24 100644 --- a/source/common/rendering/vulkan/system/vk_framebuffer.cpp +++ b/source/common/rendering/vulkan/system/vk_framebuffer.cpp @@ -26,7 +26,7 @@ #include "v_video.h" #include "m_png.h" -#include "templates.h" + #include "r_videoscale.h" #include "i_time.h" #include "v_text.h" @@ -309,7 +309,7 @@ void VulkanFrameBuffer::WaitForCommands(bool finish, bool uploadOnly) swapChain->QueuePresent(presentImageIndex, mRenderFinishedSemaphore.get()); } - int numWaitFences = MIN(mNextSubmit, (int)maxConcurrentSubmitCount); + int numWaitFences = min(mNextSubmit, (int)maxConcurrentSubmitCount); if (numWaitFences > 0) { @@ -345,8 +345,8 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::functionGetWidth(), image->Image->width); - bounds.height = std::min(tex->GetHeight(), image->Image->height); + bounds.width = min(tex->GetWidth(), image->Image->width); + bounds.height = min(tex->GetHeight(), image->Image->height); renderFunc(bounds); @@ -628,7 +628,7 @@ void VulkanFrameBuffer::UpdateGpuStats() if (q.endIndex <= q.startIndex) continue; - int64_t timeElapsed = std::max(static_cast(timestamps[q.endIndex] - timestamps[q.startIndex]), (int64_t)0); + int64_t timeElapsed = max(static_cast(timestamps[q.endIndex] - timestamps[q.startIndex]), (int64_t)0); double timeNS = timeElapsed * timestampPeriod; FString out; @@ -721,7 +721,7 @@ void VulkanFrameBuffer::CreateFanToTrisIndexBuffer() } FanToTrisIndexBuffer.reset(CreateIndexBuffer()); - FanToTrisIndexBuffer->SetData(sizeof(uint32_t) * data.Size(), data.Data()); + FanToTrisIndexBuffer->SetData(sizeof(uint32_t) * data.Size(), data.Data(), BufferUsageType::Static); } void VulkanFrameBuffer::UpdateShadowMap() diff --git a/source/common/rendering/vulkan/system/vk_swapchain.cpp b/source/common/rendering/vulkan/system/vk_swapchain.cpp index dcacd1620..789259695 100644 --- a/source/common/rendering/vulkan/system/vk_swapchain.cpp +++ b/source/common/rendering/vulkan/system/vk_swapchain.cpp @@ -161,8 +161,8 @@ bool VulkanSwapChain::CreateSwapChain(VkSwapchainKHR oldSwapChain) VkSurfaceCapabilitiesKHR surfaceCapabilities = GetSurfaceCapabilities(); actualExtent = { static_cast(width), static_cast(height) }; - actualExtent.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, actualExtent.width)); - actualExtent.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, actualExtent.height)); + actualExtent.width = max(surfaceCapabilities.minImageExtent.width, min(surfaceCapabilities.maxImageExtent.width, actualExtent.width)); + actualExtent.height = max(surfaceCapabilities.minImageExtent.height, min(surfaceCapabilities.maxImageExtent.height, actualExtent.height)); if (actualExtent.width == 0 || actualExtent.height == 0) { swapChain = VK_NULL_HANDLE; @@ -176,9 +176,9 @@ bool VulkanSwapChain::CreateSwapChain(VkSwapchainKHR oldSwapChain) // When vsync is on we only want two images. This creates a slight performance penalty in exchange for reduced input latency (less mouse lag). // When vsync is off we want three images as it allows us to generate new images even during the vertical blanking period where one entry is being used by the presentation engine. if (swapChainPresentMode == VK_PRESENT_MODE_MAILBOX_KHR || swapChainPresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) - imageCount = std::min(imageCount, (uint32_t)3); + imageCount = min(imageCount, (uint32_t)3); else - imageCount = std::min(imageCount, (uint32_t)2); + imageCount = min(imageCount, (uint32_t)2); VkSwapchainCreateInfoKHR swapChainCreateInfo = {}; swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; diff --git a/source/common/rendering/vulkan/textures/vk_hwtexture.cpp b/source/common/rendering/vulkan/textures/vk_hwtexture.cpp index 276f9fd09..b3ad6e66b 100644 --- a/source/common/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/source/common/rendering/vulkan/textures/vk_hwtexture.cpp @@ -20,7 +20,7 @@ ** */ -#include "templates.h" + #include "c_cvars.h" #include "hw_material.h" #include "hw_cvars.h" @@ -218,8 +218,8 @@ int VkHardwareTexture::GetMipLevels(int w, int h) int levels = 1; while (w > 1 || h > 1) { - w = std::max(w >> 1, 1); - h = std::max(h >> 1, 1); + w = max(w >> 1, 1); + h = max(h >> 1, 1); levels++; } return levels; @@ -391,7 +391,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) int numLayers = NumLayers(); auto fb = GetVulkanFrameBuffer(); - auto descriptor = fb->GetRenderPassManager()->AllocateTextureDescriptorSet(std::max(numLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS)); + auto descriptor = fb->GetRenderPassManager()->AllocateTextureDescriptorSet(max(numLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS)); descriptor->SetDebugName("VkHardwareTexture.mDescriptorSets"); @@ -400,14 +400,16 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) WriteDescriptors update; MaterialLayerInfo *layer; auto systex = static_cast(GetLayer(0, state.mTranslation, &layer)); - update.addCombinedImageSampler(descriptor.get(), 0, systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); + auto systeximage = systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags); + update.addCombinedImageSampler(descriptor.get(), 0, systeximage->View.get(), sampler, systeximage->Layout); if (!(layer->scaleFlags & CTF_Indexed)) { for (int i = 1; i < numLayers; i++) { auto systex = static_cast(GetLayer(i, 0, &layer)); - update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer->layerTexture, 0, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); + auto systeximage = systex->GetImage(layer->layerTexture, 0, layer->scaleFlags); + update.addCombinedImageSampler(descriptor.get(), i, systeximage->View.get(), sampler, systeximage->Layout); } } else @@ -415,7 +417,8 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) for (int i = 1; i < 3; i++) { auto systex = static_cast(GetLayer(i, translation, &layer)); - update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer->layerTexture, 0, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); + auto systeximage = systex->GetImage(layer->layerTexture, 0, layer->scaleFlags); + update.addCombinedImageSampler(descriptor.get(), i, systeximage->View.get(), sampler, systeximage->Layout); } numLayers = 3; } @@ -423,7 +426,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView(); for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++) { - update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, systex->mImage.Layout); + update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } update.updateSets(fb->device); diff --git a/source/common/rendering/vulkan/textures/vk_imagetransition.cpp b/source/common/rendering/vulkan/textures/vk_imagetransition.cpp index a135a3f0f..a5f289296 100644 --- a/source/common/rendering/vulkan/textures/vk_imagetransition.cpp +++ b/source/common/rendering/vulkan/textures/vk_imagetransition.cpp @@ -117,8 +117,8 @@ void VkTextureImage::GenerateMipmaps(VulkanCommandBuffer *cmdbuffer) barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); Layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - int nextWidth = std::max(mipWidth >> 1, 1); - int nextHeight = std::max(mipHeight >> 1, 1); + int nextWidth = max(mipWidth >> 1, 1); + int nextHeight = max(mipHeight >> 1, 1); VkImageBlit blit = {}; blit.srcOffsets[0] = { 0, 0, 0 }; diff --git a/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.cpp b/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.cpp index 7edacfe82..ee988cfc4 100644 --- a/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.cpp +++ b/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.cpp @@ -2,4 +2,7 @@ #define VMA_IMPLEMENTATION #define VMA_STATIC_VULKAN_FUNCTIONS 1 +#define VMA_NULLABLE +#define VMA_NOT_NULL + #include "vk_mem_alloc.h" diff --git a/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.h b/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.h index 30f2494a7..fd4472286 100644 --- a/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.h +++ b/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,15 +23,11 @@ #ifndef AMD_VULKAN_MEMORY_ALLOCATOR_H #define AMD_VULKAN_MEMORY_ALLOCATOR_H -#ifdef __cplusplus -extern "C" { -#endif - /** \mainpage Vulkan Memory Allocator -Version 2.0.0 (2018-03-19) +Version 3.0.0-development (2021-06-21) -Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved. \n +Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved. \n License: MIT Documentation of all members: vk_mem_alloc.h @@ -48,14 +44,29 @@ Documentation of all members: vk_mem_alloc.h - [Required and preferred flags](@ref choosing_memory_type_required_preferred_flags) - [Explicit memory types](@ref choosing_memory_type_explicit_memory_types) - [Custom memory pools](@ref choosing_memory_type_custom_memory_pools) + - [Dedicated allocations](@ref choosing_memory_type_dedicated_allocations) - \subpage memory_mapping - [Mapping functions](@ref memory_mapping_mapping_functions) - [Persistently mapped memory](@ref memory_mapping_persistently_mapped_memory) - - [Cache control](@ref memory_mapping_cache_control) + - [Cache flush and invalidate](@ref memory_mapping_cache_control) - [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable) + - \subpage staying_within_budget + - [Querying for budget](@ref staying_within_budget_querying_for_budget) + - [Controlling memory usage](@ref staying_within_budget_controlling_memory_usage) + - \subpage resource_aliasing - \subpage custom_memory_pools - [Choosing memory type index](@ref custom_memory_pools_MemTypeIndex) + - [Linear allocation algorithm](@ref linear_algorithm) + - [Free-at-once](@ref linear_algorithm_free_at_once) + - [Stack](@ref linear_algorithm_stack) + - [Double stack](@ref linear_algorithm_double_stack) + - [Ring buffer](@ref linear_algorithm_ring_buffer) + - [Buddy allocation algorithm](@ref buddy_algorithm) - \subpage defragmentation + - [Defragmenting CPU memory](@ref defragmentation_cpu) + - [Defragmenting GPU memory](@ref defragmentation_gpu) + - [Additional notes](@ref defragmentation_additional_notes) + - [Writing custom allocation algorithm](@ref defragmentation_custom_algorithm) - \subpage lost_allocations - \subpage statistics - [Numeric statistics](@ref statistics_numeric_statistics) @@ -63,7 +74,14 @@ Documentation of all members: vk_mem_alloc.h - \subpage allocation_annotation - [Allocation user data](@ref allocation_user_data) - [Allocation names](@ref allocation_names) + - \subpage debugging_memory_usage + - [Memory initialization](@ref debugging_memory_usage_initialization) + - [Margins](@ref debugging_memory_usage_margins) + - [Corruption detection](@ref debugging_memory_usage_corruption_detection) + - \subpage record_and_replay + - \subpage opengl_interop - \subpage usage_patterns + - [Common mistakes](@ref usage_patterns_common_mistakes) - [Simple patterns](@ref usage_patterns_simple) - [Advanced patterns](@ref usage_patterns_advanced) - \subpage configuration @@ -72,8 +90,11 @@ Documentation of all members: vk_mem_alloc.h - [Device memory allocation callbacks](@ref allocation_callbacks) - [Device heap memory limit](@ref heap_memory_limit) - \subpage vk_khr_dedicated_allocation + - \subpage enabling_buffer_device_address + - \subpage vk_amd_device_coherent_memory - \subpage general_considerations - [Thread safety](@ref general_considerations_thread_safety) + - [Validation layer warnings](@ref general_considerations_validation_layer_warnings) - [Allocation algorithm](@ref general_considerations_allocation_algorithm) - [Features not supported](@ref general_considerations_features_not_supported) @@ -81,1002 +102,186 @@ Documentation of all members: vk_mem_alloc.h - [Product page on GPUOpen](https://gpuopen.com/gaming-product/vulkan-memory-allocator/) - [Source repository on GitHub](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) - - - - -\page quick_start Quick start - -\section quick_start_project_setup Project setup - -Vulkan Memory Allocator comes in form of a single header file. -You don't need to build it as a separate library project. -You can add this file directly to your project and submit it to code repository next to your other source files. - -"Single header" doesn't mean that everything is contained in C/C++ declarations, -like it tends to be in case of inline functions or C++ templates. -It means that implementation is bundled with interface in a single file and needs to be extracted using preprocessor macro. -If you don't do it properly, you will get linker errors. - -To do it properly: - --# Include "vk_mem_alloc.h" file in each CPP file where you want to use the library. - This includes declarations of all members of the library. --# In exacly one CPP file define following macro before this include. - It enables also internal definitions. - -\code -#define VMA_IMPLEMENTATION -#include "vk_mem_alloc.h" -\endcode - -It may be a good idea to create dedicated CPP file just for this purpose. - -\section quick_start_initialization Initialization - -At program startup: - --# Initialize Vulkan to have `VkPhysicalDevice` and `VkDevice` object. --# Fill VmaAllocatorCreateInfo structure and create #VmaAllocator object by - calling vmaCreateAllocator(). - -\code -VmaAllocatorCreateInfo allocatorInfo = {}; -allocatorInfo.physicalDevice = physicalDevice; -allocatorInfo.device = device; - -VmaAllocator allocator; -vmaCreateAllocator(&allocatorInfo, &allocator); -\endcode - -\section quick_start_resource_allocation Resource allocation - -When you want to create a buffer or image: - --# Fill `VkBufferCreateInfo` / `VkImageCreateInfo` structure. --# Fill VmaAllocationCreateInfo structure. --# Call vmaCreateBuffer() / vmaCreateImage() to get `VkBuffer`/`VkImage` with memory - already allocated and bound to it. - -\code -VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufferInfo.size = 65536; -bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - -VmaAllocationCreateInfo allocInfo = {}; -allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; - -VkBuffer buffer; -VmaAllocation allocation; -vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); -\endcode - -Don't forget to destroy your objects when no longer needed: - -\code -vmaDestroyBuffer(allocator, buffer, allocation); -vmaDestroyAllocator(allocator); -\endcode - - -\page choosing_memory_type Choosing memory type - -Physical devices in Vulkan support various combinations of memory heaps and -types. Help with choosing correct and optimal memory type for your specific -resource is one of the key features of this library. You can use it by filling -appropriate members of VmaAllocationCreateInfo structure, as described below. -You can also combine multiple methods. - --# If you just want to find memory type index that meets your requirements, you - can use function vmaFindMemoryTypeIndex(). --# If you want to allocate a region of device memory without association with any - specific image or buffer, you can use function vmaAllocateMemory(). Usage of - this function is not recommended and usually not needed. --# If you already have a buffer or an image created, you want to allocate memory - for it and then you will bind it yourself, you can use function - vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(). - For binding you should use functions: vmaBindBufferMemory(), vmaBindImageMemory(). --# If you want to create a buffer or an image, allocate memory for it and bind - them together, all in one call, you can use function vmaCreateBuffer(), - vmaCreateImage(). This is the recommended way to use this library. - -When using 3. or 4., the library internally queries Vulkan for memory types -supported for that buffer or image (function `vkGetBufferMemoryRequirements()`) -and uses only one of these types. - -If no memory type can be found that meets all the requirements, these functions -return `VK_ERROR_FEATURE_NOT_PRESENT`. - -You can leave VmaAllocationCreateInfo structure completely filled with zeros. -It means no requirements are specified for memory type. -It is valid, although not very useful. - -\section choosing_memory_type_usage Usage - -The easiest way to specify memory requirements is to fill member -VmaAllocationCreateInfo::usage using one of the values of enum #VmaMemoryUsage. -It defines high level, common usage types. -For more details, see description of this enum. - -For example, if you want to create a uniform buffer that will be filled using -transfer only once or infrequently and used for rendering every frame, you can -do it using following code: - -\code -VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufferInfo.size = 65536; -bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - -VmaAllocationCreateInfo allocInfo = {}; -allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; - -VkBuffer buffer; -VmaAllocation allocation; -vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); -\endcode - -\section choosing_memory_type_required_preferred_flags Required and preferred flags - -You can specify more detailed requirements by filling members -VmaAllocationCreateInfo::requiredFlags and VmaAllocationCreateInfo::preferredFlags -with a combination of bits from enum `VkMemoryPropertyFlags`. For example, -if you want to create a buffer that will be persistently mapped on host (so it -must be `HOST_VISIBLE`) and preferably will also be `HOST_COHERENT` and `HOST_CACHED`, -use following code: - -\code -VmaAllocationCreateInfo allocInfo = {}; -allocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; -allocInfo.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; -allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; - -VkBuffer buffer; -VmaAllocation allocation; -vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); -\endcode - -A memory type is chosen that has all the required flags and as many preferred -flags set as possible. - -If you use VmaAllocationCreateInfo::usage, it is just internally converted to -a set of required and preferred flags. - -\section choosing_memory_type_explicit_memory_types Explicit memory types - -If you inspected memory types available on the physical device and you have -a preference for memory types that you want to use, you can fill member -VmaAllocationCreateInfo::memoryTypeBits. It is a bit mask, where each bit set -means that a memory type with that index is allowed to be used for the -allocation. Special value 0, just like `UINT32_MAX`, means there are no -restrictions to memory type index. - -Please note that this member is NOT just a memory type index. -Still you can use it to choose just one, specific memory type. -For example, if you already determined that your buffer should be created in -memory type 2, use following code: - -\code -uint32_t memoryTypeIndex = 2; - -VmaAllocationCreateInfo allocInfo = {}; -allocInfo.memoryTypeBits = 1u << memoryTypeIndex; - -VkBuffer buffer; -VmaAllocation allocation; -vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); -\endcode - -\section choosing_memory_type_custom_memory_pools Custom memory pools - -If you allocate from custom memory pool, all the ways of specifying memory -requirements described above are not applicable and the aforementioned members -of VmaAllocationCreateInfo structure are ignored. Memory type is selected -explicitly when creating the pool and then used to make all the allocations from -that pool. For further details, see \ref custom_memory_pools. - - -\page memory_mapping Memory mapping - -To "map memory" in Vulkan means to obtain a CPU pointer to `VkDeviceMemory`, -to be able to read from it or write to it in CPU code. -Mapping is possible only of memory allocated from a memory type that has -`VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag. -Functions `vkMapMemory()`, `vkUnmapMemory()` are designed for this purpose. -You can use them directly with memory allocated by this library, -but it is not recommended because of following issue: -Mapping the same `VkDeviceMemory` block multiple times is illegal - only one mapping at a time is allowed. -This includes mapping disjoint regions. Mapping is not reference-counted internally by Vulkan. -Because of this, Vulkan Memory Allocator provides following facilities: - -\section memory_mapping_mapping_functions Mapping functions - -The library provides following functions for mapping of a specific #VmaAllocation: vmaMapMemory(), vmaUnmapMemory(). -They are safer and more convenient to use than standard Vulkan functions. -You can map an allocation multiple times simultaneously - mapping is reference-counted internally. -You can also map different allocations simultaneously regardless of whether they use the same `VkDeviceMemory` block. -They way it's implemented is that the library always maps entire memory block, not just region of the allocation. -For further details, see description of vmaMapMemory() function. -Example: - -\code -// Having these objects initialized: - -struct ConstantBuffer -{ - ... -}; -ConstantBuffer constantBufferData; - -VmaAllocator allocator; -VmaBuffer constantBuffer; -VmaAllocation constantBufferAllocation; - -// You can map and fill your buffer using following code: - -void* mappedData; -vmaMapMemory(allocator, constantBufferAllocation, &mappedData); -memcpy(mappedData, &constantBufferData, sizeof(constantBufferData)); -vmaUnmapMemory(allocator, constantBufferAllocation); -\endcode - -\section memory_mapping_persistently_mapped_memory Persistently mapped memory - -Kepping your memory persistently mapped is generally OK in Vulkan. -You don't need to unmap it before using its data on the GPU. -The library provides a special feature designed for that: -Allocations made with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag set in -VmaAllocationCreateInfo::flags stay mapped all the time, -so you can just access CPU pointer to it any time -without a need to call any "map" or "unmap" function. -Example: - -\code -VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufCreateInfo.size = sizeof(ConstantBuffer); -bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY; -allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; - -VkBuffer buf; -VmaAllocation alloc; -VmaAllocationInfo allocInfo; -vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); - -// Buffer is already mapped. You can access its memory. -memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData)); -\endcode - -There are some exceptions though, when you should consider mapping memory only for a short period of time: - -- When operating system is Windows 7 or 8.x (Windows 10 is not affected because it uses WDDM2), - device is discrete AMD GPU, - and memory type is the special 256 MiB pool of `DEVICE_LOCAL + HOST_VISIBLE` memory - (selected when you use #VMA_MEMORY_USAGE_CPU_TO_GPU), - then whenever a memory block allocated from this memory type stays mapped - for the time of any call to `vkQueueSubmit()` or `vkQueuePresentKHR()`, this - block is migrated by WDDM to system RAM, which degrades performance. It doesn't - matter if that particular memory block is actually used by the command buffer - being submitted. -- Keeping many large memory blocks mapped may impact performance or stability of some debugging tools. - -\section memory_mapping_cache_control Cache control - -Memory in Vulkan doesn't need to be unmapped before using it on GPU, -but unless a memory types has `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` flag set, -you need to manually invalidate cache before reading of mapped pointer -using function `vkvkInvalidateMappedMemoryRanges()` -and flush cache after writing to mapped pointer -using function `vkFlushMappedMemoryRanges()`. -Example: - -\code -memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData)); - -VkMemoryPropertyFlags memFlags; -vmaGetMemoryTypeProperties(allocator, allocInfo.memoryType, &memFlags); -if((memFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) -{ - VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; - memRange.memory = allocInfo.deviceMemory; - memRange.offset = allocInfo.offset; - memRange.size = allocInfo.size; - vkFlushMappedMemoryRanges(device, 1, &memRange); -} -\endcode - -Please note that memory allocated with #VMA_MEMORY_USAGE_CPU_ONLY is guaranteed to be host coherent. - -Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA) -currently provide `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` flag on all memory types that are -`VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`, so on this platform you may not need to bother. - -\section memory_mapping_finding_if_memory_mappable Finding out if memory is mappable - -It may happen that your allocation ends up in memory that is `HOST_VISIBLE` (available for mapping) -despite it wasn't explicitly requested. -For example, application may work on integrated graphics with unified memory (like Intel) or -allocation from video memory might have failed, so the library chose system memory as fallback. - -You can detect this case and map such allocation to access its memory on CPU directly, -instead of launching a transfer operation. -In order to do that: inspect `allocInfo.memoryType`, call vmaGetMemoryTypeProperties(), -and look for `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag in properties of that memory type. - -\code -VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufCreateInfo.size = sizeof(ConstantBuffer); -bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; - -VkBuffer buf; -VmaAllocation alloc; -VmaAllocationInfo allocInfo; -vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); - -VkMemoryPropertyFlags memFlags; -vmaGetMemoryTypeProperties(allocator, allocInfo.memoryType, &memFlags); -if((memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) -{ - // Allocation ended up in mappable memory. You can map it and access it directly. - void* mappedData; - vmaMapMemory(allocator, alloc, &mappedData); - memcpy(mappedData, &constantBufferData, sizeof(constantBufferData)); - vmaUnmapMemory(allocator, alloc); -} -else -{ - // Allocation ended up in non-mappable memory. - // You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer. -} -\endcode - -You can even use #VMA_ALLOCATION_CREATE_MAPPED_BIT flag while creating allocations -that are not necessarily `HOST_VISIBLE` (e.g. using #VMA_MEMORY_USAGE_GPU_ONLY). -If the allocation ends up in memory type that is `HOST_VISIBLE`, it will be persistently mapped and you can use it directly. -If not, the flag is just ignored. -Example: - -\code -VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufCreateInfo.size = sizeof(ConstantBuffer); -bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; -allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; - -VkBuffer buf; -VmaAllocation alloc; -VmaAllocationInfo allocInfo; -vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); - -if(allocInfo.pUserData != nullptr) -{ - // Allocation ended up in mappable memory. - // It's persistently mapped. You can access it directly. - memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData)); -} -else -{ - // Allocation ended up in non-mappable memory. - // You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer. -} -\endcode - - -\page custom_memory_pools Custom memory pools - -A memory pool contains a number of `VkDeviceMemory` blocks. -The library automatically creates and manages default pool for each memory type available on the device. -Default memory pool automatically grows in size. -Size of allocated blocks is also variable and managed automatically. - -You can create custom pool and allocate memory out of it. -It can be useful if you want to: - -- Keep certain kind of allocations separate from others. -- Enforce particular, fixed size of Vulkan memory blocks. -- Limit maximum amount of Vulkan memory allocated for that pool. -- Reserve minimum or fixed amount of Vulkan memory always preallocated for that pool. - -To use custom memory pools: - --# Fill VmaPoolCreateInfo structure. --# Call vmaCreatePool() to obtain #VmaPool handle. --# When making an allocation, set VmaAllocationCreateInfo::pool to this handle. - You don't need to specify any other parameters of this structure, like usage. - -Example: - -\code -// Create a pool that can have at most 2 blocks, 128 MiB each. -VmaPoolCreateInfo poolCreateInfo = {}; -poolCreateInfo.memoryTypeIndex = ... -poolCreateInfo.blockSize = 128ull * 1024 * 1024; -poolCreateInfo.maxBlockCount = 2; - -VmaPool pool; -vmaCreatePool(allocator, &poolCreateInfo, &pool); - -// Allocate a buffer out of it. -VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufCreateInfo.size = 1024; -bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.pool = pool; - -VkBuffer buf; -VmaAllocation alloc; -VmaAllocationInfo allocInfo; -vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); -\endcode - -You have to free all allocations made from this pool before destroying it. - -\code -vmaDestroyBuffer(allocator, buf, alloc); -vmaDestroyPool(allocator, pool); -\endcode - -\section custom_memory_pools_MemTypeIndex Choosing memory type index - -When creating a pool, you must explicitly specify memory type index. -To find the one suitable for your buffers or images, you can use helper functions -vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo(). -You need to provide structures with example parameters of buffers or images -that you are going to create in that pool. - -\code -VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -exampleBufCreateInfo.size = 1024; // Whatever. -exampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // Change if needed. - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; // Change if needed. - -uint32_t memTypeIndex; -vmaFindMemoryTypeIndexForBufferInfo(allocator, &exampleBufCreateInfo, &allocCreateInfo, &memTypeIndex); - -VmaPoolCreateInfo poolCreateInfo = {}; -poolCreateInfo.memoryTypeIndex = memTypeIndex; -// ... -\endcode - -When creating buffers/images allocated in that pool, provide following parameters: - -- `VkBufferCreateInfo`: Prefer to pass same parameters as above. - Otherwise you risk creating resources in a memory type that is not suitable for them, which may result in undefined behavior. - Using different `VK_BUFFER_USAGE_` flags may work, but you shouldn't create images in a pool intended for buffers - or the other way around. -- VmaAllocationCreateInfo: You don't need to pass same parameters. Fill only `pool` member. - Other members are ignored anyway. - - -\page defragmentation Defragmentation - -Interleaved allocations and deallocations of many objects of varying size can -cause fragmentation, which can lead to a situation where the library is unable -to find a continuous range of free memory for a new allocation despite there is -enough free space, just scattered across many small free ranges between existing -allocations. - -To mitigate this problem, you can use vmaDefragment(). Given set of allocations, -this function can move them to compact used memory, ensure more continuous free -space and possibly also free some `VkDeviceMemory`. It can work only on -allocations made from memory type that is `HOST_VISIBLE`. Allocations are -modified to point to the new `VkDeviceMemory` and offset. Data in this memory is -also `memmove`-ed to the new place. However, if you have images or buffers bound -to these allocations (and you certainly do), you need to destroy, recreate, and -bind them to the new place in memory. - -For further details and example code, see documentation of function -vmaDefragment(). - -\page lost_allocations Lost allocations - -If your game oversubscribes video memory, if may work OK in previous-generation -graphics APIs (DirectX 9, 10, 11, OpenGL) because resources are automatically -paged to system RAM. In Vulkan you can't do it because when you run out of -memory, an allocation just fails. If you have more data (e.g. textures) that can -fit into VRAM and you don't need it all at once, you may want to upload them to -GPU on demand and "push out" ones that are not used for a long time to make room -for the new ones, effectively using VRAM (or a cartain memory pool) as a form of -cache. Vulkan Memory Allocator can help you with that by supporting a concept of -"lost allocations". - -To create an allocation that can become lost, include #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT -flag in VmaAllocationCreateInfo::flags. Before using a buffer or image bound to -such allocation in every new frame, you need to query it if it's not lost. -To check it, call vmaTouchAllocation(). -If the allocation is lost, you should not use it or buffer/image bound to it. -You mustn't forget to destroy this allocation and this buffer/image. -vmaGetAllocationInfo() can also be used for checking status of the allocation. -Allocation is lost when returned VmaAllocationInfo::deviceMemory == `VK_NULL_HANDLE`. - -To create an allocation that can make some other allocations lost to make room -for it, use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag. You will -usually use both flags #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT and -#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT at the same time. - -Warning! Current implementation uses quite naive, brute force algorithm, -which can make allocation calls that use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT -flag quite slow. A new, more optimal algorithm and data structure to speed this -up is planned for the future. - -Q: When interleaving creation of new allocations with usage of existing ones, -how do you make sure that an allocation won't become lost while it's used in the -current frame? - -It is ensured because vmaTouchAllocation() / vmaGetAllocationInfo() not only returns allocation -status/parameters and checks whether it's not lost, but when it's not, it also -atomically marks it as used in the current frame, which makes it impossible to -become lost in that frame. It uses lockless algorithm, so it works fast and -doesn't involve locking any internal mutex. - -Q: What if my allocation may still be in use by the GPU when it's rendering a -previous frame while I already submit new frame on the CPU? - -You can make sure that allocations "touched" by vmaTouchAllocation() / vmaGetAllocationInfo() will not -become lost for a number of additional frames back from the current one by -specifying this number as VmaAllocatorCreateInfo::frameInUseCount (for default -memory pool) and VmaPoolCreateInfo::frameInUseCount (for custom pool). - -Q: How do you inform the library when new frame starts? - -You need to call function vmaSetCurrentFrameIndex(). - -Example code: - -\code -struct MyBuffer -{ - VkBuffer m_Buf = nullptr; - VmaAllocation m_Alloc = nullptr; - - // Called when the buffer is really needed in the current frame. - void EnsureBuffer(); -}; - -void MyBuffer::EnsureBuffer() -{ - // Buffer has been created. - if(m_Buf != VK_NULL_HANDLE) - { - // Check if its allocation is not lost + mark it as used in current frame. - if(vmaTouchAllocation(allocator, m_Alloc)) - { - // It's all OK - safe to use m_Buf. - return; - } - } - - // Buffer not yet exists or lost - destroy and recreate it. - - vmaDestroyBuffer(allocator, m_Buf, m_Alloc); - - VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; - bufCreateInfo.size = 1024; - bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - - VmaAllocationCreateInfo allocCreateInfo = {}; - allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; - allocCreateInfo.flags = VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT | - VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT; - - vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &m_Buf, &m_Alloc, nullptr); -} -\endcode - -When using lost allocations, you may see some Vulkan validation layer warnings -about overlapping regions of memory bound to different kinds of buffers and -images. This is still valid as long as you implement proper handling of lost -allocations (like in the example above) and don't use them. - -You can create an allocation that is already in lost state from the beginning using function -vmaCreateLostAllocation(). It may be useful if you need a "dummy" allocation that is not null. - -You can call function vmaMakePoolAllocationsLost() to set all eligible allocations -in a specified custom pool to lost state. -Allocations that have been "touched" in current frame or VmaPoolCreateInfo::frameInUseCount frames back -cannot become lost. - - -\page statistics Statistics - -This library contains functions that return information about its internal state, -especially the amount of memory allocated from Vulkan. -Please keep in mind that these functions need to traverse all internal data structures -to gather these information, so they may be quite time-consuming. -Don't call them too often. - -\section statistics_numeric_statistics Numeric statistics - -You can query for overall statistics of the allocator using function vmaCalculateStats(). -Information are returned using structure #VmaStats. -It contains #VmaStatInfo - number of allocated blocks, number of allocations -(occupied ranges in these blocks), number of unused (free) ranges in these blocks, -number of bytes used and unused (but still allocated from Vulkan) and other information. -They are summed across memory heaps, memory types and total for whole allocator. - -You can query for statistics of a custom pool using function vmaGetPoolStats(). -Information are returned using structure #VmaPoolStats. - -You can query for information about specific allocation using function vmaGetAllocationInfo(). -It fill structure #VmaAllocationInfo. - -\section statistics_json_dump JSON dump - -You can dump internal state of the allocator to a string in JSON format using function vmaBuildStatsString(). -The result is guaranteed to be correct JSON. -It uses ANSI encoding. -Any strings provided by user (see [Allocation names](@ref allocation_names)) -are copied as-is and properly escaped for JSON, so if they use UTF-8, ISO-8859-2 or any other encoding, -this JSON string can be treated as using this encoding. -It must be freed using function vmaFreeStatsString(). - -The format of this JSON string is not part of official documentation of the library, -but it will not change in backward-incompatible way without increasing library major version number -and appropriate mention in changelog. - -The JSON string contains all the data that can be obtained using vmaCalculateStats(). -It can also contain detailed map of allocated memory blocks and their regions - -free and occupied by allocations. -This allows e.g. to visualize the memory or assess fragmentation. - - -\page allocation_annotation Allocation names and user data - -\section allocation_user_data Allocation user data - -You can annotate allocations with your own information, e.g. for debugging purposes. -To do that, fill VmaAllocationCreateInfo::pUserData field when creating -an allocation. It's an opaque `void*` pointer. You can use it e.g. as a pointer, -some handle, index, key, ordinal number or any other value that would associate -the allocation with your custom metadata. - -\code -VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -// Fill bufferInfo... - -MyBufferMetadata* pMetadata = CreateBufferMetadata(); - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; -allocCreateInfo.pUserData = pMetadata; - -VkBuffer buffer; -VmaAllocation allocation; -vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, nullptr); -\endcode - -The pointer may be later retrieved as VmaAllocationInfo::pUserData: - -\code -VmaAllocationInfo allocInfo; -vmaGetAllocationInfo(allocator, allocation, &allocInfo); -MyBufferMetadata* pMetadata = (MyBufferMetadata*)allocInfo.pUserData; -\endcode - -It can also be changed using function vmaSetAllocationUserData(). - -Values of (non-zero) allocations' `pUserData` are printed in JSON report created by -vmaBuildStatsString(), in hexadecimal form. - -\section allocation_names Allocation names - -There is alternative mode available where `pUserData` pointer is used to point to -a null-terminated string, giving a name to the allocation. To use this mode, -set #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT flag in VmaAllocationCreateInfo::flags. -Then `pUserData` passed as VmaAllocationCreateInfo::pUserData or argument to -vmaSetAllocationUserData() must be either null or pointer to a null-terminated string. -The library creates internal copy of the string, so the pointer you pass doesn't need -to be valid for whole lifetime of the allocation. You can free it after the call. - -\code -VkImageCreateInfo imageInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; -// Fill imageInfo... - -std::string imageName = "Texture: "; -imageName += fileName; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; -allocCreateInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT; -allocCreateInfo.pUserData = imageName.c_str(); - -VkImage image; -VmaAllocation allocation; -vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &image, &allocation, nullptr); -\endcode - -The value of `pUserData` pointer of the allocation will be different than the one -you passed when setting allocation's name - pointing to a buffer managed -internally that holds copy of the string. - -\code -VmaAllocationInfo allocInfo; -vmaGetAllocationInfo(allocator, allocation, &allocInfo); -const char* imageName = (const char*)allocInfo.pUserData; -printf("Image name: %s\n", imageName); -\endcode - -That string is also printed in JSON report created by vmaBuildStatsString(). - - -\page usage_patterns Recommended usage patterns - -\section usage_patterns_simple Simple patterns - -\subsection usage_patterns_simple_render_targets Render targets - -When: -Any resources that you frequently write and read on GPU, -e.g. images used as color attachments (aka "render targets"), depth-stencil attachments, -images/buffers used as storage image/buffer (aka "Unordered Access View (UAV)"). - -What to do: -Create them in video memory that is fastest to access from GPU using -#VMA_MEMORY_USAGE_GPU_ONLY. - -Consider using [VK_KHR_dedicated_allocation](@ref vk_khr_dedicated_allocation) extension -and/or manually creating them as dedicated allocations using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, -especially if they are large or if you plan to destroy and recreate them e.g. when -display resolution changes. -Prefer to create such resources first and all other GPU resources (like textures and vertex buffers) later. - -\subsection usage_patterns_simple_immutable_resources Immutable resources - -When: -Any resources that you fill on CPU only once (aka "immutable") or infrequently -and then read frequently on GPU, -e.g. textures, vertex and index buffers, constant buffers that don't change often. - -What to do: -Create them in video memory that is fastest to access from GPU using -#VMA_MEMORY_USAGE_GPU_ONLY. - -To initialize content of such resource, create a CPU-side (aka "staging") copy of it -in system memory - #VMA_MEMORY_USAGE_CPU_ONLY, map it, fill it, -and submit a transfer from it to the GPU resource. -You can keep the staging copy if you need it for another upload transfer in the future. -If you don't, you can destroy it or reuse this buffer for uploading different resource -after the transfer finishes. - -Prefer to create just buffers in system memory rather than images, even for uploading textures. -Use `vkCmdCopyBufferToImage()`. -Dont use images with `VK_IMAGE_TILING_LINEAR`. - -\subsection usage_patterns_dynamic_resources Dynamic resources - -When: -Any resources that change frequently (aka "dynamic"), e.g. every frame or every draw call, -written on CPU, read on GPU. - -What to do: -Create them using #VMA_MEMORY_USAGE_CPU_TO_GPU. -You can map it and write to it directly on CPU, as well as read from it on GPU. - -This is a more complex situation. Different solutions are possible, -and the best one depends on specific GPU type, but you can use this simple approach for the start. -Prefer to write to such resource sequentially (e.g. using `memcpy`). -Don't perform random access or any reads from it, as it may be very slow. - -\subsection usage_patterns_readback Readback - -When: -Resources that contain data written by GPU that you want to read back on CPU, -e.g. results of some computations. - -What to do: -Create them using #VMA_MEMORY_USAGE_GPU_TO_CPU. -You can write to them directly on GPU, as well as map and read them on CPU. - -\section usage_patterns_advanced Advanced patterns - -\subsection usage_patterns_integrated_graphics Detecting integrated graphics - -You can support integrated graphics (like Intel HD Graphics, AMD APU) better -by detecting it in Vulkan. -To do it, call `vkGetPhysicalDeviceProperties()`, inspect -`VkPhysicalDeviceProperties::deviceType` and look for `VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU`. -When you find it, you can assume that memory is unified and all memory types are equally fast -to access from GPU, regardless of `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`. - -You can then sum up sizes of all available memory heaps and treat them as useful for -your GPU resources, instead of only `DEVICE_LOCAL` ones. -You can also prefer to create your resources in memory types that are `HOST_VISIBLE` to map them -directly instead of submitting explicit transfer (see below). - -\subsection usage_patterns_direct_vs_transfer Direct access versus transfer - -For resources that you frequently write on CPU and read on GPU, many solutions are possible: - --# Create one copy in video memory using #VMA_MEMORY_USAGE_GPU_ONLY, - second copy in system memory using #VMA_MEMORY_USAGE_CPU_ONLY and submit explicit tranfer each time. --# Create just single copy using #VMA_MEMORY_USAGE_CPU_TO_GPU, map it and fill it on CPU, - read it directly on GPU. --# Create just single copy using #VMA_MEMORY_USAGE_CPU_ONLY, map it and fill it on CPU, - read it directly on GPU. - -Which solution is the most efficient depends on your resource and especially on the GPU. -It is best to measure it and then make the decision. -Some general recommendations: - -- On integrated graphics use (2) or (3) to avoid unnecesary time and memory overhead - related to using a second copy. -- For small resources (e.g. constant buffers) use (2). - Discrete AMD cards have special 256 MiB pool of video memory that is directly mappable. - Even if the resource ends up in system memory, its data may be cached on GPU after first - fetch over PCIe bus. -- For larger resources (e.g. textures), decide between (1) and (2). - You may want to differentiate NVIDIA and AMD, e.g. by looking for memory type that is - both `DEVICE_LOCAL` and `HOST_VISIBLE`. When you find it, use (2), otherwise use (1). - -Similarly, for resources that you frequently write on GPU and read on CPU, multiple -solutions are possible: - --# Create one copy in video memory using #VMA_MEMORY_USAGE_GPU_ONLY, - second copy in system memory using #VMA_MEMORY_USAGE_GPU_TO_CPU and submit explicit tranfer each time. --# Create just single copy using #VMA_MEMORY_USAGE_GPU_TO_CPU, write to it directly on GPU, - map it and read it on CPU. - -You should take some measurements to decide which option is faster in case of your specific -resource. - -If you don't want to specialize your code for specific types of GPUs, yon can still make -an simple optimization for cases when your resource ends up in mappable memory to use it -directly in this case instead of creating CPU-side staging copy. -For details see [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable). - - -\page configuration Configuration - -Please check "CONFIGURATION SECTION" in the code to find macros that you can define -before each include of this file or change directly in this file to provide -your own implementation of basic facilities like assert, `min()` and `max()` functions, -mutex, atomic etc. -The library uses its own implementation of containers by default, but you can switch to using -STL containers instead. - -\section config_Vulkan_functions Pointers to Vulkan functions - -The library uses Vulkan functions straight from the `vulkan.h` header by default. -If you want to provide your own pointers to these functions, e.g. fetched using -`vkGetInstanceProcAddr()` and `vkGetDeviceProcAddr()`: - --# Define `VMA_STATIC_VULKAN_FUNCTIONS 0`. --# Provide valid pointers through VmaAllocatorCreateInfo::pVulkanFunctions. - -\section custom_memory_allocator Custom host memory allocator - -If you use custom allocator for CPU memory rather than default operator `new` -and `delete` from C++, you can make this library using your allocator as well -by filling optional member VmaAllocatorCreateInfo::pAllocationCallbacks. These -functions will be passed to Vulkan, as well as used by the library itself to -make any CPU-side allocations. - -\section allocation_callbacks Device memory allocation callbacks - -The library makes calls to `vkAllocateMemory()` and `vkFreeMemory()` internally. -You can setup callbacks to be informed about these calls, e.g. for the purpose -of gathering some statistics. To do it, fill optional member -VmaAllocatorCreateInfo::pDeviceMemoryCallbacks. - -\section heap_memory_limit Device heap memory limit - -If you want to test how your program behaves with limited amount of Vulkan device -memory available without switching your graphics card to one that really has -smaller VRAM, you can use a feature of this library intended for this purpose. -To do it, fill optional member VmaAllocatorCreateInfo::pHeapSizeLimit. - - - -\page vk_khr_dedicated_allocation VK_KHR_dedicated_allocation - -VK_KHR_dedicated_allocation is a Vulkan extension which can be used to improve -performance on some GPUs. It augments Vulkan API with possibility to query -driver whether it prefers particular buffer or image to have its own, dedicated -allocation (separate `VkDeviceMemory` block) for better efficiency - to be able -to do some internal optimizations. - -The extension is supported by this library. It will be used automatically when -enabled. To enable it: - -1 . When creating Vulkan device, check if following 2 device extensions are -supported (call `vkEnumerateDeviceExtensionProperties()`). -If yes, enable them (fill `VkDeviceCreateInfo::ppEnabledExtensionNames`). - -- VK_KHR_get_memory_requirements2 -- VK_KHR_dedicated_allocation - -If you enabled these extensions: - -2 . Use #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag when creating -your #VmaAllocator`to inform the library that you enabled required extensions -and you want the library to use them. - -\code -allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT; - -vmaCreateAllocator(&allocatorInfo, &allocator); -\endcode - -That's all. The extension will be automatically used whenever you create a -buffer using vmaCreateBuffer() or image using vmaCreateImage(). - -When using the extension together with Vulkan Validation Layer, you will receive -warnings like this: - - vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer. - -It is OK, you should just ignore it. It happens because you use function -`vkGetBufferMemoryRequirements2KHR()` instead of standard -`vkGetBufferMemoryRequirements()`, while the validation layer seems to be -unaware of it. - -To learn more about this extension, see: - -- [VK_KHR_dedicated_allocation in Vulkan specification](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_dedicated_allocation) -- [VK_KHR_dedicated_allocation unofficial manual](http://asawicki.info/articles/VK_KHR_dedicated_allocation.php5) - - - -\page general_considerations General considerations - -\section general_considerations_thread_safety Thread safety - -- The library has no global state, so separate #VmaAllocator objects can be used - independently. - There should be no need to create multiple such objects though - one per `VkDevice` is enough. -- By default, all calls to functions that take #VmaAllocator as first parameter - are safe to call from multiple threads simultaneously because they are - synchronized internally when needed. -- When the allocator is created with #VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT - flag, calls to functions that take such #VmaAllocator object must be - synchronized externally. -- Access to a #VmaAllocation object must be externally synchronized. For example, - you must not call vmaGetAllocationInfo() and vmaMapMemory() from different - threads at the same time if you pass the same #VmaAllocation object to these - functions. - -\section general_considerations_allocation_algorithm Allocation algorithm - -The library uses following algorithm for allocation, in order: - --# Try to find free range of memory in existing blocks. --# If failed, try to create a new block of `VkDeviceMemory`, with preferred block size. --# If failed, try to create such block with size/2, size/4, size/8. --# If failed and #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag was - specified, try to find space in existing blocks, possilby making some other - allocations lost. --# If failed, try to allocate separate `VkDeviceMemory` for this allocation, - just like when you use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. --# If failed, choose other memory type that meets the requirements specified in - VmaAllocationCreateInfo and go to point 1. --# If failed, return `VK_ERROR_OUT_OF_DEVICE_MEMORY`. - -\section general_considerations_features_not_supported Features not supported - -Features deliberately excluded from the scope of this library: - -- Data transfer - issuing commands that transfer data between buffers or images, any usage of - `VkCommandList` or `VkCommandQueue` and related synchronization is responsibility of the user. -- Support for any programming languages other than C/C++. - Bindings to other languages are welcomed as external projects. - */ -#include +#ifdef __cplusplus +extern "C" { +#endif + +/* +Define this macro to 0/1 to disable/enable support for recording functionality, +available through VmaAllocatorCreateInfo::pRecordSettings. +*/ +#ifndef VMA_RECORDING_ENABLED + #define VMA_RECORDING_ENABLED 0 +#endif + +#if defined(__ANDROID__) && defined(VK_NO_PROTOTYPES) && VMA_STATIC_VULKAN_FUNCTIONS + extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; + extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; + extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; + extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; + extern PFN_vkAllocateMemory vkAllocateMemory; + extern PFN_vkFreeMemory vkFreeMemory; + extern PFN_vkMapMemory vkMapMemory; + extern PFN_vkUnmapMemory vkUnmapMemory; + extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges; + extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges; + extern PFN_vkBindBufferMemory vkBindBufferMemory; + extern PFN_vkBindImageMemory vkBindImageMemory; + extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; + extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; + extern PFN_vkCreateBuffer vkCreateBuffer; + extern PFN_vkDestroyBuffer vkDestroyBuffer; + extern PFN_vkCreateImage vkCreateImage; + extern PFN_vkDestroyImage vkDestroyImage; + extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer; + #if VMA_VULKAN_VERSION >= 1001000 + extern PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2; + extern PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2; + extern PFN_vkBindBufferMemory2 vkBindBufferMemory2; + extern PFN_vkBindImageMemory2 vkBindImageMemory2; + extern PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2; + #endif // #if VMA_VULKAN_VERSION >= 1001000 +#endif // #if defined(__ANDROID__) && VMA_STATIC_VULKAN_FUNCTIONS && VK_NO_PROTOTYPES + +#ifndef VULKAN_H_ + #include +#endif + +// Define this macro to declare maximum supported Vulkan version in format AAABBBCCC, +// where AAA = major, BBB = minor, CCC = patch. +// If you want to use version > 1.0, it still needs to be enabled via VmaAllocatorCreateInfo::vulkanApiVersion. +#if !defined(VMA_VULKAN_VERSION) + #if defined(VK_VERSION_1_2) + #define VMA_VULKAN_VERSION 1002000 + #elif defined(VK_VERSION_1_1) + #define VMA_VULKAN_VERSION 1001000 + #else + #define VMA_VULKAN_VERSION 1000000 + #endif +#endif + +#if !defined(VMA_DEDICATED_ALLOCATION) + #if VK_KHR_get_memory_requirements2 && VK_KHR_dedicated_allocation + #define VMA_DEDICATED_ALLOCATION 1 + #else + #define VMA_DEDICATED_ALLOCATION 0 + #endif +#endif + +#if !defined(VMA_BIND_MEMORY2) + #if VK_KHR_bind_memory2 + #define VMA_BIND_MEMORY2 1 + #else + #define VMA_BIND_MEMORY2 0 + #endif +#endif + +#if !defined(VMA_MEMORY_BUDGET) + #if VK_EXT_memory_budget && (VK_KHR_get_physical_device_properties2 || VMA_VULKAN_VERSION >= 1001000) + #define VMA_MEMORY_BUDGET 1 + #else + #define VMA_MEMORY_BUDGET 0 + #endif +#endif + +// Defined to 1 when VK_KHR_buffer_device_address device extension or equivalent core Vulkan 1.2 feature is defined in its headers. +#if !defined(VMA_BUFFER_DEVICE_ADDRESS) + #if VK_KHR_buffer_device_address || VMA_VULKAN_VERSION >= 1002000 + #define VMA_BUFFER_DEVICE_ADDRESS 1 + #else + #define VMA_BUFFER_DEVICE_ADDRESS 0 + #endif +#endif + +// Defined to 1 when VK_EXT_memory_priority device extension is defined in Vulkan headers. +#if !defined(VMA_MEMORY_PRIORITY) + #if VK_EXT_memory_priority + #define VMA_MEMORY_PRIORITY 1 + #else + #define VMA_MEMORY_PRIORITY 0 + #endif +#endif + +// Defined to 1 when VK_KHR_external_memory device extension is defined in Vulkan headers. +#if !defined(VMA_EXTERNAL_MEMORY) + #if VK_KHR_external_memory + #define VMA_EXTERNAL_MEMORY 1 + #else + #define VMA_EXTERNAL_MEMORY 0 + #endif +#endif + +// Define these macros to decorate all public functions with additional code, +// before and after returned type, appropriately. This may be useful for +// exporting the functions when compiling VMA as a separate library. Example: +// #define VMA_CALL_PRE __declspec(dllexport) +// #define VMA_CALL_POST __cdecl +#ifndef VMA_CALL_PRE + #define VMA_CALL_PRE +#endif +#ifndef VMA_CALL_POST + #define VMA_CALL_POST +#endif + +// Define this macro to decorate pointers with an attribute specifying the +// length of the array they point to if they are not null. +// +// The length may be one of +// - The name of another parameter in the argument list where the pointer is declared +// - The name of another member in the struct where the pointer is declared +// - The name of a member of a struct type, meaning the value of that member in +// the context of the call. For example +// VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryHeapCount"), +// this means the number of memory heaps available in the device associated +// with the VmaAllocator being dealt with. +#ifndef VMA_LEN_IF_NOT_NULL + #define VMA_LEN_IF_NOT_NULL(len) +#endif + +// The VMA_NULLABLE macro is defined to be _Nullable when compiling with Clang. +// see: https://clang.llvm.org/docs/AttributeReference.html#nullable +#ifndef VMA_NULLABLE + #ifdef __clang__ + #define VMA_NULLABLE _Nullable + #else + #define VMA_NULLABLE + #endif +#endif + +// The VMA_NOT_NULL macro is defined to be _Nonnull when compiling with Clang. +// see: https://clang.llvm.org/docs/AttributeReference.html#nonnull +#ifndef VMA_NOT_NULL + #ifdef __clang__ + #define VMA_NOT_NULL _Nonnull + #else + #define VMA_NOT_NULL + #endif +#endif + +// If non-dispatchable handles are represented as pointers then we can give +// then nullability annotations +#ifndef VMA_NOT_NULL_NON_DISPATCHABLE + #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define VMA_NOT_NULL_NON_DISPATCHABLE VMA_NOT_NULL + #else + #define VMA_NOT_NULL_NON_DISPATCHABLE + #endif +#endif + +#ifndef VMA_NULLABLE_NON_DISPATCHABLE + #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define VMA_NULLABLE_NON_DISPATCHABLE VMA_NULLABLE + #else + #define VMA_NULLABLE_NON_DISPATCHABLE + #endif +#endif /** \struct VmaAllocator \brief Represents main object of this library initialized. -Fill structure VmaAllocatorCreateInfo and call function vmaCreateAllocator() to create it. +Fill structure #VmaAllocatorCreateInfo and call function vmaCreateAllocator() to create it. Call function vmaDestroyAllocator() to destroy it. It is recommended to create just one object of this type per `VkDevice` object, @@ -1086,16 +291,18 @@ VK_DEFINE_HANDLE(VmaAllocator) /// Callback function called after successful vkAllocateMemory. typedef void (VKAPI_PTR *PFN_vmaAllocateDeviceMemoryFunction)( - VmaAllocator allocator, - uint32_t memoryType, - VkDeviceMemory memory, - VkDeviceSize size); + VmaAllocator VMA_NOT_NULL allocator, + uint32_t memoryType, + VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory, + VkDeviceSize size, + void* VMA_NULLABLE pUserData); /// Callback function called before vkFreeMemory. typedef void (VKAPI_PTR *PFN_vmaFreeDeviceMemoryFunction)( - VmaAllocator allocator, - uint32_t memoryType, - VkDeviceMemory memory, - VkDeviceSize size); + VmaAllocator VMA_NOT_NULL allocator, + uint32_t memoryType, + VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory, + VkDeviceSize size, + void* VMA_NULLABLE pUserData); /** \brief Set of callbacks that the library will call for `vkAllocateMemory` and `vkFreeMemory`. @@ -1106,9 +313,11 @@ Used in VmaAllocatorCreateInfo::pDeviceMemoryCallbacks. */ typedef struct VmaDeviceMemoryCallbacks { /// Optional, can be null. - PFN_vmaAllocateDeviceMemoryFunction pfnAllocate; + PFN_vmaAllocateDeviceMemoryFunction VMA_NULLABLE pfnAllocate; /// Optional, can be null. - PFN_vmaFreeDeviceMemoryFunction pfnFree; + PFN_vmaFreeDeviceMemoryFunction VMA_NULLABLE pfnFree; + /// Optional, can be null. + void* VMA_NULLABLE pUserData; } VmaDeviceMemoryCallbacks; /// Flags for created #VmaAllocator. @@ -1120,7 +329,10 @@ typedef enum VmaAllocatorCreateFlagBits { VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, /** \brief Enables usage of VK_KHR_dedicated_allocation extension. - Using this extenion will automatically allocate dedicated blocks of memory for + The flag works only if VmaAllocatorCreateInfo::vulkanApiVersion `== VK_API_VERSION_1_0`. + When it is `VK_API_VERSION_1_1`, the flag is ignored because the extension has been promoted to Vulkan 1.1. + + Using this extension will automatically allocate dedicated blocks of memory for some buffers and images instead of suballocating place for them out of bigger memory blocks (as if you explicitly used #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag) when it is recommended by the driver. It may improve performance on some @@ -1131,15 +343,95 @@ typedef enum VmaAllocatorCreateFlagBits { VmaAllocatorCreateInfo::device, and you want them to be used internally by this library: - - VK_KHR_get_memory_requirements2 - - VK_KHR_dedicated_allocation + - VK_KHR_get_memory_requirements2 (device extension) + - VK_KHR_dedicated_allocation (device extension) -When this flag is set, you can experience following warnings reported by Vulkan -validation layer. You can ignore them. + When this flag is set, you can experience following warnings reported by Vulkan + validation layer. You can ignore them. -> vkBindBufferMemory(): Binding memory to buffer 0x2d but vkGetBufferMemoryRequirements() has not been called on that buffer. + > vkBindBufferMemory(): Binding memory to buffer 0x2d but vkGetBufferMemoryRequirements() has not been called on that buffer. */ VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT = 0x00000002, + /** + Enables usage of VK_KHR_bind_memory2 extension. + + The flag works only if VmaAllocatorCreateInfo::vulkanApiVersion `== VK_API_VERSION_1_0`. + When it is `VK_API_VERSION_1_1`, the flag is ignored because the extension has been promoted to Vulkan 1.1. + + You may set this flag only if you found out that this device extension is supported, + you enabled it while creating Vulkan device passed as VmaAllocatorCreateInfo::device, + and you want it to be used internally by this library. + + The extension provides functions `vkBindBufferMemory2KHR` and `vkBindImageMemory2KHR`, + which allow to pass a chain of `pNext` structures while binding. + This flag is required if you use `pNext` parameter in vmaBindBufferMemory2() or vmaBindImageMemory2(). + */ + VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT = 0x00000004, + /** + Enables usage of VK_EXT_memory_budget extension. + + You may set this flag only if you found out that this device extension is supported, + you enabled it while creating Vulkan device passed as VmaAllocatorCreateInfo::device, + and you want it to be used internally by this library, along with another instance extension + VK_KHR_get_physical_device_properties2, which is required by it (or Vulkan 1.1, where this extension is promoted). + + The extension provides query for current memory usage and budget, which will probably + be more accurate than an estimation used by the library otherwise. + */ + VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT = 0x00000008, + /** + Enables usage of VK_AMD_device_coherent_memory extension. + + You may set this flag only if you: + + - found out that this device extension is supported and enabled it while creating Vulkan device passed as VmaAllocatorCreateInfo::device, + - checked that `VkPhysicalDeviceCoherentMemoryFeaturesAMD::deviceCoherentMemory` is true and set it while creating the Vulkan device, + - want it to be used internally by this library. + + The extension and accompanying device feature provide access to memory types with + `VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD` and `VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD` flags. + They are useful mostly for writing breadcrumb markers - a common method for debugging GPU crash/hang/TDR. + + When the extension is not enabled, such memory types are still enumerated, but their usage is illegal. + To protect from this error, if you don't create the allocator with this flag, it will refuse to allocate any memory or create a custom pool in such memory type, + returning `VK_ERROR_FEATURE_NOT_PRESENT`. + */ + VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT = 0x00000010, + /** + Enables usage of "buffer device address" feature, which allows you to use function + `vkGetBufferDeviceAddress*` to get raw GPU pointer to a buffer and pass it for usage inside a shader. + + You may set this flag only if you: + + 1. (For Vulkan version < 1.2) Found as available and enabled device extension + VK_KHR_buffer_device_address. + This extension is promoted to core Vulkan 1.2. + 2. Found as available and enabled device feature `VkPhysicalDeviceBufferDeviceAddressFeatures::bufferDeviceAddress`. + + When this flag is set, you can create buffers with `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT` using VMA. + The library automatically adds `VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT` to + allocated memory blocks wherever it might be needed. + + For more information, see documentation chapter \ref enabling_buffer_device_address. + */ + VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT = 0x00000020, + /** + Enables usage of VK_EXT_memory_priority extension in the library. + + You may set this flag only if you found available and enabled this device extension, + along with `VkPhysicalDeviceMemoryPriorityFeaturesEXT::memoryPriority == VK_TRUE`, + while creating Vulkan device passed as VmaAllocatorCreateInfo::device. + + When this flag is used, VmaAllocationCreateInfo::priority and VmaPoolCreateInfo::priority + are used to set priorities of allocated Vulkan memory. Without it, these variables are ignored. + + A priority must be a floating-point value between 0 and 1, indicating the priority of the allocation relative to other memory allocations. + Larger values are higher priority. The granularity of the priorities is implementation-dependent. + It is automatically passed to every call to `vkAllocateMemory` done by the library using structure `VkMemoryPriorityAllocateInfoEXT`. + The value to be used for default priority is 0.5. + For more details, see the documentation of the VK_EXT_memory_priority extension. + */ + VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT = 0x00000040, VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VmaAllocatorCreateFlagBits; @@ -1150,24 +442,64 @@ typedef VkFlags VmaAllocatorCreateFlags; Used in VmaAllocatorCreateInfo::pVulkanFunctions. */ typedef struct VmaVulkanFunctions { - PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; - PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; - PFN_vkAllocateMemory vkAllocateMemory; - PFN_vkFreeMemory vkFreeMemory; - PFN_vkMapMemory vkMapMemory; - PFN_vkUnmapMemory vkUnmapMemory; - PFN_vkBindBufferMemory vkBindBufferMemory; - PFN_vkBindImageMemory vkBindImageMemory; - PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; - PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; - PFN_vkCreateBuffer vkCreateBuffer; - PFN_vkDestroyBuffer vkDestroyBuffer; - PFN_vkCreateImage vkCreateImage; - PFN_vkDestroyImage vkDestroyImage; - PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR; - PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR; + PFN_vkGetPhysicalDeviceProperties VMA_NULLABLE vkGetPhysicalDeviceProperties; + PFN_vkGetPhysicalDeviceMemoryProperties VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties; + PFN_vkAllocateMemory VMA_NULLABLE vkAllocateMemory; + PFN_vkFreeMemory VMA_NULLABLE vkFreeMemory; + PFN_vkMapMemory VMA_NULLABLE vkMapMemory; + PFN_vkUnmapMemory VMA_NULLABLE vkUnmapMemory; + PFN_vkFlushMappedMemoryRanges VMA_NULLABLE vkFlushMappedMemoryRanges; + PFN_vkInvalidateMappedMemoryRanges VMA_NULLABLE vkInvalidateMappedMemoryRanges; + PFN_vkBindBufferMemory VMA_NULLABLE vkBindBufferMemory; + PFN_vkBindImageMemory VMA_NULLABLE vkBindImageMemory; + PFN_vkGetBufferMemoryRequirements VMA_NULLABLE vkGetBufferMemoryRequirements; + PFN_vkGetImageMemoryRequirements VMA_NULLABLE vkGetImageMemoryRequirements; + PFN_vkCreateBuffer VMA_NULLABLE vkCreateBuffer; + PFN_vkDestroyBuffer VMA_NULLABLE vkDestroyBuffer; + PFN_vkCreateImage VMA_NULLABLE vkCreateImage; + PFN_vkDestroyImage VMA_NULLABLE vkDestroyImage; + PFN_vkCmdCopyBuffer VMA_NULLABLE vkCmdCopyBuffer; +#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + PFN_vkGetBufferMemoryRequirements2KHR VMA_NULLABLE vkGetBufferMemoryRequirements2KHR; + PFN_vkGetImageMemoryRequirements2KHR VMA_NULLABLE vkGetImageMemoryRequirements2KHR; +#endif +#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000 + PFN_vkBindBufferMemory2KHR VMA_NULLABLE vkBindBufferMemory2KHR; + PFN_vkBindImageMemory2KHR VMA_NULLABLE vkBindImageMemory2KHR; +#endif +#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000 + PFN_vkGetPhysicalDeviceMemoryProperties2KHR VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties2KHR; +#endif } VmaVulkanFunctions; +/// Flags to be used in VmaRecordSettings::flags. +typedef enum VmaRecordFlagBits { + /** \brief Enables flush after recording every function call. + + Enable it if you expect your application to crash, which may leave recording file truncated. + It may degrade performance though. + */ + VMA_RECORD_FLUSH_AFTER_CALL_BIT = 0x00000001, + + VMA_RECORD_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VmaRecordFlagBits; +typedef VkFlags VmaRecordFlags; + +/// Parameters for recording calls to VMA functions. To be used in VmaAllocatorCreateInfo::pRecordSettings. +typedef struct VmaRecordSettings +{ + /// Flags for recording. Use #VmaRecordFlagBits enum. + VmaRecordFlags flags; + /** \brief Path to the file that should be written by the recording. + + Suggested extension: "csv". + If the file already exists, it will be overwritten. + It will be opened for the whole time #VmaAllocator object is alive. + If opening this file fails, creation of the whole allocator object fails. + */ + const char* VMA_NOT_NULL pFilePath; +} VmaRecordSettings; + /// Description of a Allocator to be created. typedef struct VmaAllocatorCreateInfo { @@ -1175,19 +507,19 @@ typedef struct VmaAllocatorCreateInfo VmaAllocatorCreateFlags flags; /// Vulkan physical device. /** It must be valid throughout whole lifetime of created allocator. */ - VkPhysicalDevice physicalDevice; + VkPhysicalDevice VMA_NOT_NULL physicalDevice; /// Vulkan device. /** It must be valid throughout whole lifetime of created allocator. */ - VkDevice device; + VkDevice VMA_NOT_NULL device; /// Preferred size of a single `VkDeviceMemory` block to be allocated from large heaps > 1 GiB. Optional. /** Set to 0 to use default, which is currently 256 MiB. */ VkDeviceSize preferredLargeHeapBlockSize; /// Custom CPU memory allocation callbacks. Optional. /** Optional, can be null. When specified, will also be used for all CPU-side memory allocations. */ - const VkAllocationCallbacks* pAllocationCallbacks; + const VkAllocationCallbacks* VMA_NULLABLE pAllocationCallbacks; /// Informative callbacks for `vkAllocateMemory`, `vkFreeMemory`. Optional. /** Optional, can be null. */ - const VmaDeviceMemoryCallbacks* pDeviceMemoryCallbacks; + const VmaDeviceMemoryCallbacks* VMA_NULLABLE pDeviceMemoryCallbacks; /** \brief Maximum number of additional frames that are in use at the same time as current frame. This value is used only when you make allocations with @@ -1223,47 +555,103 @@ typedef struct VmaAllocatorCreateInfo smaller amount of memory, because graphics driver doesn't necessary fail new allocations with `VK_ERROR_OUT_OF_DEVICE_MEMORY` result when memory capacity is exceeded. It may return success and just silently migrate some device memory - blocks to system RAM. + blocks to system RAM. This driver behavior can also be controlled using + VK_AMD_memory_overallocation_behavior extension. */ - const VkDeviceSize* pHeapSizeLimit; - /** \brief Pointers to Vulkan functions. Can be null if you leave define `VMA_STATIC_VULKAN_FUNCTIONS 1`. + const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryHeapCount") pHeapSizeLimit; - If you leave define `VMA_STATIC_VULKAN_FUNCTIONS 1` in configuration section, - you can pass null as this member, because the library will fetch pointers to - Vulkan functions internally in a static way, like: + /** \brief Pointers to Vulkan functions. Can be null. - vulkanFunctions.vkAllocateMemory = &vkAllocateMemory; - - Fill this member if you want to provide your own pointers to Vulkan functions, - e.g. fetched using `vkGetInstanceProcAddr()` and `vkGetDeviceProcAddr()`. + For details see [Pointers to Vulkan functions](@ref config_Vulkan_functions). */ - const VmaVulkanFunctions* pVulkanFunctions; + const VmaVulkanFunctions* VMA_NULLABLE pVulkanFunctions; + /** \brief Parameters for recording of VMA calls. Can be null. + + If not null, it enables recording of calls to VMA functions to a file. + If support for recording is not enabled using `VMA_RECORDING_ENABLED` macro, + creation of the allocator object fails with `VK_ERROR_FEATURE_NOT_PRESENT`. + */ + const VmaRecordSettings* VMA_NULLABLE pRecordSettings; + /** \brief Handle to Vulkan instance object. + + Starting from version 3.0.0 this member is no longer optional, it must be set! + */ + VkInstance VMA_NOT_NULL instance; + /** \brief Optional. The highest version of Vulkan that the application is designed to use. + + It must be a value in the format as created by macro `VK_MAKE_VERSION` or a constant like: `VK_API_VERSION_1_1`, `VK_API_VERSION_1_0`. + The patch version number specified is ignored. Only the major and minor versions are considered. + It must be less or equal (preferably equal) to value as passed to `vkCreateInstance` as `VkApplicationInfo::apiVersion`. + Only versions 1.0, 1.1, 1.2 are supported by the current implementation. + Leaving it initialized to zero is equivalent to `VK_API_VERSION_1_0`. + */ + uint32_t vulkanApiVersion; +#if VMA_EXTERNAL_MEMORY + /** \brief Either null or a pointer to an array of external memory handle types for each Vulkan memory type. + + If not NULL, it must be a pointer to an array of `VkPhysicalDeviceMemoryProperties::memoryTypeCount` + elements, defining external memory handle types of particular Vulkan memory type, + to be passed using `VkExportMemoryAllocateInfoKHR`. + + Any of the elements may be equal to 0, which means not to use `VkExportMemoryAllocateInfoKHR` on this memory type. + This is also the default in case of `pTypeExternalMemoryHandleTypes` = NULL. + */ + const VkExternalMemoryHandleTypeFlagsKHR* VMA_NULLABLE VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryTypeCount") pTypeExternalMemoryHandleTypes; +#endif // #if VMA_EXTERNAL_MEMORY } VmaAllocatorCreateInfo; /// Creates Allocator object. -VkResult vmaCreateAllocator( - const VmaAllocatorCreateInfo* pCreateInfo, - VmaAllocator* pAllocator); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator( + const VmaAllocatorCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaAllocator VMA_NULLABLE * VMA_NOT_NULL pAllocator); /// Destroys allocator object. -void vmaDestroyAllocator( - VmaAllocator allocator); +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator( + VmaAllocator VMA_NULLABLE allocator); + +/** \brief Information about existing #VmaAllocator object. +*/ +typedef struct VmaAllocatorInfo +{ + /** \brief Handle to Vulkan instance object. + + This is the same value as has been passed through VmaAllocatorCreateInfo::instance. + */ + VkInstance VMA_NOT_NULL instance; + /** \brief Handle to Vulkan physical device object. + + This is the same value as has been passed through VmaAllocatorCreateInfo::physicalDevice. + */ + VkPhysicalDevice VMA_NOT_NULL physicalDevice; + /** \brief Handle to Vulkan device object. + + This is the same value as has been passed through VmaAllocatorCreateInfo::device. + */ + VkDevice VMA_NOT_NULL device; +} VmaAllocatorInfo; + +/** \brief Returns information about existing #VmaAllocator object - handle to Vulkan device etc. + +It might be useful if you want to keep just the #VmaAllocator handle and fetch other required handles to +`VkPhysicalDevice`, `VkDevice` etc. every time using this function. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocatorInfo(VmaAllocator VMA_NOT_NULL allocator, VmaAllocatorInfo* VMA_NOT_NULL pAllocatorInfo); /** PhysicalDeviceProperties are fetched from physicalDevice by the allocator. You can access it here, without fetching it again on your own. */ -void vmaGetPhysicalDeviceProperties( - VmaAllocator allocator, - const VkPhysicalDeviceProperties** ppPhysicalDeviceProperties); +VMA_CALL_PRE void VMA_CALL_POST vmaGetPhysicalDeviceProperties( + VmaAllocator VMA_NOT_NULL allocator, + const VkPhysicalDeviceProperties* VMA_NULLABLE * VMA_NOT_NULL ppPhysicalDeviceProperties); /** PhysicalDeviceMemoryProperties are fetched from physicalDevice by the allocator. You can access it here, without fetching it again on your own. */ -void vmaGetMemoryProperties( - VmaAllocator allocator, - const VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties); +VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryProperties( + VmaAllocator VMA_NOT_NULL allocator, + const VkPhysicalDeviceMemoryProperties* VMA_NULLABLE * VMA_NOT_NULL ppPhysicalDeviceMemoryProperties); /** \brief Given Memory Type Index, returns Property Flags of this memory type. @@ -1271,10 +659,10 @@ void vmaGetMemoryProperties( This is just a convenience function. Same information can be obtained using vmaGetMemoryProperties(). */ -void vmaGetMemoryTypeProperties( - VmaAllocator allocator, +VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryTypeProperties( + VmaAllocator VMA_NOT_NULL allocator, uint32_t memoryTypeIndex, - VkMemoryPropertyFlags* pFlags); + VkMemoryPropertyFlags* VMA_NOT_NULL pFlags); /** \brief Sets index of the current frame. @@ -1284,8 +672,8 @@ This function must be used if you make allocations with when a new frame begins. Allocations queried using vmaGetAllocationInfo() cannot become lost in the current frame. */ -void vmaSetCurrentFrameIndex( - VmaAllocator allocator, +VMA_CALL_PRE void VMA_CALL_POST vmaSetCurrentFrameIndex( + VmaAllocator VMA_NOT_NULL allocator, uint32_t frameIndex); /** \brief Calculated statistics of memory usage in entire allocator. @@ -1314,26 +702,95 @@ typedef struct VmaStats VmaStatInfo total; } VmaStats; -/// Retrieves statistics from current state of the Allocator. -void vmaCalculateStats( - VmaAllocator allocator, - VmaStats* pStats); +/** \brief Retrieves statistics from current state of the Allocator. +This function is called "calculate" not "get" because it has to traverse all +internal data structures, so it may be quite slow. For faster but more brief statistics +suitable to be called every frame or every allocation, use vmaGetBudget(). + +Note that when using allocator from multiple threads, returned information may immediately +become outdated. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStats( + VmaAllocator VMA_NOT_NULL allocator, + VmaStats* VMA_NOT_NULL pStats); + +/** \brief Statistics of current memory usage and available budget, in bytes, for specific memory heap. +*/ +typedef struct VmaBudget +{ + /** \brief Sum size of all `VkDeviceMemory` blocks allocated from particular heap, in bytes. + */ + VkDeviceSize blockBytes; + + /** \brief Sum size of all allocations created in particular heap, in bytes. + + Usually less or equal than `blockBytes`. + Difference `blockBytes - allocationBytes` is the amount of memory allocated but unused - + available for new allocations or wasted due to fragmentation. + + It might be greater than `blockBytes` if there are some allocations in lost state, as they account + to this value as well. + */ + VkDeviceSize allocationBytes; + + /** \brief Estimated current memory usage of the program, in bytes. + + Fetched from system using `VK_EXT_memory_budget` extension if enabled. + + It might be different than `blockBytes` (usually higher) due to additional implicit objects + also occupying the memory, like swapchain, pipelines, descriptor heaps, command buffers, or + `VkDeviceMemory` blocks allocated outside of this library, if any. + */ + VkDeviceSize usage; + + /** \brief Estimated amount of memory available to the program, in bytes. + + Fetched from system using `VK_EXT_memory_budget` extension if enabled. + + It might be different (most probably smaller) than `VkMemoryHeap::size[heapIndex]` due to factors + external to the program, like other programs also consuming system resources. + Difference `budget - usage` is the amount of additional memory that can probably + be allocated without problems. Exceeding the budget may result in various problems. + */ + VkDeviceSize budget; +} VmaBudget; + +/** \brief Retrieves information about current memory budget for all memory heaps. + +\param allocator +\param[out] pBudget Must point to array with number of elements at least equal to number of memory heaps in physical device used. + +This function is called "get" not "calculate" because it is very fast, suitable to be called +every frame or every allocation. For more detailed statistics use vmaCalculateStats(). + +Note that when using allocator from multiple threads, returned information may immediately +become outdated. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetBudget( + VmaAllocator VMA_NOT_NULL allocator, + VmaBudget* VMA_NOT_NULL pBudget); + +#ifndef VMA_STATS_STRING_ENABLED #define VMA_STATS_STRING_ENABLED 1 +#endif #if VMA_STATS_STRING_ENABLED /// Builds and returns statistics as string in JSON format. -/** @param[out] ppStatsString Must be freed using vmaFreeStatsString() function. +/** +@param allocator +@param[out] ppStatsString Must be freed using vmaFreeStatsString() function. +@param detailedMap */ -void vmaBuildStatsString( - VmaAllocator allocator, - char** ppStatsString, +VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString( + VmaAllocator VMA_NOT_NULL allocator, + char* VMA_NULLABLE * VMA_NOT_NULL ppStatsString, VkBool32 detailedMap); -void vmaFreeStatsString( - VmaAllocator allocator, - char* pStatsString); +VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString( + VmaAllocator VMA_NOT_NULL allocator, + char* VMA_NULLABLE pStatsString); #endif // #if VMA_STATS_STRING_ENABLED @@ -1359,11 +816,11 @@ typedef enum VmaMemoryUsage It is roughly equivalent of `D3D12_HEAP_TYPE_DEFAULT`. Usage: - + - Resources written and read by device, e.g. images used as attachments. - Resources transferred from host once (immutable) or infrequently and read by device multiple times, e.g. textures to be sampled, vertex buffers, uniform - (constant) buffers, and majority of other types of resources used by device. + (constant) buffers, and majority of other types of resources used on GPU. Allocation may still end up in `HOST_VISIBLE` memory on some implementations. In such case, you are free to map it. @@ -1372,9 +829,9 @@ typedef enum VmaMemoryUsage VMA_MEMORY_USAGE_GPU_ONLY = 1, /** Memory will be mappable on host. It usually means CPU (system) memory. - Resources created in this pool may still be accessible to the device, but access to them can be slower. Guarantees to be `HOST_VISIBLE` and `HOST_COHERENT`. - CPU read may be uncached. + CPU access is typically uncached. Writes may be write-combined. + Resources created in this pool may still be accessible to the device, but access to them can be slow. It is roughly equivalent of `D3D12_HEAP_TYPE_UPLOAD`. Usage: Staging copy of resources used as transfer source. @@ -1382,9 +839,9 @@ typedef enum VmaMemoryUsage VMA_MEMORY_USAGE_CPU_ONLY = 2, /** Memory that is both mappable on host (guarantees to be `HOST_VISIBLE`) and preferably fast to access by GPU. - CPU reads may be uncached and very slow. + CPU access is typically uncached. Writes may be write-combined. - Usage: Resources written frequently by host (dynamic), read by device. E.g. textures, vertex buffers, uniform buffers updated every frame or every draw call. + Usage: Resources written frequently by host (dynamic), read by device. E.g. textures (with LINEAR layout), vertex buffers, uniform buffers updated every frame or every draw call. */ VMA_MEMORY_USAGE_CPU_TO_GPU = 3, /** Memory mappable on host (guarantees to be `HOST_VISIBLE`) and cached. @@ -1396,39 +853,49 @@ typedef enum VmaMemoryUsage - Any resources read or accessed randomly on host, e.g. CPU-side copy of vertex buffer used as source of transfer, but also used for collision detection. */ VMA_MEMORY_USAGE_GPU_TO_CPU = 4, + /** CPU memory - memory that is preferably not `DEVICE_LOCAL`, but also not guaranteed to be `HOST_VISIBLE`. + + Usage: Staging copy of resources moved from GPU memory to CPU memory as part + of custom paging/residency mechanism, to be moved back to GPU memory when needed. + */ + VMA_MEMORY_USAGE_CPU_COPY = 5, + /** Lazily allocated GPU memory having `VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT`. + Exists mostly on mobile platforms. Using it on desktop PC or other GPUs with no such memory type present will fail the allocation. + + Usage: Memory for transient attachment images (color attachments, depth attachments etc.), created with `VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT`. + + Allocations with this usage are always created as dedicated - it implies #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. + */ + VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED = 6, + VMA_MEMORY_USAGE_MAX_ENUM = 0x7FFFFFFF } VmaMemoryUsage; /// Flags to be passed as VmaAllocationCreateInfo::flags. typedef enum VmaAllocationCreateFlagBits { /** \brief Set this flag if the allocation should have its own memory block. - + Use it for special, big resources, like fullscreen images used as attachments. - - This flag must also be used for host visible resources that you want to map - simultaneously because otherwise they might end up as regions of the same - `VkDeviceMemory`, while mapping same `VkDeviceMemory` multiple times - simultaneously is illegal. You should not use this flag if VmaAllocationCreateInfo::pool is not null. */ VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT = 0x00000001, /** \brief Set this flag to only try to allocate from existing `VkDeviceMemory` blocks and never create new such block. - + If new allocation cannot be placed in any of the existing blocks, allocation fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY` error. - + You should not use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT and #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT at the same time. It makes no sense. - + If VmaAllocationCreateInfo::pool is not null, this flag is implied and ignored. */ VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT = 0x00000002, /** \brief Set this flag to use a memory that will be persistently mapped and retrieve pointer to it. - + Pointer to mapped memory will be returned through VmaAllocationInfo::pMappedData. - Is it valid to use this flag for allocation made from memory type that is not + It is valid to use this flag for allocation made from memory type that is not `HOST_VISIBLE`. This flag is then ignored and memory is not mapped. This is useful if you need an allocation that is efficient to use on GPU (`DEVICE_LOCAL`) and still want to map it directly if possible on platforms that @@ -1463,6 +930,54 @@ typedef enum VmaAllocationCreateFlagBits { freed together with the allocation. It is also used in vmaBuildStatsString(). */ VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = 0x00000020, + /** Allocation will be created from upper stack in a double stack pool. + + This flag is only allowed for custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT flag. + */ + VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = 0x00000040, + /** Create both buffer/image and allocation, but don't bind them together. + It is useful when you want to bind yourself to do some more advanced binding, e.g. using some extensions. + The flag is meaningful only with functions that bind by default: vmaCreateBuffer(), vmaCreateImage(). + Otherwise it is ignored. + */ + VMA_ALLOCATION_CREATE_DONT_BIND_BIT = 0x00000080, + /** Create allocation only if additional device memory required for it, if any, won't exceed + memory budget. Otherwise return `VK_ERROR_OUT_OF_DEVICE_MEMORY`. + */ + VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT = 0x00000100, + + /** Allocation strategy that chooses smallest possible free range for the + allocation. + */ + VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = 0x00010000, + /** Allocation strategy that chooses biggest possible free range for the + allocation. + */ + VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT = 0x00020000, + /** Allocation strategy that chooses first suitable free range for the + allocation. + + "First" doesn't necessarily means the one with smallest offset in memory, + but rather the one that is easiest and fastest to find. + */ + VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = 0x00040000, + + /** Allocation strategy that tries to minimize memory usage. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT, + /** Allocation strategy that tries to minimize allocation time. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT, + /** Allocation strategy that tries to minimize memory fragmentation. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT = VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT, + + /** A bit mask to extract only `STRATEGY` bits from entire set of flags. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MASK = + VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT | + VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT | + VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT, VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VmaAllocationCreateFlagBits; @@ -1473,19 +988,19 @@ typedef struct VmaAllocationCreateInfo /// Use #VmaAllocationCreateFlagBits enum. VmaAllocationCreateFlags flags; /** \brief Intended usage of memory. - + You can leave #VMA_MEMORY_USAGE_UNKNOWN if you specify memory requirements in other way. \n If `pool` is not null, this member is ignored. */ VmaMemoryUsage usage; /** \brief Flags that must be set in a Memory Type chosen for an allocation. - + Leave 0 if you specify memory requirements in other way. \n If `pool` is not null, this member is ignored.*/ VkMemoryPropertyFlags requiredFlags; /** \brief Flags that preferably should be set in a memory type chosen for an allocation. - - Set to 0 if no additional flags are prefered. \n + + Set to 0 if no additional flags are preferred. \n If `pool` is not null, this member is ignored. */ VkMemoryPropertyFlags preferredFlags; /** \brief Bitmask containing one bit set for every memory type acceptable for this allocation. @@ -1501,14 +1016,21 @@ typedef struct VmaAllocationCreateInfo Leave `VK_NULL_HANDLE` to allocate from default pool. If not null, members: `usage`, `requiredFlags`, `preferredFlags`, `memoryTypeBits` are ignored. */ - VmaPool pool; + VmaPool VMA_NULLABLE pool; /** \brief Custom general-purpose pointer that will be stored in #VmaAllocation, can be read as VmaAllocationInfo::pUserData and changed using vmaSetAllocationUserData(). - + If #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT is used, it must be either null or pointer to a null-terminated string. The string will be then copied to internal buffer, so it doesn't need to be valid after allocation call. */ - void* pUserData; + void* VMA_NULLABLE pUserData; + /** \brief A floating-point value between 0 and 1, indicating the priority of the allocation relative to other memory allocations. + + It is used only when #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT flag was used during creation of the #VmaAllocator object + and this allocation ends up as dedicated or is explicitly forced as dedicated using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. + Otherwise, it has the priority of a memory block where it is placed and this variable is ignored. + */ + float priority; } VmaAllocationCreateInfo; /** @@ -1527,11 +1049,11 @@ device doesn't support any memory type with requested features for the specific type of resource you want to use it for. Please check parameters of your resource, like image layout (OPTIMAL versus LINEAR) or mip level count. */ -VkResult vmaFindMemoryTypeIndex( - VmaAllocator allocator, +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex( + VmaAllocator VMA_NOT_NULL allocator, uint32_t memoryTypeBits, - const VmaAllocationCreateInfo* pAllocationCreateInfo, - uint32_t* pMemoryTypeIndex); + const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, + uint32_t* VMA_NOT_NULL pMemoryTypeIndex); /** \brief Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo. @@ -1545,11 +1067,11 @@ It is just a convenience function, equivalent to calling: - `vmaFindMemoryTypeIndex` - `vkDestroyBuffer` */ -VkResult vmaFindMemoryTypeIndexForBufferInfo( - VmaAllocator allocator, - const VkBufferCreateInfo* pBufferCreateInfo, - const VmaAllocationCreateInfo* pAllocationCreateInfo, - uint32_t* pMemoryTypeIndex); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo( + VmaAllocator VMA_NOT_NULL allocator, + const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo, + const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, + uint32_t* VMA_NOT_NULL pMemoryTypeIndex); /** \brief Helps to find memoryTypeIndex, given VkImageCreateInfo and VmaAllocationCreateInfo. @@ -1563,17 +1085,17 @@ It is just a convenience function, equivalent to calling: - `vmaFindMemoryTypeIndex` - `vkDestroyImage` */ -VkResult vmaFindMemoryTypeIndexForImageInfo( - VmaAllocator allocator, - const VkImageCreateInfo* pImageCreateInfo, - const VmaAllocationCreateInfo* pAllocationCreateInfo, - uint32_t* pMemoryTypeIndex); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo( + VmaAllocator VMA_NOT_NULL allocator, + const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo, + const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, + uint32_t* VMA_NOT_NULL pMemoryTypeIndex); /// Flags to be passed as VmaPoolCreateInfo::flags. typedef enum VmaPoolCreateFlagBits { /** \brief Use this flag if you always allocate only buffers and linear images or only optimal images out of this pool and so Buffer-Image Granularity can be ignored. - This is na optional optimization flag. + This is an optional optimization flag. If you always allocate using vmaCreateBuffer(), vmaCreateImage(), vmaAllocateMemoryForBuffer(), then you don't need to use it because allocator @@ -1586,10 +1108,44 @@ typedef enum VmaPoolCreateFlagBits { (wasted memory). In that case, if you can make sure you always allocate only buffers and linear images or only optimal images out of this pool, use this flag to make allocator disregard Buffer-Image Granularity and so make allocations - more optimal. + faster and more optimal. */ VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002, + /** \brief Enables alternative, linear allocation algorithm in this pool. + + Specify this flag to enable linear allocation algorithm, which always creates + new allocations after last one and doesn't reuse space from allocations freed in + between. It trades memory consumption for simplified algorithm and data + structure, which has better performance and uses less memory for metadata. + + By using this flag, you can achieve behavior of free-at-once, stack, + ring buffer, and double stack. For details, see documentation chapter + \ref linear_algorithm. + + When using this flag, you must specify VmaPoolCreateInfo::maxBlockCount == 1 (or 0 for default). + + For more details, see [Linear allocation algorithm](@ref linear_algorithm). + */ + VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004, + + /** \brief Enables alternative, buddy allocation algorithm in this pool. + + It operates on a tree of blocks, each having size that is a power of two and + a half of its parent's size. Comparing to default algorithm, this one provides + faster allocation and deallocation and decreased external fragmentation, + at the expense of more memory wasted (internal fragmentation). + + For more details, see [Buddy allocation algorithm](@ref buddy_algorithm). + */ + VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT = 0x00000008, + + /** Bit mask to extract only `ALGORITHM` bits from entire set of flags. + */ + VMA_POOL_CREATE_ALGORITHM_MASK = + VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT | + VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT, + VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VmaPoolCreateFlagBits; typedef VkFlags VmaPoolCreateFlags; @@ -1603,22 +1159,26 @@ typedef struct VmaPoolCreateInfo { /** \brief Use combination of #VmaPoolCreateFlagBits. */ VmaPoolCreateFlags flags; - /** \brief Size of a single `VkDeviceMemory` block to be allocated as part of this pool, in bytes. + /** \brief Size of a single `VkDeviceMemory` block to be allocated as part of this pool, in bytes. Optional. - Optional. Leave 0 to use default. + Specify nonzero to set explicit, constant size of memory blocks used by this + pool. + + Leave 0 to use default and let the library manage block sizes automatically. + Sizes of particular blocks may vary. */ VkDeviceSize blockSize; /** \brief Minimum number of blocks to be always allocated in this pool, even if they stay empty. - Set to 0 to have no preallocated blocks and let the pool be completely empty. + Set to 0 to have no preallocated blocks and allow the pool be completely empty. */ size_t minBlockCount; /** \brief Maximum number of blocks that can be allocated in this pool. Optional. - Optional. Set to 0 to use `SIZE_MAX`, which means no limit. - - Set to same value as minBlockCount to have fixed amount of memory allocated - throuout whole lifetime of this pool. + Set to 0 to use default, which is `SIZE_MAX`, which means no limit. + + Set to same value as VmaPoolCreateInfo::minBlockCount to have fixed amount of memory allocated + throughout whole lifetime of this pool. */ size_t maxBlockCount; /** \brief Maximum number of additional frames that are in use at the same time as current frame. @@ -1635,6 +1195,29 @@ typedef struct VmaPoolCreateInfo { become lost, set this value to 0. */ uint32_t frameInUseCount; + /** \brief A floating-point value between 0 and 1, indicating the priority of the allocations in this pool relative to other memory allocations. + + It is used only when #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT flag was used during creation of the #VmaAllocator object. + Otherwise, this variable is ignored. + */ + float priority; + /** \brief Additional minimum alignment to be used for all allocations created from this pool. Can be 0. + + Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two. + It can be useful in cases where alignment returned by Vulkan by functions like `vkGetBufferMemoryRequirements` is not enough, + e.g. when doing interop with OpenGL. + */ + VkDeviceSize minAllocationAlignment; + /** \brief Additional `pNext` chain to be attached to `VkMemoryAllocateInfo` used for every allocation made by this pool. Optional. + + Optional, can be null. If not null, it must point to a `pNext` chain of structures that can be attached to `VkMemoryAllocateInfo`. + It can be useful for special needs such as adding `VkExportMemoryAllocateInfoKHR`. + Structures pointed by this member must remain alive and unchanged for the whole lifetime of the custom pool. + + Please note that some structures, e.g. `VkMemoryPriorityAllocateInfoEXT`, `VkMemoryDedicatedAllocateInfoKHR`, + can be attached automatically by this library when using other, more convenient of its features. + */ + void* VMA_NULLABLE pMemoryAllocateNext; } VmaPoolCreateInfo; /** \brief Describes parameter of existing #VmaPool. @@ -1652,13 +1235,16 @@ typedef struct VmaPoolStats { /** \brief Number of continuous memory ranges in the pool not used by any #VmaAllocation. */ size_t unusedRangeCount; - /** \brief Size of the largest continuous free memory region. + /** \brief Size of the largest continuous free memory region available for new allocation. Making a new allocation of that size is not guaranteed to succeed because of possible additional margin required to respect alignment and buffer/image granularity. */ VkDeviceSize unusedRangeSizeMax; + /** \brief Number of `VkDeviceMemory` blocks allocated for this pool. + */ + size_t blockCount; } VmaPoolStats; /** \brief Allocates Vulkan device memory and creates #VmaPool object. @@ -1667,16 +1253,16 @@ typedef struct VmaPoolStats { @param pCreateInfo Parameters of pool to create. @param[out] pPool Handle to created pool. */ -VkResult vmaCreatePool( - VmaAllocator allocator, - const VmaPoolCreateInfo* pCreateInfo, - VmaPool* pPool); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreatePool( + VmaAllocator VMA_NOT_NULL allocator, + const VmaPoolCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaPool VMA_NULLABLE * VMA_NOT_NULL pPool); /** \brief Destroys #VmaPool object and frees Vulkan device memory. */ -void vmaDestroyPool( - VmaAllocator allocator, - VmaPool pool); +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool( + VmaAllocator VMA_NOT_NULL allocator, + VmaPool VMA_NULLABLE pool); /** \brief Retrieves statistics of existing #VmaPool object. @@ -1684,10 +1270,10 @@ void vmaDestroyPool( @param pool Pool object. @param[out] pPoolStats Statistics of specified pool. */ -void vmaGetPoolStats( - VmaAllocator allocator, - VmaPool pool, - VmaPoolStats* pPoolStats); +VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStats( + VmaAllocator VMA_NOT_NULL allocator, + VmaPool VMA_NOT_NULL pool, + VmaPoolStats* VMA_NOT_NULL pPoolStats); /** \brief Marks all allocations in given pool as lost if they are not used in current frame or VmaPoolCreateInfo::frameInUseCount back from now. @@ -1695,10 +1281,47 @@ void vmaGetPoolStats( @param pool Pool. @param[out] pLostAllocationCount Number of allocations marked as lost. Optional - pass null if you don't need this information. */ -void vmaMakePoolAllocationsLost( - VmaAllocator allocator, - VmaPool pool, - size_t* pLostAllocationCount); +VMA_CALL_PRE void VMA_CALL_POST vmaMakePoolAllocationsLost( + VmaAllocator VMA_NOT_NULL allocator, + VmaPool VMA_NOT_NULL pool, + size_t* VMA_NULLABLE pLostAllocationCount); + +/** \brief Checks magic number in margins around all allocations in given memory pool in search for corruptions. + +Corruption detection is enabled only when `VMA_DEBUG_DETECT_CORRUPTION` macro is defined to nonzero, +`VMA_DEBUG_MARGIN` is defined to nonzero and the pool is created in memory type that is +`HOST_VISIBLE` and `HOST_COHERENT`. For more information, see [Corruption detection](@ref debugging_memory_usage_corruption_detection). + +Possible return values: + +- `VK_ERROR_FEATURE_NOT_PRESENT` - corruption detection is not enabled for specified pool. +- `VK_SUCCESS` - corruption detection has been performed and succeeded. +- `VK_ERROR_UNKNOWN` - corruption detection has been performed and found memory corruptions around one of the allocations. + `VMA_ASSERT` is also fired in that case. +- Other value: Error returned by Vulkan, e.g. memory mapping failure. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(VmaAllocator VMA_NOT_NULL allocator, VmaPool VMA_NOT_NULL pool); + +/** \brief Retrieves name of a custom pool. + +After the call `ppName` is either null or points to an internally-owned null-terminated string +containing name of the pool that was previously set. The pointer becomes invalid when the pool is +destroyed or its name is changed using vmaSetPoolName(). +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName( + VmaAllocator VMA_NOT_NULL allocator, + VmaPool VMA_NOT_NULL pool, + const char* VMA_NULLABLE * VMA_NOT_NULL ppName); + +/** \brief Sets name of a custom pool. + +`pName` can be either null or pointer to a null-terminated string with new name for the pool. +Function makes internal copy of the string, so it can be changed or freed immediately after this call. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName( + VmaAllocator VMA_NOT_NULL allocator, + VmaPool VMA_NOT_NULL pool, + const char* VMA_NULLABLE pName); /** \struct VmaAllocation \brief Represents single memory allocation. @@ -1730,20 +1353,25 @@ VK_DEFINE_HANDLE(VmaAllocation) */ typedef struct VmaAllocationInfo { /** \brief Memory type index that this allocation was allocated from. - + It never changes. */ uint32_t memoryType; /** \brief Handle to Vulkan memory object. Same memory object can be shared by multiple allocations. - + It can change after call to vmaDefragment() if this allocation is passed to the function, or if allocation is lost. If the allocation is lost, it is equal to `VK_NULL_HANDLE`. */ - VkDeviceMemory deviceMemory; - /** \brief Offset into deviceMemory object to the beginning of this allocation, in bytes. (deviceMemory, offset) pair is unique to this allocation. + VkDeviceMemory VMA_NULLABLE_NON_DISPATCHABLE deviceMemory; + /** \brief Offset in `VkDeviceMemory` object to the beginning of this allocation, in bytes. `(deviceMemory, offset)` pair is unique to this allocation. + + You usually don't need to use this offset. If you create a buffer or an image together with the allocation using e.g. function + vmaCreateBuffer(), vmaCreateImage(), functions that operate on these resources refer to the beginning of the buffer or image, + not entire device memory block. Functions like vmaMapMemory(), vmaBindBufferMemory() also refer to the beginning of the allocation + and apply this offset automatically. It can change after call to vmaDefragment() if this allocation is passed to the function, or if allocation is lost. */ @@ -1751,70 +1379,127 @@ typedef struct VmaAllocationInfo { /** \brief Size of this allocation, in bytes. It never changes, unless allocation is lost. + + \note Allocation size returned in this variable may be greater than the size + requested for the resource e.g. as `VkBufferCreateInfo::size`. Whole size of the + allocation is accessible for operations on memory e.g. using a pointer after + mapping with vmaMapMemory(), but operations on the resource e.g. using + `vkCmdCopyBuffer` must be limited to the size of the resource. */ VkDeviceSize size; /** \brief Pointer to the beginning of this allocation as mapped data. If the allocation hasn't been mapped using vmaMapMemory() and hasn't been - created with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag, this value null. + created with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag, this value is null. It can change after call to vmaMapMemory(), vmaUnmapMemory(). It can also change after call to vmaDefragment() if this allocation is passed to the function. */ - void* pMappedData; + void* VMA_NULLABLE pMappedData; /** \brief Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vmaSetAllocationUserData(). It can change after call to vmaSetAllocationUserData() for this allocation. */ - void* pUserData; + void* VMA_NULLABLE pUserData; } VmaAllocationInfo; /** \brief General purpose memory allocation. +@param allocator +@param pVkMemoryRequirements +@param pCreateInfo @param[out] pAllocation Handle to allocated memory. @param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). -You should free the memory using vmaFreeMemory(). +You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages(). It is recommended to use vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(), vmaCreateBuffer(), vmaCreateImage() instead whenever possible. */ -VkResult vmaAllocateMemory( - VmaAllocator allocator, - const VkMemoryRequirements* pVkMemoryRequirements, - const VmaAllocationCreateInfo* pCreateInfo, - VmaAllocation* pAllocation, - VmaAllocationInfo* pAllocationInfo); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory( + VmaAllocator VMA_NOT_NULL allocator, + const VkMemoryRequirements* VMA_NOT_NULL pVkMemoryRequirements, + const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); + +/** \brief General purpose memory allocation for multiple allocation objects at once. + +@param allocator Allocator object. +@param pVkMemoryRequirements Memory requirements for each allocation. +@param pCreateInfo Creation parameters for each alloction. +@param allocationCount Number of allocations to make. +@param[out] pAllocations Pointer to array that will be filled with handles to created allocations. +@param[out] pAllocationInfo Optional. Pointer to array that will be filled with parameters of created allocations. + +You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages(). + +Word "pages" is just a suggestion to use this function to allocate pieces of memory needed for sparse binding. +It is just a general purpose allocation function able to make multiple allocations at once. +It may be internally optimized to be more efficient than calling vmaAllocateMemory() `allocationCount` times. + +All allocations are made using same parameters. All of them are created out of the same memory pool and type. +If any allocation fails, all allocations already made within this function call are also freed, so that when +returned result is not `VK_SUCCESS`, `pAllocation` array is always entirely filled with `VK_NULL_HANDLE`. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages( + VmaAllocator VMA_NOT_NULL allocator, + const VkMemoryRequirements* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pVkMemoryRequirements, + const VmaAllocationCreateInfo* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pCreateInfo, + size_t allocationCount, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations, + VmaAllocationInfo* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationInfo); /** +@param allocator +@param buffer +@param pCreateInfo @param[out] pAllocation Handle to allocated memory. @param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). You should free the memory using vmaFreeMemory(). */ -VkResult vmaAllocateMemoryForBuffer( - VmaAllocator allocator, - VkBuffer buffer, - const VmaAllocationCreateInfo* pCreateInfo, - VmaAllocation* pAllocation, - VmaAllocationInfo* pAllocationInfo); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer( + VmaAllocator VMA_NOT_NULL allocator, + VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer, + const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); /// Function similar to vmaAllocateMemoryForBuffer(). -VkResult vmaAllocateMemoryForImage( - VmaAllocator allocator, - VkImage image, - const VmaAllocationCreateInfo* pCreateInfo, - VmaAllocation* pAllocation, - VmaAllocationInfo* pAllocationInfo); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage( + VmaAllocator VMA_NOT_NULL allocator, + VkImage VMA_NOT_NULL_NON_DISPATCHABLE image, + const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); -/// Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). -void vmaFreeMemory( - VmaAllocator allocator, - VmaAllocation allocation); +/** \brief Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). + +Passing `VK_NULL_HANDLE` as `allocation` is valid. Such function call is just skipped. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemory( + VmaAllocator VMA_NOT_NULL allocator, + const VmaAllocation VMA_NULLABLE allocation); + +/** \brief Frees memory and destroys multiple allocations. + +Word "pages" is just a suggestion to use this function to free pieces of memory used for sparse binding. +It is just a general purpose function to free memory and destroy allocations made using e.g. vmaAllocateMemory(), +vmaAllocateMemoryPages() and other functions. +It may be internally optimized to be more efficient than calling vmaFreeMemory() `allocationCount` times. + +Allocations in `pAllocations` array can come from any memory pools and types. +Passing `VK_NULL_HANDLE` as elements of `pAllocations` array is valid. Such entries are just skipped. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemoryPages( + VmaAllocator VMA_NOT_NULL allocator, + size_t allocationCount, + const VmaAllocation VMA_NULLABLE * VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations); /** \brief Returns current information about specified allocation and atomically marks it as used in current frame. -Current paramters of given allocation are returned in `pAllocationInfo`. +Current paramteres of given allocation are returned in `pAllocationInfo`. This function also atomically "touches" allocation - marks it as used in current frame, just like vmaTouchAllocation(). @@ -1828,15 +1513,15 @@ you can avoid calling it too often. (e.g. due to defragmentation or allocation becoming lost). - If you just want to check if allocation is not lost, vmaTouchAllocation() will work faster. */ -void vmaGetAllocationInfo( - VmaAllocator allocator, - VmaAllocation allocation, - VmaAllocationInfo* pAllocationInfo); +VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationInfo( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VmaAllocationInfo* VMA_NOT_NULL pAllocationInfo); /** \brief Returns `VK_TRUE` if allocation is not lost and atomically marks it as used in current frame. If the allocation has been created with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag, -this function returns `VK_TRUE` if it's not in lost state, so it can still be used. +this function returns `VK_TRUE` if it is not in lost state, so it can still be used. It then also atomically "touches" the allocation - marks it as used in current frame, so that you can be sure it won't become lost in current frame or next `frameInUseCount` frames. @@ -1847,9 +1532,9 @@ Lost allocation and the buffer/image still need to be destroyed. If the allocation has been created without #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag, this function always returns `VK_TRUE`. */ -VkBool32 vmaTouchAllocation( - VmaAllocator allocator, - VmaAllocation allocation); +VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaTouchAllocation( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation); /** \brief Sets pUserData in given allocation to new value. @@ -1864,10 +1549,10 @@ If the flag was not used, the value of pointer `pUserData` is just copied to allocation's `pUserData`. It is opaque, so you can use it however you want - e.g. as a pointer, ordinal number or some handle to you own data. */ -void vmaSetAllocationUserData( - VmaAllocator allocator, - VmaAllocation allocation, - void* pUserData); +VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + void* VMA_NULLABLE pUserData); /** \brief Creates new allocation that is in lost state from the beginning. @@ -1879,16 +1564,16 @@ Returned allocation is not tied to any specific memory pool or memory type and not bound to any image or buffer. It has size = 0. It cannot be turned into a real, non-empty allocation. */ -void vmaCreateLostAllocation( - VmaAllocator allocator, - VmaAllocation* pAllocation); +VMA_CALL_PRE void VMA_CALL_POST vmaCreateLostAllocation( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation); /** \brief Maps memory represented by given allocation and returns pointer to it. Maps memory represented by given allocation to make it accessible to CPU code. When succeeded, `*ppData` contains pointer to first byte of this memory. If the allocation is part of bigger `VkDeviceMemory` block, the pointer is -correctly offseted to the beginning of region assigned to this particular +correctly offsetted to the beginning of region assigned to this particular allocation. Mapping is internally reference-counted and synchronized, so despite raw Vulkan @@ -1916,24 +1601,256 @@ This function fails when used on allocation made in memory type that is not This function always fails when called for allocation that was created with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag. Such allocations cannot be mapped. + +This function doesn't automatically flush or invalidate caches. +If the allocation is made from a memory types that is not `HOST_COHERENT`, +you also need to use vmaInvalidateAllocation() / vmaFlushAllocation(), as required by Vulkan specification. */ -VkResult vmaMapMemory( - VmaAllocator allocator, - VmaAllocation allocation, - void** ppData); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaMapMemory( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + void* VMA_NULLABLE * VMA_NOT_NULL ppData); /** \brief Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). For details, see description of vmaMapMemory(). -*/ -void vmaUnmapMemory( - VmaAllocator allocator, - VmaAllocation allocation); -/** \brief Optional configuration parameters to be passed to function vmaDefragment(). */ +This function doesn't automatically flush or invalidate caches. +If the allocation is made from a memory types that is not `HOST_COHERENT`, +you also need to use vmaInvalidateAllocation() / vmaFlushAllocation(), as required by Vulkan specification. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaUnmapMemory( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation); + +/** \brief Flushes memory of given allocation. + +Calls `vkFlushMappedMemoryRanges()` for memory associated with given range of given allocation. +It needs to be called after writing to a mapped memory for memory types that are not `HOST_COHERENT`. +Unmap operation doesn't do that automatically. + +- `offset` must be relative to the beginning of allocation. +- `size` can be `VK_WHOLE_SIZE`. It means all memory from `offset` the the end of given allocation. +- `offset` and `size` don't have to be aligned. + They are internally rounded down/up to multiply of `nonCoherentAtomSize`. +- If `size` is 0, this call is ignored. +- If memory type that the `allocation` belongs to is not `HOST_VISIBLE` or it is `HOST_COHERENT`, + this call is ignored. + +Warning! `offset` and `size` are relative to the contents of given `allocation`. +If you mean whole allocation, you can pass 0 and `VK_WHOLE_SIZE`, respectively. +Do not pass allocation's offset as `offset`!!! + +This function returns the `VkResult` from `vkFlushMappedMemoryRanges` if it is +called, otherwise `VK_SUCCESS`. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocation( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkDeviceSize offset, + VkDeviceSize size); + +/** \brief Invalidates memory of given allocation. + +Calls `vkInvalidateMappedMemoryRanges()` for memory associated with given range of given allocation. +It needs to be called before reading from a mapped memory for memory types that are not `HOST_COHERENT`. +Map operation doesn't do that automatically. + +- `offset` must be relative to the beginning of allocation. +- `size` can be `VK_WHOLE_SIZE`. It means all memory from `offset` the the end of given allocation. +- `offset` and `size` don't have to be aligned. + They are internally rounded down/up to multiply of `nonCoherentAtomSize`. +- If `size` is 0, this call is ignored. +- If memory type that the `allocation` belongs to is not `HOST_VISIBLE` or it is `HOST_COHERENT`, + this call is ignored. + +Warning! `offset` and `size` are relative to the contents of given `allocation`. +If you mean whole allocation, you can pass 0 and `VK_WHOLE_SIZE`, respectively. +Do not pass allocation's offset as `offset`!!! + +This function returns the `VkResult` from `vkInvalidateMappedMemoryRanges` if +it is called, otherwise `VK_SUCCESS`. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocation( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkDeviceSize offset, + VkDeviceSize size); + +/** \brief Flushes memory of given set of allocations. + +Calls `vkFlushMappedMemoryRanges()` for memory associated with given ranges of given allocations. +For more information, see documentation of vmaFlushAllocation(). + +\param allocator +\param allocationCount +\param allocations +\param offsets If not null, it must point to an array of offsets of regions to flush, relative to the beginning of respective allocations. Null means all ofsets are zero. +\param sizes If not null, it must point to an array of sizes of regions to flush in respective allocations. Null means `VK_WHOLE_SIZE` for all allocations. + +This function returns the `VkResult` from `vkFlushMappedMemoryRanges` if it is +called, otherwise `VK_SUCCESS`. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocations( + VmaAllocator VMA_NOT_NULL allocator, + uint32_t allocationCount, + const VmaAllocation VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations, + const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) offsets, + const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) sizes); + +/** \brief Invalidates memory of given set of allocations. + +Calls `vkInvalidateMappedMemoryRanges()` for memory associated with given ranges of given allocations. +For more information, see documentation of vmaInvalidateAllocation(). + +\param allocator +\param allocationCount +\param allocations +\param offsets If not null, it must point to an array of offsets of regions to flush, relative to the beginning of respective allocations. Null means all ofsets are zero. +\param sizes If not null, it must point to an array of sizes of regions to flush in respective allocations. Null means `VK_WHOLE_SIZE` for all allocations. + +This function returns the `VkResult` from `vkInvalidateMappedMemoryRanges` if it is +called, otherwise `VK_SUCCESS`. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocations( + VmaAllocator VMA_NOT_NULL allocator, + uint32_t allocationCount, + const VmaAllocation VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations, + const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) offsets, + const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) sizes); + +/** \brief Checks magic number in margins around all allocations in given memory types (in both default and custom pools) in search for corruptions. + +@param allocator +@param memoryTypeBits Bit mask, where each bit set means that a memory type with that index should be checked. + +Corruption detection is enabled only when `VMA_DEBUG_DETECT_CORRUPTION` macro is defined to nonzero, +`VMA_DEBUG_MARGIN` is defined to nonzero and only for memory types that are +`HOST_VISIBLE` and `HOST_COHERENT`. For more information, see [Corruption detection](@ref debugging_memory_usage_corruption_detection). + +Possible return values: + +- `VK_ERROR_FEATURE_NOT_PRESENT` - corruption detection is not enabled for any of specified memory types. +- `VK_SUCCESS` - corruption detection has been performed and succeeded. +- `VK_ERROR_UNKNOWN` - corruption detection has been performed and found memory corruptions around one of the allocations. + `VMA_ASSERT` is also fired in that case. +- Other value: Error returned by Vulkan, e.g. memory mapping failure. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(VmaAllocator VMA_NOT_NULL allocator, uint32_t memoryTypeBits); + +/** \struct VmaDefragmentationContext +\brief Represents Opaque object that represents started defragmentation process. + +Fill structure #VmaDefragmentationInfo2 and call function vmaDefragmentationBegin() to create it. +Call function vmaDefragmentationEnd() to destroy it. +*/ +VK_DEFINE_HANDLE(VmaDefragmentationContext) + +/// Flags to be used in vmaDefragmentationBegin(). None at the moment. Reserved for future use. +typedef enum VmaDefragmentationFlagBits { + VMA_DEFRAGMENTATION_FLAG_INCREMENTAL = 0x1, + VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VmaDefragmentationFlagBits; +typedef VkFlags VmaDefragmentationFlags; + +/** \brief Parameters for defragmentation. + +To be used with function vmaDefragmentationBegin(). +*/ +typedef struct VmaDefragmentationInfo2 { + /** \brief Reserved for future use. Should be 0. + */ + VmaDefragmentationFlags flags; + /** \brief Number of allocations in `pAllocations` array. + */ + uint32_t allocationCount; + /** \brief Pointer to array of allocations that can be defragmented. + + The array should have `allocationCount` elements. + The array should not contain nulls. + Elements in the array should be unique - same allocation cannot occur twice. + It is safe to pass allocations that are in the lost state - they are ignored. + All allocations not present in this array are considered non-moveable during this defragmentation. + */ + const VmaAllocation VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations; + /** \brief Optional, output. Pointer to array that will be filled with information whether the allocation at certain index has been changed during defragmentation. + + The array should have `allocationCount` elements. + You can pass null if you are not interested in this information. + */ + VkBool32* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationsChanged; + /** \brief Numer of pools in `pPools` array. + */ + uint32_t poolCount; + /** \brief Either null or pointer to array of pools to be defragmented. + + All the allocations in the specified pools can be moved during defragmentation + and there is no way to check if they were really moved as in `pAllocationsChanged`, + so you must query all the allocations in all these pools for new `VkDeviceMemory` + and offset using vmaGetAllocationInfo() if you might need to recreate buffers + and images bound to them. + + The array should have `poolCount` elements. + The array should not contain nulls. + Elements in the array should be unique - same pool cannot occur twice. + + Using this array is equivalent to specifying all allocations from the pools in `pAllocations`. + It might be more efficient. + */ + const VmaPool VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(poolCount) pPools; + /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places using transfers on CPU side, like `memcpy()`, `memmove()`. + + `VK_WHOLE_SIZE` means no limit. + */ + VkDeviceSize maxCpuBytesToMove; + /** \brief Maximum number of allocations that can be moved to a different place using transfers on CPU side, like `memcpy()`, `memmove()`. + + `UINT32_MAX` means no limit. + */ + uint32_t maxCpuAllocationsToMove; + /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places using transfers on GPU side, posted to `commandBuffer`. + + `VK_WHOLE_SIZE` means no limit. + */ + VkDeviceSize maxGpuBytesToMove; + /** \brief Maximum number of allocations that can be moved to a different place using transfers on GPU side, posted to `commandBuffer`. + + `UINT32_MAX` means no limit. + */ + uint32_t maxGpuAllocationsToMove; + /** \brief Optional. Command buffer where GPU copy commands will be posted. + + If not null, it must be a valid command buffer handle that supports Transfer queue type. + It must be in the recording state and outside of a render pass instance. + You need to submit it and make sure it finished execution before calling vmaDefragmentationEnd(). + + Passing null means that only CPU defragmentation will be performed. + */ + VkCommandBuffer VMA_NULLABLE commandBuffer; +} VmaDefragmentationInfo2; + +typedef struct VmaDefragmentationPassMoveInfo { + VmaAllocation VMA_NOT_NULL allocation; + VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory; + VkDeviceSize offset; +} VmaDefragmentationPassMoveInfo; + +/** \brief Parameters for incremental defragmentation steps. + +To be used with function vmaBeginDefragmentationPass(). +*/ +typedef struct VmaDefragmentationPassInfo { + uint32_t moveCount; + VmaDefragmentationPassMoveInfo* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(moveCount) pMoves; +} VmaDefragmentationPassInfo; + +/** \brief Deprecated. Optional configuration parameters to be passed to function vmaDefragment(). + +\deprecated This is a part of the old interface. It is recommended to use structure #VmaDefragmentationInfo2 and function vmaDefragmentationBegin() instead. +*/ typedef struct VmaDefragmentationInfo { /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places. - + Default is `VK_WHOLE_SIZE`, which means no limit. */ VkDeviceSize maxBytesToMove; @@ -1956,95 +1873,108 @@ typedef struct VmaDefragmentationStats { uint32_t deviceMemoryBlocksFreed; } VmaDefragmentationStats; -/** \brief Compacts memory by moving allocations. +/** \brief Begins defragmentation process. +@param allocator Allocator object. +@param pInfo Structure filled with parameters of defragmentation. +@param[out] pStats Optional. Statistics of defragmentation. You can pass null if you are not interested in this information. +@param[out] pContext Context object that must be passed to vmaDefragmentationEnd() to finish defragmentation. +@return `VK_SUCCESS` and `*pContext == null` if defragmentation finished within this function call. `VK_NOT_READY` and `*pContext != null` if defragmentation has been started and you need to call vmaDefragmentationEnd() to finish it. Negative value in case of error. + +Use this function instead of old, deprecated vmaDefragment(). + +Warning! Between the call to vmaDefragmentationBegin() and vmaDefragmentationEnd(): + +- You should not use any of allocations passed as `pInfo->pAllocations` or + any allocations that belong to pools passed as `pInfo->pPools`, + including calling vmaGetAllocationInfo(), vmaTouchAllocation(), or access + their data. +- Some mutexes protecting internal data structures may be locked, so trying to + make or free any allocations, bind buffers or images, map memory, or launch + another simultaneous defragmentation in between may cause stall (when done on + another thread) or deadlock (when done on the same thread), unless you are + 100% sure that defragmented allocations are in different pools. +- Information returned via `pStats` and `pInfo->pAllocationsChanged` are undefined. + They become valid after call to vmaDefragmentationEnd(). +- If `pInfo->commandBuffer` is not null, you must submit that command buffer + and make sure it finished execution before calling vmaDefragmentationEnd(). + +For more information and important limitations regarding defragmentation, see documentation chapter: +[Defragmentation](@ref defragmentation). +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationBegin( + VmaAllocator VMA_NOT_NULL allocator, + const VmaDefragmentationInfo2* VMA_NOT_NULL pInfo, + VmaDefragmentationStats* VMA_NULLABLE pStats, + VmaDefragmentationContext VMA_NULLABLE * VMA_NOT_NULL pContext); + +/** \brief Ends defragmentation process. + +Use this function to finish defragmentation started by vmaDefragmentationBegin(). +It is safe to pass `context == null`. The function then does nothing. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationEnd( + VmaAllocator VMA_NOT_NULL allocator, + VmaDefragmentationContext VMA_NULLABLE context); + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass( + VmaAllocator VMA_NOT_NULL allocator, + VmaDefragmentationContext VMA_NULLABLE context, + VmaDefragmentationPassInfo* VMA_NOT_NULL pInfo +); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass( + VmaAllocator VMA_NOT_NULL allocator, + VmaDefragmentationContext VMA_NULLABLE context +); + +/** \brief Deprecated. Compacts memory by moving allocations. + +@param allocator @param pAllocations Array of allocations that can be moved during this compation. @param allocationCount Number of elements in pAllocations and pAllocationsChanged arrays. @param[out] pAllocationsChanged Array of boolean values that will indicate whether matching allocation in pAllocations array has been moved. This parameter is optional. Pass null if you don't need this information. @param pDefragmentationInfo Configuration parameters. Optional - pass null to use default values. @param[out] pDefragmentationStats Statistics returned by the function. Optional - pass null if you don't need this information. -@return VK_SUCCESS if completed, VK_INCOMPLETE if succeeded but didn't make all possible optimizations because limits specified in pDefragmentationInfo have been reached, negative error code in case of error. +@return `VK_SUCCESS` if completed, negative error code in case of error. + +\deprecated This is a part of the old interface. It is recommended to use structure #VmaDefragmentationInfo2 and function vmaDefragmentationBegin() instead. This function works by moving allocations to different places (different `VkDeviceMemory` objects and/or different offsets) in order to optimize memory -usage. Only allocations that are in pAllocations array can be moved. All other +usage. Only allocations that are in `pAllocations` array can be moved. All other allocations are considered nonmovable in this call. Basic rules: - Only allocations made in memory types that have - `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag can be compacted. You may pass other - allocations but it makes no sense - these will never be moved. -- You may pass allocations made with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT but - it makes no sense - they will never be moved. + `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` and `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` + flags can be compacted. You may pass other allocations but it makes no sense - + these will never be moved. +- Custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT or + #VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT flag are not defragmented. Allocations + passed to this function that come from such pools are ignored. +- Allocations created with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT or + created as dedicated allocations for any other reason are also ignored. - Both allocations made with or without #VMA_ALLOCATION_CREATE_MAPPED_BIT flag can be compacted. If not persistently mapped, memory will be mapped temporarily inside this function if needed. -- You must not pass same #VmaAllocation object multiple times in pAllocations array. +- You must not pass same #VmaAllocation object multiple times in `pAllocations` array. The function also frees empty `VkDeviceMemory` blocks. -After allocation has been moved, its VmaAllocationInfo::deviceMemory and/or -VmaAllocationInfo::offset changes. You must query them again using -vmaGetAllocationInfo() if you need them. - -If an allocation has been moved, data in memory is copied to new place -automatically, but if it was bound to a buffer or an image, you must destroy -that object yourself, create new one and bind it to the new memory pointed by -the allocation. You must use `vkDestroyBuffer()`, `vkDestroyImage()`, -`vkCreateBuffer()`, `vkCreateImage()` for that purpose and NOT vmaDestroyBuffer(), -vmaDestroyImage(), vmaCreateBuffer(), vmaCreateImage()! Example: - -\code -VkDevice device = ...; -VmaAllocator allocator = ...; -std::vector buffers = ...; -std::vector allocations = ...; - -std::vector allocationsChanged(allocations.size()); -vmaDefragment(allocator, allocations.data(), allocations.size(), allocationsChanged.data(), nullptr, nullptr); - -for(size_t i = 0; i < allocations.size(); ++i) -{ - if(allocationsChanged[i]) - { - VmaAllocationInfo allocInfo; - vmaGetAllocationInfo(allocator, allocations[i], &allocInfo); - - vkDestroyBuffer(device, buffers[i], nullptr); - - VkBufferCreateInfo bufferInfo = ...; - vkCreateBuffer(device, &bufferInfo, nullptr, &buffers[i]); - - // You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning. - - vkBindBufferMemory(device, buffers[i], allocInfo.deviceMemory, allocInfo.offset); - } -} -\endcode - -Note: Please don't expect memory to be fully compacted after this call. -Algorithms inside are based on some heuristics that try to maximize number of Vulkan -memory blocks to make totally empty to release them, as well as to maximimze continuous -empty space inside remaining blocks, while minimizing the number and size of data that -needs to be moved. Some fragmentation still remains after this call. This is normal. - -Warning: This function is not 100% correct according to Vulkan specification. Use it -at your own risk. That's because Vulkan doesn't guarantee that memory -requirements (size and alignment) for a new buffer or image are consistent. They -may be different even for subsequent calls with the same parameters. It really -does happen on some platforms, especially with images. - Warning: This function may be time-consuming, so you shouldn't call it too often -(like every frame or after every resource creation/destruction). +(like after every resource creation/destruction). You can call it on special occasions (like when reloading a game level or -when you just destroyed a lot of objects). +when you just destroyed a lot of objects). Calling it every frame may be OK, but +you should measure that on your platform. + +For more information, see [Defragmentation](@ref defragmentation) chapter. */ -VkResult vmaDefragment( - VmaAllocator allocator, - VmaAllocation* pAllocations, +VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragment( + VmaAllocator VMA_NOT_NULL allocator, + const VmaAllocation VMA_NOT_NULL * VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations, size_t allocationCount, - VkBool32* pAllocationsChanged, - const VmaDefragmentationInfo *pDefragmentationInfo, - VmaDefragmentationStats* pDefragmentationStats); + VkBool32* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationsChanged, + const VmaDefragmentationInfo* VMA_NULLABLE pDefragmentationInfo, + VmaDefragmentationStats* VMA_NULLABLE pDefragmentationStats); /** \brief Binds buffer to allocation. @@ -2058,10 +1988,30 @@ allocations, calls to `vkBind*Memory()` or `vkMapMemory()` won't happen from mul It is recommended to use function vmaCreateBuffer() instead of this one. */ -VkResult vmaBindBufferMemory( - VmaAllocator allocator, - VmaAllocation allocation, - VkBuffer buffer); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer); + +/** \brief Binds buffer to allocation with additional parameters. + +@param allocator +@param allocation +@param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0. +@param buffer +@param pNext A chain of structures to be attached to `VkBindBufferMemoryInfoKHR` structure used internally. Normally it should be null. + +This function is similar to vmaBindBufferMemory(), but it provides additional parameters. + +If `pNext` is not null, #VmaAllocator object must have been created with #VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT flag +or with VmaAllocatorCreateInfo::vulkanApiVersion `>= VK_API_VERSION_1_1`. Otherwise the call fails. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory2( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkDeviceSize allocationLocalOffset, + VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer, + const void* VMA_NULLABLE pNext); /** \brief Binds image to allocation. @@ -2075,12 +2025,35 @@ allocations, calls to `vkBind*Memory()` or `vkMapMemory()` won't happen from mul It is recommended to use function vmaCreateImage() instead of this one. */ -VkResult vmaBindImageMemory( - VmaAllocator allocator, - VmaAllocation allocation, - VkImage image); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkImage VMA_NOT_NULL_NON_DISPATCHABLE image); + +/** \brief Binds image to allocation with additional parameters. + +@param allocator +@param allocation +@param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0. +@param image +@param pNext A chain of structures to be attached to `VkBindImageMemoryInfoKHR` structure used internally. Normally it should be null. + +This function is similar to vmaBindImageMemory(), but it provides additional parameters. + +If `pNext` is not null, #VmaAllocator object must have been created with #VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT flag +or with VmaAllocatorCreateInfo::vulkanApiVersion `>= VK_API_VERSION_1_1`. Otherwise the call fails. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory2( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkDeviceSize allocationLocalOffset, + VkImage VMA_NOT_NULL_NON_DISPATCHABLE image, + const void* VMA_NULLABLE pNext); /** +@param allocator +@param pBufferCreateInfo +@param pAllocationCreateInfo @param[out] pBuffer Buffer that was created. @param[out] pAllocation Allocation that was created. @param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). @@ -2098,21 +2071,40 @@ If the function succeeded, you must destroy both buffer and allocation when you no longer need them using either convenience function vmaDestroyBuffer() or separately, using `vkDestroyBuffer()` and vmaFreeMemory(). -If VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag was used, +If #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag was used, VK_KHR_dedicated_allocation extension is used internally to query driver whether it requires or prefers the new buffer to have dedicated allocation. If yes, and if dedicated allocation is possible (VmaAllocationCreateInfo::pool is null -and VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT is not used), it creates dedicated +and #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT is not used), it creates dedicated allocation for this buffer, just like when using -VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. +#VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. + +\note This function creates a new `VkBuffer`. Sub-allocation of parts of one large buffer, +although recommended as a good practice, is out of scope of this library and could be implemented +by the user as a higher-level logic on top of VMA. */ -VkResult vmaCreateBuffer( - VmaAllocator allocator, - const VkBufferCreateInfo* pBufferCreateInfo, - const VmaAllocationCreateInfo* pAllocationCreateInfo, - VkBuffer* pBuffer, - VmaAllocation* pAllocation, - VmaAllocationInfo* pAllocationInfo); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer( + VmaAllocator VMA_NOT_NULL allocator, + const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo, + const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, + VkBuffer VMA_NULLABLE_NON_DISPATCHABLE * VMA_NOT_NULL pBuffer, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); + +/** \brief Creates a buffer with additional minimum alignment. + +Similar to vmaCreateBuffer() but provides additional parameter `minAlignment` which allows to specify custom, +minimum alignment to be used when placing the buffer inside a larger memory block, which may be needed e.g. +for interop with OpenGL. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment( + VmaAllocator VMA_NOT_NULL allocator, + const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo, + const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, + VkDeviceSize minAlignment, + VkBuffer VMA_NULLABLE_NON_DISPATCHABLE * VMA_NOT_NULL pBuffer, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); /** \brief Destroys Vulkan buffer and frees allocated memory. @@ -2125,19 +2117,19 @@ vmaFreeMemory(allocator, allocation); It it safe to pass null as buffer and/or allocation. */ -void vmaDestroyBuffer( - VmaAllocator allocator, - VkBuffer buffer, - VmaAllocation allocation); +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer( + VmaAllocator VMA_NOT_NULL allocator, + VkBuffer VMA_NULLABLE_NON_DISPATCHABLE buffer, + VmaAllocation VMA_NULLABLE allocation); /// Function similar to vmaCreateBuffer(). -VkResult vmaCreateImage( - VmaAllocator allocator, - const VkImageCreateInfo* pImageCreateInfo, - const VmaAllocationCreateInfo* pAllocationCreateInfo, - VkImage* pImage, - VmaAllocation* pAllocation, - VmaAllocationInfo* pAllocationInfo); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage( + VmaAllocator VMA_NOT_NULL allocator, + const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo, + const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, + VkImage VMA_NULLABLE_NON_DISPATCHABLE * VMA_NOT_NULL pImage, + VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); /** \brief Destroys Vulkan image and frees allocated memory. @@ -2150,10 +2142,10 @@ vmaFreeMemory(allocator, allocation); It it safe to pass null as image and/or allocation. */ -void vmaDestroyImage( - VmaAllocator allocator, - VkImage image, - VmaAllocation allocation); +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage( + VmaAllocator VMA_NOT_NULL allocator, + VkImage VMA_NULLABLE_NON_DISPATCHABLE image, + VmaAllocation VMA_NULLABLE allocation); #ifdef __cplusplus } @@ -2162,7 +2154,7 @@ void vmaDestroyImage( #endif // AMD_VULKAN_MEMORY_ALLOCATOR_H // For Visual Studio IntelliSense. -#ifdef __INTELLISENSE__ +#if defined(__cplusplus) && defined(__INTELLISENSE__) #define VMA_IMPLEMENTATION #endif @@ -2172,6 +2164,17 @@ void vmaDestroyImage( #include #include #include +#include + +#if VMA_RECORDING_ENABLED + #include + #if defined(_WIN32) + #include + #else + #include + #include + #endif +#endif /******************************************************************************* CONFIGURATION SECTION @@ -2185,12 +2188,23 @@ Define this macro to 1 to make the library fetch pointers to Vulkan functions internally, like: vulkanFunctions.vkAllocateMemory = &vkAllocateMemory; - -Define to 0 if you are going to provide you own pointers to Vulkan functions via -VmaAllocatorCreateInfo::pVulkanFunctions. */ #if !defined(VMA_STATIC_VULKAN_FUNCTIONS) && !defined(VK_NO_PROTOTYPES) -#define VMA_STATIC_VULKAN_FUNCTIONS 1 + #define VMA_STATIC_VULKAN_FUNCTIONS 1 +#endif + +/* +Define this macro to 1 to make the library fetch pointers to Vulkan functions +internally, like: + + vulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkGetDeviceProcAddr(m_hDevice, vkAllocateMemory); +*/ +#if !defined(VMA_DYNAMIC_VULKAN_FUNCTIONS) + #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 + #if defined(VK_NO_PROTOTYPES) + extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; + extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; + #endif #endif // Define this macro to 1 to make the library use STL containers instead of its own implementation. @@ -2208,6 +2222,24 @@ the containers. #define VMA_USE_STL_LIST 1 #endif +#ifndef VMA_USE_STL_SHARED_MUTEX + // Compiler conforms to C++17. + #if __cplusplus >= 201703L + #define VMA_USE_STL_SHARED_MUTEX 1 + // Visual studio defines __cplusplus properly only when passed additional parameter: /Zc:__cplusplus + // Otherwise it is always 199711L, despite shared_mutex works since Visual Studio 2015 Update 2. + // See: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/ + #elif defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918 && __cplusplus == 199711L && _MSVC_LANG >= 201703L + #define VMA_USE_STL_SHARED_MUTEX 1 + #else + #define VMA_USE_STL_SHARED_MUTEX 0 + #endif +#endif + +/* +THESE INCLUDES ARE NOT ENABLED BY DEFAULT. +Library has its own container implementation. +*/ #if VMA_USE_STL_VECTOR #include #endif @@ -2226,22 +2258,16 @@ remove them if not needed. */ #include // for assert #include // for min, max -#include // for std::mutex -#include // for std::atomic - -#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) - #include // for aligned_alloc() -#endif +#include #ifndef VMA_NULL // Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0. #define VMA_NULL nullptr #endif -#ifndef __MINGW32__ -#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) || (defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)) +#if defined(__ANDROID_API__) && (__ANDROID_API__ < 16) #include -void *aligned_alloc(size_t alignment, size_t size) +static void* vma_aligned_alloc(size_t alignment, size_t size) { // alignment must be >= sizeof(void*) if(alignment < sizeof(void*)) @@ -2249,30 +2275,88 @@ void *aligned_alloc(size_t alignment, size_t size) alignment = sizeof(void*); } + return memalign(alignment, size); +} +#elif defined(__APPLE__) || defined(__ANDROID__) || (defined(__linux__) && defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)) +#include + +#if defined(__APPLE__) +#include +#endif + +static void* vma_aligned_alloc(size_t alignment, size_t size) +{ + // Unfortunately, aligned_alloc causes VMA to crash due to it returning null pointers. (At least under 11.4) + // Therefore, for now disable this specific exception until a proper solution is found. + //#if defined(__APPLE__) && (defined(MAC_OS_X_VERSION_10_16) || defined(__IPHONE_14_0)) + //#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_16 || __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + // // For C++14, usr/include/malloc/_malloc.h declares aligned_alloc()) only + // // with the MacOSX11.0 SDK in Xcode 12 (which is what adds + // // MAC_OS_X_VERSION_10_16), even though the function is marked + // // availabe for 10.15. That is why the preprocessor checks for 10.16 but + // // the __builtin_available checks for 10.15. + // // People who use C++17 could call aligned_alloc with the 10.15 SDK already. + // if (__builtin_available(macOS 10.15, iOS 13, *)) + // return aligned_alloc(alignment, size); + //#endif + //#endif + + // alignment must be >= sizeof(void*) + if(alignment < sizeof(void*)) + { + alignment = sizeof(void*); + } + void *pointer; if(posix_memalign(&pointer, alignment, size) == 0) return pointer; return VMA_NULL; } +#elif defined(_WIN32) +static void* vma_aligned_alloc(size_t alignment, size_t size) +{ + return _aligned_malloc(size, alignment); +} +#else +static void* vma_aligned_alloc(size_t alignment, size_t size) +{ + return aligned_alloc(alignment, size); +} #endif + +#if defined(_WIN32) +static void vma_aligned_free(void* ptr) +{ + _aligned_free(ptr); +} +#else +static void vma_aligned_free(void* VMA_NULLABLE ptr) +{ + free(ptr); +} #endif +// If your compiler is not compatible with C++11 and definition of +// aligned_alloc() function is missing, uncommeting following line may help: + +//#include + // Normal assert to check for programmer's errors, especially in Debug configuration. #ifndef VMA_ASSERT - #ifdef _DEBUG - #define VMA_ASSERT(expr) assert(expr) - #else + #ifdef NDEBUG #define VMA_ASSERT(expr) + #else + #define VMA_ASSERT(expr) assert(expr) #endif #endif // Assert that will be called very often, like inside data structures e.g. operator[]. // Making it non-empty can make program slow. #ifndef VMA_HEAVY_ASSERT - #ifdef _DEBUG - #define VMA_HEAVY_ASSERT(expr) //VMA_ASSERT(expr) - #else + #ifdef NDEBUG #define VMA_HEAVY_ASSERT(expr) + #else + #define VMA_HEAVY_ASSERT(expr) //VMA_ASSERT(expr) #endif #endif @@ -2281,27 +2365,24 @@ void *aligned_alloc(size_t alignment, size_t size) #endif #ifndef VMA_SYSTEM_ALIGNED_MALLOC - #if defined(_WIN32) - #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (_aligned_malloc((size), (alignment))) - #else - #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (aligned_alloc((alignment), (size) )) - #endif + #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) vma_aligned_alloc((alignment), (size)) #endif -#ifndef VMA_SYSTEM_FREE - #if defined(_WIN32) - #define VMA_SYSTEM_FREE(ptr) _aligned_free(ptr) +#ifndef VMA_SYSTEM_ALIGNED_FREE + // VMA_SYSTEM_FREE is the old name, but might have been defined by the user + #if defined(VMA_SYSTEM_FREE) + #define VMA_SYSTEM_ALIGNED_FREE(ptr) VMA_SYSTEM_FREE(ptr) #else - #define VMA_SYSTEM_FREE(ptr) free(ptr) - #endif + #define VMA_SYSTEM_ALIGNED_FREE(ptr) vma_aligned_free(ptr) + #endif #endif #ifndef VMA_MIN - #define VMA_MIN(v1, v2) (std::min((v1), (v2))) + #define VMA_MIN(v1, v2) ((std::min)((v1), (v2))) #endif #ifndef VMA_MAX - #define VMA_MAX(v1, v2) (std::max((v1), (v2))) + #define VMA_MAX(v1, v2) ((std::max)((v1), (v2))) #endif #ifndef VMA_SWAP @@ -2324,100 +2405,166 @@ void *aligned_alloc(size_t alignment, size_t size) // Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString. #if VMA_STATS_STRING_ENABLED - static inline void VmaUint32ToStr(char* outStr, size_t strLen, uint32_t num) - { - snprintf(outStr, strLen, "%u", static_cast(num)); - } - static inline void VmaUint64ToStr(char* outStr, size_t strLen, uint64_t num) - { - snprintf(outStr, strLen, "%llu", static_cast(num)); - } - static inline void VmaPtrToStr(char* outStr, size_t strLen, const void* ptr) - { - snprintf(outStr, strLen, "%p", ptr); - } + static inline void VmaUint32ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint32_t num) + { + snprintf(outStr, strLen, "%u", static_cast(num)); + } + static inline void VmaUint64ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint64_t num) + { + snprintf(outStr, strLen, "%llu", static_cast(num)); + } + static inline void VmaPtrToStr(char* VMA_NOT_NULL outStr, size_t strLen, const void* ptr) + { + snprintf(outStr, strLen, "%p", ptr); + } #endif #ifndef VMA_MUTEX - class VmaMutex - { - public: - VmaMutex() { } - ~VmaMutex() { } - void Lock() { m_Mutex.lock(); } - void Unlock() { m_Mutex.unlock(); } - private: - std::mutex m_Mutex; - }; - #define VMA_MUTEX VmaMutex + class VmaMutex + { + public: + void Lock() { m_Mutex.lock(); } + void Unlock() { m_Mutex.unlock(); } + bool TryLock() { return m_Mutex.try_lock(); } + private: + std::mutex m_Mutex; + }; + #define VMA_MUTEX VmaMutex #endif +// Read-write mutex, where "read" is shared access, "write" is exclusive access. +#ifndef VMA_RW_MUTEX + #if VMA_USE_STL_SHARED_MUTEX + // Use std::shared_mutex from C++17. + #include + class VmaRWMutex + { + public: + void LockRead() { m_Mutex.lock_shared(); } + void UnlockRead() { m_Mutex.unlock_shared(); } + bool TryLockRead() { return m_Mutex.try_lock_shared(); } + void LockWrite() { m_Mutex.lock(); } + void UnlockWrite() { m_Mutex.unlock(); } + bool TryLockWrite() { return m_Mutex.try_lock(); } + private: + std::shared_mutex m_Mutex; + }; + #define VMA_RW_MUTEX VmaRWMutex + #elif defined(_WIN32) && defined(WINVER) && WINVER >= 0x0600 + // Use SRWLOCK from WinAPI. + // Minimum supported client = Windows Vista, server = Windows Server 2008. + class VmaRWMutex + { + public: + VmaRWMutex() { InitializeSRWLock(&m_Lock); } + void LockRead() { AcquireSRWLockShared(&m_Lock); } + void UnlockRead() { ReleaseSRWLockShared(&m_Lock); } + bool TryLockRead() { return TryAcquireSRWLockShared(&m_Lock) != FALSE; } + void LockWrite() { AcquireSRWLockExclusive(&m_Lock); } + void UnlockWrite() { ReleaseSRWLockExclusive(&m_Lock); } + bool TryLockWrite() { return TryAcquireSRWLockExclusive(&m_Lock) != FALSE; } + private: + SRWLOCK m_Lock; + }; + #define VMA_RW_MUTEX VmaRWMutex + #else + // Less efficient fallback: Use normal mutex. + class VmaRWMutex + { + public: + void LockRead() { m_Mutex.Lock(); } + void UnlockRead() { m_Mutex.Unlock(); } + bool TryLockRead() { return m_Mutex.TryLock(); } + void LockWrite() { m_Mutex.Lock(); } + void UnlockWrite() { m_Mutex.Unlock(); } + bool TryLockWrite() { return m_Mutex.TryLock(); } + private: + VMA_MUTEX m_Mutex; + }; + #define VMA_RW_MUTEX VmaRWMutex + #endif // #if VMA_USE_STL_SHARED_MUTEX +#endif // #ifndef VMA_RW_MUTEX + /* -If providing your own implementation, you need to implement a subset of std::atomic: - -- Constructor(uint32_t desired) -- uint32_t load() const -- void store(uint32_t desired) -- bool compare_exchange_weak(uint32_t& expected, uint32_t desired) +If providing your own implementation, you need to implement a subset of std::atomic. */ #ifndef VMA_ATOMIC_UINT32 - #define VMA_ATOMIC_UINT32 std::atomic + #include + #define VMA_ATOMIC_UINT32 std::atomic #endif -#ifndef VMA_BEST_FIT - /** - Main parameter for function assessing how good is a free suballocation for a new - allocation request. - - - Set to 1 to use Best-Fit algorithm - prefer smaller blocks, as close to the - size of requested allocations as possible. - - Set to 0 to use Worst-Fit algorithm - prefer larger blocks, as large as - possible. - - Experiments in special testing environment showed that Best-Fit algorithm is - better. - */ - #define VMA_BEST_FIT (1) +#ifndef VMA_ATOMIC_UINT64 + #include + #define VMA_ATOMIC_UINT64 std::atomic #endif #ifndef VMA_DEBUG_ALWAYS_DEDICATED_MEMORY - /** - Every allocation will have its own memory block. - Define to 1 for debugging purposes only. - */ - #define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0) + /** + Every allocation will have its own memory block. + Define to 1 for debugging purposes only. + */ + #define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0) #endif -#ifndef VMA_DEBUG_ALIGNMENT - /** - Minimum alignment of all suballocations, in bytes. - Set to more than 1 for debugging purposes only. Must be power of two. - */ - #define VMA_DEBUG_ALIGNMENT (1) +#ifndef VMA_MIN_ALIGNMENT + /** + Minimum alignment of all allocations, in bytes. + Set to more than 1 for debugging purposes. Must be power of two. + */ + #ifdef VMA_DEBUG_ALIGNMENT // Old name + #define VMA_MIN_ALIGNMENT VMA_DEBUG_ALIGNMENT + #else + #define VMA_MIN_ALIGNMENT (1) + #endif #endif #ifndef VMA_DEBUG_MARGIN - /** - Minimum margin between suballocations, in bytes. - Set nonzero for debugging purposes only. - */ - #define VMA_DEBUG_MARGIN (0) + /** + Minimum margin before and after every allocation, in bytes. + Set nonzero for debugging purposes only. + */ + #define VMA_DEBUG_MARGIN (0) +#endif + +#ifndef VMA_DEBUG_INITIALIZE_ALLOCATIONS + /** + Define this macro to 1 to automatically fill new allocations and destroyed + allocations with some bit pattern. + */ + #define VMA_DEBUG_INITIALIZE_ALLOCATIONS (0) +#endif + +#ifndef VMA_DEBUG_DETECT_CORRUPTION + /** + Define this macro to 1 together with non-zero value of VMA_DEBUG_MARGIN to + enable writing magic value to the margin before and after every allocation and + validating it, so that memory corruptions (out-of-bounds writes) are detected. + */ + #define VMA_DEBUG_DETECT_CORRUPTION (0) #endif #ifndef VMA_DEBUG_GLOBAL_MUTEX - /** - Set this to 1 for debugging purposes only, to enable single mutex protecting all - entry calls to the library. Can be useful for debugging multithreading issues. - */ - #define VMA_DEBUG_GLOBAL_MUTEX (0) + /** + Set this to 1 for debugging purposes only, to enable single mutex protecting all + entry calls to the library. Can be useful for debugging multithreading issues. + */ + #define VMA_DEBUG_GLOBAL_MUTEX (0) #endif #ifndef VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY - /** - Minimum value for VkPhysicalDeviceLimits::bufferImageGranularity. - Set to more than 1 for debugging purposes only. Must be power of two. - */ - #define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1) + /** + Minimum value for VkPhysicalDeviceLimits::bufferImageGranularity. + Set to more than 1 for debugging purposes only. Must be power of two. + */ + #define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1) +#endif + +#ifndef VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT + /* + Set this to 1 to make VMA never exceed VkPhysicalDeviceLimits::maxMemoryAllocationCount + and return error instead of leaving up to Vulkan implementation what to do in such cases. + */ + #define VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT (0) #endif #ifndef VMA_SMALL_HEAP_MAX_SIZE @@ -2430,41 +2577,155 @@ If providing your own implementation, you need to implement a subset of std::ato #define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256ull * 1024 * 1024) #endif +#ifndef VMA_CLASS_NO_COPY + #define VMA_CLASS_NO_COPY(className) \ + private: \ + className(const className&) = delete; \ + className& operator=(const className&) = delete; +#endif + static const uint32_t VMA_FRAME_INDEX_LOST = UINT32_MAX; +// Decimal 2139416166, float NaN, little-endian binary 66 E6 84 7F. +static const uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666; + +static const uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED = 0xDC; +static const uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF; + /******************************************************************************* END OF CONFIGURATION */ +// # Copy of some Vulkan definitions so we don't need to check their existence just to handle few constants. + +static const uint32_t VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY = 0x00000040; +static const uint32_t VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY = 0x00000080; +static const uint32_t VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY = 0x00020000; + +static const uint32_t VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET = 0x10000000u; + static VkAllocationCallbacks VmaEmptyAllocationCallbacks = { VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL }; // Returns number of bits set to 1 in (v). static inline uint32_t VmaCountBitsSet(uint32_t v) { - uint32_t c = v - ((v >> 1) & 0x55555555); - c = ((c >> 2) & 0x33333333) + (c & 0x33333333); - c = ((c >> 4) + c) & 0x0F0F0F0F; - c = ((c >> 8) + c) & 0x00FF00FF; - c = ((c >> 16) + c) & 0x0000FFFF; - return c; + uint32_t c = v - ((v >> 1) & 0x55555555); + c = ((c >> 2) & 0x33333333) + (c & 0x33333333); + c = ((c >> 4) + c) & 0x0F0F0F0F; + c = ((c >> 8) + c) & 0x00FF00FF; + c = ((c >> 16) + c) & 0x0000FFFF; + return c; +} + +/* +Returns true if given number is a power of two. +T must be unsigned integer number or signed integer but always nonnegative. +For 0 returns true. +*/ +template +inline bool VmaIsPow2(T x) +{ + return (x & (x-1)) == 0; } // Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16. // Use types like uint32_t, uint64_t as T. template -static inline T VmaAlignUp(T val, T align) +static inline T VmaAlignUp(T val, T alignment) { - return (val + align - 1) / align * align; + VMA_HEAVY_ASSERT(VmaIsPow2(alignment)); + return (val + alignment - 1) & ~(alignment - 1); +} +// Aligns given value down to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 8. +// Use types like uint32_t, uint64_t as T. +template +static inline T VmaAlignDown(T val, T alignment) +{ + VMA_HEAVY_ASSERT(VmaIsPow2(alignment)); + return val & ~(alignment - 1); } // Division with mathematical rounding to nearest number. template -inline T VmaRoundDiv(T x, T y) +static inline T VmaRoundDiv(T x, T y) { - return (x + (y / (T)2)) / y; + return (x + (y / (T)2)) / y; } +// Returns smallest power of 2 greater or equal to v. +static inline uint32_t VmaNextPow2(uint32_t v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +} +static inline uint64_t VmaNextPow2(uint64_t v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + v++; + return v; +} + +// Returns largest power of 2 less or equal to v. +static inline uint32_t VmaPrevPow2(uint32_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v = v ^ (v >> 1); + return v; +} +static inline uint64_t VmaPrevPow2(uint64_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + v = v ^ (v >> 1); + return v; +} + +static inline bool VmaStrIsEmpty(const char* pStr) +{ + return pStr == VMA_NULL || *pStr == '\0'; +} + +#if VMA_STATS_STRING_ENABLED + +static const char* VmaAlgorithmToStr(uint32_t algorithm) +{ + switch(algorithm) + { + case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT: + return "Linear"; + case VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT: + return "Buddy"; + case 0: + return "Default"; + default: + VMA_ASSERT(0); + return ""; + } +} + +#endif // #if VMA_STATS_STRING_ENABLED + #ifndef VMA_SORT template @@ -2551,7 +2812,7 @@ static inline bool VmaIsBufferImageGranularityConflict( { VMA_SWAP(suballocType1, suballocType2); } - + switch(suballocType1) { case VMA_SUBALLOCATION_TYPE_FREE: @@ -2578,31 +2839,88 @@ static inline bool VmaIsBufferImageGranularityConflict( } } +static void VmaWriteMagicValue(void* pData, VkDeviceSize offset) +{ +#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION + uint32_t* pDst = (uint32_t*)((char*)pData + offset); + const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t); + for(size_t i = 0; i < numberCount; ++i, ++pDst) + { + *pDst = VMA_CORRUPTION_DETECTION_MAGIC_VALUE; + } +#else + // no-op +#endif +} + +static bool VmaValidateMagicValue(const void* pData, VkDeviceSize offset) +{ +#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION + const uint32_t* pSrc = (const uint32_t*)((const char*)pData + offset); + const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t); + for(size_t i = 0; i < numberCount; ++i, ++pSrc) + { + if(*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE) + { + return false; + } + } +#endif + return true; +} + +/* +Fills structure with parameters of an example buffer to be used for transfers +during GPU memory defragmentation. +*/ +static void VmaFillGpuDefragmentationBufferCreateInfo(VkBufferCreateInfo& outBufCreateInfo) +{ + memset(&outBufCreateInfo, 0, sizeof(outBufCreateInfo)); + outBufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + outBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + outBufCreateInfo.size = (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE; // Example size. +} + // Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope). struct VmaMutexLock { + VMA_CLASS_NO_COPY(VmaMutexLock) public: - VmaMutexLock(VMA_MUTEX& mutex, bool useMutex) : + VmaMutexLock(VMA_MUTEX& mutex, bool useMutex = true) : m_pMutex(useMutex ? &mutex : VMA_NULL) - { - if(m_pMutex) - { - m_pMutex->Lock(); - } - } - + { if(m_pMutex) { m_pMutex->Lock(); } } ~VmaMutexLock() - { - if(m_pMutex) - { - m_pMutex->Unlock(); - } - } - + { if(m_pMutex) { m_pMutex->Unlock(); } } private: VMA_MUTEX* m_pMutex; }; +// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for reading. +struct VmaMutexLockRead +{ + VMA_CLASS_NO_COPY(VmaMutexLockRead) +public: + VmaMutexLockRead(VMA_RW_MUTEX& mutex, bool useMutex) : + m_pMutex(useMutex ? &mutex : VMA_NULL) + { if(m_pMutex) { m_pMutex->LockRead(); } } + ~VmaMutexLockRead() { if(m_pMutex) { m_pMutex->UnlockRead(); } } +private: + VMA_RW_MUTEX* m_pMutex; +}; + +// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for writing. +struct VmaMutexLockWrite +{ + VMA_CLASS_NO_COPY(VmaMutexLockWrite) +public: + VmaMutexLockWrite(VMA_RW_MUTEX& mutex, bool useMutex) : + m_pMutex(useMutex ? &mutex : VMA_NULL) + { if(m_pMutex) { m_pMutex->LockWrite(); } } + ~VmaMutexLockWrite() { if(m_pMutex) { m_pMutex->UnlockWrite(); } } +private: + VMA_RW_MUTEX* m_pMutex; +}; + #if VMA_DEBUG_GLOBAL_MUTEX static VMA_MUTEX gDebugGlobalMutex; #define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex, true); @@ -2622,23 +2940,69 @@ Cmp should return true if first argument is less than second argument. Returned value is the found element, if present in the collection or place where new element with value (key) should be inserted. */ -template -static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, CmpT cmp) +template +static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, const CmpLess& cmp) { - size_t down = 0, up = (end - beg); - while(down < up) - { - const size_t mid = (down + up) / 2; - if(cmp(*(beg+mid), key)) - { - down = mid + 1; - } - else - { - up = mid; - } - } - return beg + down; + size_t down = 0, up = (end - beg); + while(down < up) + { + const size_t mid = down + (up - down) / 2; // Overflow-safe midpoint calculation + if(cmp(*(beg+mid), key)) + { + down = mid + 1; + } + else + { + up = mid; + } + } + return beg + down; +} + +template +IterT VmaBinaryFindSorted(const IterT& beg, const IterT& end, const KeyT& value, const CmpLess& cmp) +{ + IterT it = VmaBinaryFindFirstNotLess( + beg, end, value, cmp); + if(it == end || + (!cmp(*it, value) && !cmp(value, *it))) + { + return it; + } + return end; +} + +/* +Returns true if all pointers in the array are not-null and unique. +Warning! O(n^2) complexity. Use only inside VMA_HEAVY_ASSERT. +T must be pointer type, e.g. VmaAllocation, VmaPool. +*/ +template +static bool VmaValidatePointerArray(uint32_t count, const T* arr) +{ + for(uint32_t i = 0; i < count; ++i) + { + const T iPtr = arr[i]; + if(iPtr == VMA_NULL) + { + return false; + } + for(uint32_t j = i + 1; j < count; ++j) + { + if(iPtr == arr[j]) + { + return false; + } + } + } + return true; +} + +template +static inline void VmaPnextChainPushFront(MainT* mainStruct, NewT* newStruct) +{ + newStruct->pNext = mainStruct->pNext; + mainStruct->pNext = newStruct; } //////////////////////////////////////////////////////////////////////////////// @@ -2646,10 +3010,11 @@ static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, Cm static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t size, size_t alignment) { + void* result = VMA_NULL; if((pAllocationCallbacks != VMA_NULL) && (pAllocationCallbacks->pfnAllocation != VMA_NULL)) { - return (*pAllocationCallbacks->pfnAllocation)( + result = (*pAllocationCallbacks->pfnAllocation)( pAllocationCallbacks->pUserData, size, alignment, @@ -2657,8 +3022,10 @@ static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t } else { - return VMA_SYSTEM_ALIGNED_MALLOC(size, alignment); + result = VMA_SYSTEM_ALIGNED_MALLOC(size, alignment); } + VMA_ASSERT(result != VMA_NULL && "CPU memory allocation failed."); + return result; } static void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr) @@ -2670,7 +3037,7 @@ static void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr } else { - VMA_SYSTEM_FREE(ptr); + VMA_SYSTEM_ALIGNED_FREE(ptr); } } @@ -2710,6 +3077,30 @@ static void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks, } } +static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr) +{ + if(srcStr != VMA_NULL) + { + const size_t len = strlen(srcStr); + char* const result = vma_new_array(allocs, char, len + 1); + memcpy(result, srcStr, len + 1); + return result; + } + else + { + return VMA_NULL; + } +} + +static void VmaFreeString(const VkAllocationCallbacks* allocs, char* str) +{ + if(str != VMA_NULL) + { + const size_t len = strlen(str); + vma_delete_array(allocs, str, len + 1); + } +} + // STL-compatible allocator. template class VmaStlAllocator @@ -2717,7 +3108,7 @@ class VmaStlAllocator public: const VkAllocationCallbacks* const m_pCallbacks; typedef T value_type; - + VmaStlAllocator(const VkAllocationCallbacks* pCallbacks) : m_pCallbacks(pCallbacks) { } template VmaStlAllocator(const VmaStlAllocator& src) : m_pCallbacks(src.m_pCallbacks) { } @@ -2736,6 +3127,7 @@ public: } VmaStlAllocator& operator=(const VmaStlAllocator& x) = delete; + VmaStlAllocator(const VmaStlAllocator&) = default; }; #if VMA_USE_STL_VECTOR @@ -2780,7 +3172,12 @@ public: m_Capacity(count) { } - + + // This version of the constructor is here for compatibility with pre-C++14 std::vector. + // value is unused. + VmaVector(size_t count, const T& value, const AllocatorT& allocator) + : VmaVector(count, allocator) {} + VmaVector(const VmaVector& src) : m_Allocator(src.m_Allocator), m_pArray(src.m_Count ? (T*)VmaAllocateArray(src.m_Allocator.m_pCallbacks, src.m_Count) : VMA_NULL), @@ -2792,7 +3189,7 @@ public: memcpy(m_pArray, src.m_pArray, m_Count * sizeof(T)); } } - + ~VmaVector() { VmaFree(m_Allocator.m_pCallbacks, m_pArray); @@ -2810,12 +3207,12 @@ public: } return *this; } - + bool empty() const { return m_Count == 0; } size_t size() const { return m_Count; } T* data() { return m_pArray; } const T* data() const { return m_pArray; } - + T& operator[](size_t index) { VMA_HEAVY_ASSERT(index < m_Count); @@ -2851,12 +3248,12 @@ public: void reserve(size_t newCapacity, bool freeMemory = false) { newCapacity = VMA_MAX(newCapacity, m_Count); - + if((newCapacity < m_Capacity) && !freeMemory) { newCapacity = m_Capacity; } - + if(newCapacity != m_Capacity) { T* const newArray = newCapacity ? VmaAllocateArray(m_Allocator, newCapacity) : VMA_NULL; @@ -2870,17 +3267,13 @@ public: } } - void resize(size_t newCount, bool freeMemory = false) + void resize(size_t newCount) { size_t newCapacity = m_Capacity; if(newCount > m_Capacity) { newCapacity = VMA_MAX(newCount, VMA_MAX(m_Capacity * 3 / 2, (size_t)8)); } - else if(freeMemory) - { - newCapacity = newCount; - } if(newCapacity != m_Capacity) { @@ -2898,9 +3291,25 @@ public: m_Count = newCount; } - void clear(bool freeMemory = false) + void clear() { - resize(0, freeMemory); + resize(0); + } + + void shrink_to_fit() + { + if(m_Capacity > m_Count) + { + T* newArray = VMA_NULL; + if(m_Count > 0) + { + newArray = VmaAllocateArray(m_Allocator.m_pCallbacks, m_Count); + memcpy(newArray, m_pArray, m_Count * sizeof(T)); + } + VmaFree(m_Allocator.m_pCallbacks, m_pArray); + m_Capacity = m_Count; + m_pArray = newArray; + } } void insert(size_t index, const T& src) @@ -2951,9 +3360,14 @@ public: } typedef T* iterator; + typedef const T* const_iterator; iterator begin() { return m_pArray; } iterator end() { return m_pArray + m_Count; } + const_iterator cbegin() const { return m_pArray; } + const_iterator cend() const { return m_pArray + m_Count; } + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } private: AllocatorT m_Allocator; @@ -3006,24 +3420,186 @@ bool VmaVectorRemoveSorted(VectorT& vector, const typename VectorT::value_type& return false; } -template -size_t VmaVectorFindSorted(const VectorT& vector, const typename VectorT::value_type& value) +//////////////////////////////////////////////////////////////////////////////// +// class VmaSmallVector + +/* +This is a vector (a variable-sized array), optimized for the case when the array is small. + +It contains some number of elements in-place, which allows it to avoid heap allocation +when the actual number of elements is below that threshold. This allows normal "small" +cases to be fast without losing generality for large inputs. +*/ + +template +class VmaSmallVector { - CmpLess comparator; - typename VectorT::iterator it = VmaBinaryFindFirstNotLess( - vector.data(), - vector.data() + vector.size(), - value, - comparator); - if(it != vector.size() && !comparator(*it, value) && !comparator(value, *it)) +public: + typedef T value_type; + + VmaSmallVector(const AllocatorT& allocator) : + m_Count(0), + m_DynamicArray(allocator) { - return it - vector.begin(); } - else + VmaSmallVector(size_t count, const AllocatorT& allocator) : + m_Count(count), + m_DynamicArray(count > N ? count : 0, allocator) { - return vector.size(); } -} + template + VmaSmallVector(const VmaSmallVector& src) = delete; + template + VmaSmallVector& operator=(const VmaSmallVector& rhs) = delete; + + bool empty() const { return m_Count == 0; } + size_t size() const { return m_Count; } + T* data() { return m_Count > N ? m_DynamicArray.data() : m_StaticArray; } + const T* data() const { return m_Count > N ? m_DynamicArray.data() : m_StaticArray; } + + T& operator[](size_t index) + { + VMA_HEAVY_ASSERT(index < m_Count); + return data()[index]; + } + const T& operator[](size_t index) const + { + VMA_HEAVY_ASSERT(index < m_Count); + return data()[index]; + } + + T& front() + { + VMA_HEAVY_ASSERT(m_Count > 0); + return data()[0]; + } + const T& front() const + { + VMA_HEAVY_ASSERT(m_Count > 0); + return data()[0]; + } + T& back() + { + VMA_HEAVY_ASSERT(m_Count > 0); + return data()[m_Count - 1]; + } + const T& back() const + { + VMA_HEAVY_ASSERT(m_Count > 0); + return data()[m_Count - 1]; + } + + void resize(size_t newCount, bool freeMemory = false) + { + if(newCount > N && m_Count > N) + { + // Any direction, staying in m_DynamicArray + m_DynamicArray.resize(newCount); + if(freeMemory) + { + m_DynamicArray.shrink_to_fit(); + } + } + else if(newCount > N && m_Count <= N) + { + // Growing, moving from m_StaticArray to m_DynamicArray + m_DynamicArray.resize(newCount); + if(m_Count > 0) + { + memcpy(m_DynamicArray.data(), m_StaticArray, m_Count * sizeof(T)); + } + } + else if(newCount <= N && m_Count > N) + { + // Shrinking, moving from m_DynamicArray to m_StaticArray + if(newCount > 0) + { + memcpy(m_StaticArray, m_DynamicArray.data(), newCount * sizeof(T)); + } + m_DynamicArray.resize(0); + if(freeMemory) + { + m_DynamicArray.shrink_to_fit(); + } + } + else + { + // Any direction, staying in m_StaticArray - nothing to do here + } + m_Count = newCount; + } + + void clear(bool freeMemory = false) + { + m_DynamicArray.clear(); + if(freeMemory) + { + m_DynamicArray.shrink_to_fit(); + } + m_Count = 0; + } + + void insert(size_t index, const T& src) + { + VMA_HEAVY_ASSERT(index <= m_Count); + const size_t oldCount = size(); + resize(oldCount + 1); + T* const dataPtr = data(); + if(index < oldCount) + { + // I know, this could be more optimal for case where memmove can be memcpy directly from m_StaticArray to m_DynamicArray. + memmove(dataPtr + (index + 1), dataPtr + index, (oldCount - index) * sizeof(T)); + } + dataPtr[index] = src; + } + + void remove(size_t index) + { + VMA_HEAVY_ASSERT(index < m_Count); + const size_t oldCount = size(); + if(index < oldCount - 1) + { + // I know, this could be more optimal for case where memmove can be memcpy directly from m_DynamicArray to m_StaticArray. + T* const dataPtr = data(); + memmove(dataPtr + index, dataPtr + (index + 1), (oldCount - index - 1) * sizeof(T)); + } + resize(oldCount - 1); + } + + void push_back(const T& src) + { + const size_t newIndex = size(); + resize(newIndex + 1); + data()[newIndex] = src; + } + + void pop_back() + { + VMA_HEAVY_ASSERT(m_Count > 0); + resize(size() - 1); + } + + void push_front(const T& src) + { + insert(0, src); + } + + void pop_front() + { + VMA_HEAVY_ASSERT(m_Count > 0); + remove(0); + } + + typedef T* iterator; + + iterator begin() { return data(); } + iterator end() { return data() + m_Count; } + +private: + size_t m_Count; + T m_StaticArray[N]; // Used when m_Size <= N + VmaVector m_DynamicArray; // Used when m_Size > N +}; //////////////////////////////////////////////////////////////////////////////// // class VmaPoolAllocator @@ -3036,58 +3612,53 @@ allocator can create multiple blocks. template class VmaPoolAllocator { + VMA_CLASS_NO_COPY(VmaPoolAllocator) public: - VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, size_t itemsPerBlock); + VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity); ~VmaPoolAllocator(); - void Clear(); - T* Alloc(); + template T* Alloc(Types&&... args); void Free(T* ptr); private: union Item { uint32_t NextFreeIndex; - T Value; + alignas(T) char Value[sizeof(T)]; }; struct ItemBlock { Item* pItems; + uint32_t Capacity; uint32_t FirstFreeIndex; }; - + const VkAllocationCallbacks* m_pAllocationCallbacks; - size_t m_ItemsPerBlock; + const uint32_t m_FirstBlockCapacity; VmaVector< ItemBlock, VmaStlAllocator > m_ItemBlocks; ItemBlock& CreateNewBlock(); }; template -VmaPoolAllocator::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, size_t itemsPerBlock) : +VmaPoolAllocator::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity) : m_pAllocationCallbacks(pAllocationCallbacks), - m_ItemsPerBlock(itemsPerBlock), + m_FirstBlockCapacity(firstBlockCapacity), m_ItemBlocks(VmaStlAllocator(pAllocationCallbacks)) { - VMA_ASSERT(itemsPerBlock > 0); + VMA_ASSERT(m_FirstBlockCapacity > 1); } template VmaPoolAllocator::~VmaPoolAllocator() -{ - Clear(); -} - -template -void VmaPoolAllocator::Clear() { for(size_t i = m_ItemBlocks.size(); i--; ) - vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemsPerBlock); + vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemBlocks[i].Capacity); m_ItemBlocks.clear(); } template -T* VmaPoolAllocator::Alloc() +template T* VmaPoolAllocator::Alloc(Types&&... args) { for(size_t i = m_ItemBlocks.size(); i--; ) { @@ -3097,7 +3668,9 @@ T* VmaPoolAllocator::Alloc() { Item* const pItem = &block.pItems[block.FirstFreeIndex]; block.FirstFreeIndex = pItem->NextFreeIndex; - return &pItem->Value; + T* result = (T*)&pItem->Value; + new(result)T(std::forward(args)...); // Explicit constructor call. + return result; } } @@ -3105,24 +3678,27 @@ T* VmaPoolAllocator::Alloc() ItemBlock& newBlock = CreateNewBlock(); Item* const pItem = &newBlock.pItems[0]; newBlock.FirstFreeIndex = pItem->NextFreeIndex; - return &pItem->Value; + T* result = (T*)&pItem->Value; + new(result)T(std::forward(args)...); // Explicit constructor call. + return result; } template void VmaPoolAllocator::Free(T* ptr) { // Search all memory blocks to find ptr. - for(size_t i = 0; i < m_ItemBlocks.size(); ++i) + for(size_t i = m_ItemBlocks.size(); i--; ) { ItemBlock& block = m_ItemBlocks[i]; - + // Casting to union. Item* pItemPtr; memcpy(&pItemPtr, &ptr, sizeof(pItemPtr)); - + // Check if pItemPtr is in address range of this block. - if((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + m_ItemsPerBlock)) + if((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + block.Capacity)) { + ptr->~T(); // Explicit destructor call. const uint32_t index = static_cast(pItemPtr - block.pItems); pItemPtr->NextFreeIndex = block.FirstFreeIndex; block.FirstFreeIndex = index; @@ -3135,15 +3711,20 @@ void VmaPoolAllocator::Free(T* ptr) template typename VmaPoolAllocator::ItemBlock& VmaPoolAllocator::CreateNewBlock() { - ItemBlock newBlock = { - vma_new_array(m_pAllocationCallbacks, Item, m_ItemsPerBlock), 0 }; + const uint32_t newBlockCapacity = m_ItemBlocks.empty() ? + m_FirstBlockCapacity : m_ItemBlocks.back().Capacity * 3 / 2; + + const ItemBlock newBlock = { + vma_new_array(m_pAllocationCallbacks, Item, newBlockCapacity), + newBlockCapacity, + 0 }; m_ItemBlocks.push_back(newBlock); // Setup singly-linked list of all free items in this block. - for(uint32_t i = 0; i < m_ItemsPerBlock - 1; ++i) + for(uint32_t i = 0; i < newBlockCapacity - 1; ++i) newBlock.pItems[i].NextFreeIndex = i + 1; - newBlock.pItems[m_ItemsPerBlock - 1].NextFreeIndex = UINT32_MAX; + newBlock.pItems[newBlockCapacity - 1].NextFreeIndex = UINT32_MAX; return m_ItemBlocks.back(); } @@ -3168,6 +3749,7 @@ struct VmaListItem template class VmaRawList { + VMA_CLASS_NO_COPY(VmaRawList) public: typedef VmaListItem ItemType; @@ -3189,7 +3771,7 @@ public: ItemType* PushFront(const T& value); void PopBack(); void PopFront(); - + // Item can be null - it means PushBack. ItemType* InsertBefore(ItemType* pItem); // Item can be null - it means PushFront. @@ -3206,10 +3788,6 @@ private: ItemType* m_pFront; ItemType* m_pBack; size_t m_Count; - - // Declared not defined, to block copy constructor and assignment operator. - VmaRawList(const VmaRawList& src); - VmaRawList& operator=(const VmaRawList& rhs); }; template @@ -3438,6 +4016,7 @@ VmaListItem* VmaRawList::InsertAfter(ItemType* pItem, const T& value) template class VmaList { + VMA_CLASS_NO_COPY(VmaList) public: class iterator { @@ -3502,7 +4081,7 @@ public: VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; } - + private: VmaRawList* m_pList; VmaListItem* m_pItem; @@ -3530,7 +4109,7 @@ public: m_pItem(src.m_pItem) { } - + const T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); @@ -3585,7 +4164,7 @@ public: VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; } - + private: const_iterator(const VmaRawList* pList, const VmaListItem* pItem) : m_pList(pList), @@ -3610,6 +4189,9 @@ public: const_iterator cbegin() const { return const_iterator(&m_RawList, m_RawList.Front()); } const_iterator cend() const { return const_iterator(&m_RawList, VMA_NULL); } + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } + void clear() { m_RawList.Clear(); } void push_back(const T& value) { m_RawList.PushBack(value); } void erase(iterator it) { m_RawList.Remove(it.m_pItem); } @@ -3621,6 +4203,222 @@ private: #endif // #if VMA_USE_STL_LIST +//////////////////////////////////////////////////////////////////////////////// +// class VmaIntrusiveLinkedList + +/* +Expected interface of ItemTypeTraits: +struct MyItemTypeTraits +{ + typedef MyItem ItemType; + static ItemType* GetPrev(const ItemType* item) { return item->myPrevPtr; } + static ItemType* GetNext(const ItemType* item) { return item->myNextPtr; } + static ItemType*& AccessPrev(ItemType* item) { return item->myPrevPtr; } + static ItemType*& AccessNext(ItemType* item) { return item->myNextPtr; } +}; +*/ +template +class VmaIntrusiveLinkedList +{ +public: + typedef typename ItemTypeTraits::ItemType ItemType; + static ItemType* GetPrev(const ItemType* item) { return ItemTypeTraits::GetPrev(item); } + static ItemType* GetNext(const ItemType* item) { return ItemTypeTraits::GetNext(item); } + // Movable, not copyable. + VmaIntrusiveLinkedList() { } + VmaIntrusiveLinkedList(const VmaIntrusiveLinkedList& src) = delete; + VmaIntrusiveLinkedList(VmaIntrusiveLinkedList&& src) : + m_Front(src.m_Front), m_Back(src.m_Back), m_Count(src.m_Count) + { + src.m_Front = src.m_Back = VMA_NULL; + src.m_Count = 0; + } + ~VmaIntrusiveLinkedList() + { + VMA_HEAVY_ASSERT(IsEmpty()); + } + VmaIntrusiveLinkedList& operator=(const VmaIntrusiveLinkedList& src) = delete; + VmaIntrusiveLinkedList& operator=(VmaIntrusiveLinkedList&& src) + { + if(&src != this) + { + VMA_HEAVY_ASSERT(IsEmpty()); + m_Front = src.m_Front; + m_Back = src.m_Back; + m_Count = src.m_Count; + src.m_Front = src.m_Back = VMA_NULL; + src.m_Count = 0; + } + return *this; + } + void RemoveAll() + { + if(!IsEmpty()) + { + ItemType* item = m_Back; + while(item != VMA_NULL) + { + ItemType* const prevItem = ItemTypeTraits::AccessPrev(item); + ItemTypeTraits::AccessPrev(item) = VMA_NULL; + ItemTypeTraits::AccessNext(item) = VMA_NULL; + item = prevItem; + } + m_Front = VMA_NULL; + m_Back = VMA_NULL; + m_Count = 0; + } + } + size_t GetCount() const { return m_Count; } + bool IsEmpty() const { return m_Count == 0; } + ItemType* Front() { return m_Front; } + const ItemType* Front() const { return m_Front; } + ItemType* Back() { return m_Back; } + const ItemType* Back() const { return m_Back; } + void PushBack(ItemType* item) + { + VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL); + if(IsEmpty()) + { + m_Front = item; + m_Back = item; + m_Count = 1; + } + else + { + ItemTypeTraits::AccessPrev(item) = m_Back; + ItemTypeTraits::AccessNext(m_Back) = item; + m_Back = item; + ++m_Count; + } + } + void PushFront(ItemType* item) + { + VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL); + if(IsEmpty()) + { + m_Front = item; + m_Back = item; + m_Count = 1; + } + else + { + ItemTypeTraits::AccessNext(item) = m_Front; + ItemTypeTraits::AccessPrev(m_Front) = item; + m_Front = item; + ++m_Count; + } + } + ItemType* PopBack() + { + VMA_HEAVY_ASSERT(m_Count > 0); + ItemType* const backItem = m_Back; + ItemType* const prevItem = ItemTypeTraits::GetPrev(backItem); + if(prevItem != VMA_NULL) + { + ItemTypeTraits::AccessNext(prevItem) = VMA_NULL; + } + m_Back = prevItem; + --m_Count; + ItemTypeTraits::AccessPrev(backItem) = VMA_NULL; + ItemTypeTraits::AccessNext(backItem) = VMA_NULL; + return backItem; + } + ItemType* PopFront() + { + VMA_HEAVY_ASSERT(m_Count > 0); + ItemType* const frontItem = m_Front; + ItemType* const nextItem = ItemTypeTraits::GetNext(frontItem); + if(nextItem != VMA_NULL) + { + ItemTypeTraits::AccessPrev(nextItem) = VMA_NULL; + } + m_Front = nextItem; + --m_Count; + ItemTypeTraits::AccessPrev(frontItem) = VMA_NULL; + ItemTypeTraits::AccessNext(frontItem) = VMA_NULL; + return frontItem; + } + + // MyItem can be null - it means PushBack. + void InsertBefore(ItemType* existingItem, ItemType* newItem) + { + VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL); + if(existingItem != VMA_NULL) + { + ItemType* const prevItem = ItemTypeTraits::GetPrev(existingItem); + ItemTypeTraits::AccessPrev(newItem) = prevItem; + ItemTypeTraits::AccessNext(newItem) = existingItem; + ItemTypeTraits::AccessPrev(existingItem) = newItem; + if(prevItem != VMA_NULL) + { + ItemTypeTraits::AccessNext(prevItem) = newItem; + } + else + { + VMA_HEAVY_ASSERT(m_Front == existingItem); + m_Front = newItem; + } + ++m_Count; + } + else + PushBack(newItem); + } + // MyItem can be null - it means PushFront. + void InsertAfter(ItemType* existingItem, ItemType* newItem) + { + VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL); + if(existingItem != VMA_NULL) + { + ItemType* const nextItem = ItemTypeTraits::GetNext(existingItem); + ItemTypeTraits::AccessNext(newItem) = nextItem; + ItemTypeTraits::AccessPrev(newItem) = existingItem; + ItemTypeTraits::AccessNext(existingItem) = newItem; + if(nextItem != VMA_NULL) + { + ItemTypeTraits::AccessPrev(nextItem) = newItem; + } + else + { + VMA_HEAVY_ASSERT(m_Back == existingItem); + m_Back = newItem; + } + ++m_Count; + } + else + return PushFront(newItem); + } + void Remove(ItemType* item) + { + VMA_HEAVY_ASSERT(item != VMA_NULL && m_Count > 0); + if(ItemTypeTraits::GetPrev(item) != VMA_NULL) + { + ItemTypeTraits::AccessNext(ItemTypeTraits::AccessPrev(item)) = ItemTypeTraits::GetNext(item); + } + else + { + VMA_HEAVY_ASSERT(m_Front == item); + m_Front = ItemTypeTraits::GetNext(item); + } + + if(ItemTypeTraits::GetNext(item) != VMA_NULL) + { + ItemTypeTraits::AccessPrev(ItemTypeTraits::AccessNext(item)) = ItemTypeTraits::GetPrev(item); + } + else + { + VMA_HEAVY_ASSERT(m_Back == item); + m_Back = ItemTypeTraits::GetPrev(item); + } + ItemTypeTraits::AccessPrev(item) = VMA_NULL; + ItemTypeTraits::AccessNext(item) = VMA_NULL; + --m_Count; + } +private: + ItemType* m_Front = VMA_NULL; + ItemType* m_Back = VMA_NULL; + size_t m_Count = 0; +}; + //////////////////////////////////////////////////////////////////////////////// // class VmaMap @@ -3664,7 +4462,7 @@ public: void insert(const PairType& pair); iterator find(const KeyT& key); void erase(iterator it); - + private: VmaVector< PairType, VmaStlAllocator > m_Vector; }; @@ -3727,6 +4525,8 @@ void VmaMap::erase(iterator it) class VmaDeviceMemoryBlock; +enum VMA_CACHE_OPERATION { VMA_CACHE_FLUSH, VMA_CACHE_INVALIDATE }; + struct VmaAllocation_T { private: @@ -3745,16 +4545,25 @@ public: ALLOCATION_TYPE_DEDICATED, }; + /* + This struct is allocated using VmaPoolAllocator. + */ + VmaAllocation_T(uint32_t currentFrameIndex, bool userDataString) : - m_Alignment(1), - m_Size(0), - m_pUserData(VMA_NULL), - m_LastUseFrameIndex(currentFrameIndex), - m_Type((uint8_t)ALLOCATION_TYPE_NONE), - m_SuballocationType((uint8_t)VMA_SUBALLOCATION_TYPE_UNKNOWN), - m_MapCount(0), - m_Flags(userDataString ? (uint8_t)FLAG_USER_DATA_STRING : 0) + m_Alignment{1}, + m_Size{0}, + m_pUserData{VMA_NULL}, + m_LastUseFrameIndex{currentFrameIndex}, + m_MemoryTypeIndex{0}, + m_Type{(uint8_t)ALLOCATION_TYPE_NONE}, + m_SuballocationType{(uint8_t)VMA_SUBALLOCATION_TYPE_UNKNOWN}, + m_MapCount{0}, + m_Flags{userDataString ? (uint8_t)FLAG_USER_DATA_STRING : (uint8_t)0} { +#if VMA_STATS_STRING_ENABLED + m_CreationFrameIndex = currentFrameIndex; + m_BufferImageUsage = 0; +#endif } ~VmaAllocation_T() @@ -3766,11 +4575,11 @@ public: } void InitBlockAllocation( - VmaPool hPool, VmaDeviceMemoryBlock* block, VkDeviceSize offset, VkDeviceSize alignment, VkDeviceSize size, + uint32_t memoryTypeIndex, VmaSuballocationType suballocationType, bool mapped, bool canBecomeLost) @@ -3780,9 +4589,9 @@ public: m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK; m_Alignment = alignment; m_Size = size; + m_MemoryTypeIndex = memoryTypeIndex; m_MapCount = mapped ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0; m_SuballocationType = (uint8_t)suballocationType; - m_BlockAllocation.m_hPool = hPool; m_BlockAllocation.m_Block = block; m_BlockAllocation.m_Offset = offset; m_BlockAllocation.m_CanBecomeLost = canBecomeLost; @@ -3793,7 +4602,7 @@ public: VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE); VMA_ASSERT(m_LastUseFrameIndex.load() == VMA_FRAME_INDEX_LOST); m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK; - m_BlockAllocation.m_hPool = VK_NULL_HANDLE; + m_MemoryTypeIndex = 0; m_BlockAllocation.m_Block = VMA_NULL; m_BlockAllocation.m_Offset = 0; m_BlockAllocation.m_CanBecomeLost = true; @@ -3804,6 +4613,8 @@ public: VmaDeviceMemoryBlock* block, VkDeviceSize offset); + void ChangeOffset(VkDeviceSize newOffset); + // pMappedData not null means allocation is created with MAPPED flag. void InitDedicatedAllocation( uint32_t memoryTypeIndex, @@ -3817,11 +4628,13 @@ public: m_Type = (uint8_t)ALLOCATION_TYPE_DEDICATED; m_Alignment = 0; m_Size = size; + m_MemoryTypeIndex = memoryTypeIndex; m_SuballocationType = (uint8_t)suballocationType; m_MapCount = (pMappedData != VMA_NULL) ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0; - m_DedicatedAllocation.m_MemoryTypeIndex = memoryTypeIndex; m_DedicatedAllocation.m_hMemory = hMemory; m_DedicatedAllocation.m_pMappedData = pMappedData; + m_DedicatedAllocation.m_Prev = VMA_NULL; + m_DedicatedAllocation.m_Next = VMA_NULL; } ALLOCATION_TYPE GetType() const { return (ALLOCATION_TYPE)m_Type; } @@ -3839,12 +4652,11 @@ public: } VkDeviceSize GetOffset() const; VkDeviceMemory GetMemory() const; - uint32_t GetMemoryTypeIndex() const; + uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; } bool IsPersistentMap() const { return (m_MapCount & MAP_COUNT_FLAG_PERSISTENT_MAP) != 0; } void* GetMappedData() const; bool CanBecomeLost() const; - VmaPool GetPool() const; - + uint32_t GetLastUseFrameIndex() const { return m_LastUseFrameIndex.load(); @@ -3857,7 +4669,7 @@ public: - If hAllocation.LastUseFrameIndex + frameInUseCount < allocator.CurrentFrameIndex, makes it lost by setting LastUseFrameIndex = VMA_FRAME_INDEX_LOST and returns true. - Else, returns false. - + If hAllocation is already lost, assert - you should not call it then. If hAllocation was not created with CAN_BECOME_LOST_BIT, assert. */ @@ -3881,11 +4693,25 @@ public: VkResult DedicatedAllocMap(VmaAllocator hAllocator, void** ppData); void DedicatedAllocUnmap(VmaAllocator hAllocator); +#if VMA_STATS_STRING_ENABLED + uint32_t GetCreationFrameIndex() const { return m_CreationFrameIndex; } + uint32_t GetBufferImageUsage() const { return m_BufferImageUsage; } + + void InitBufferImageUsage(uint32_t bufferImageUsage) + { + VMA_ASSERT(m_BufferImageUsage == 0); + m_BufferImageUsage = bufferImageUsage; + } + + void PrintParameters(class VmaJsonWriter& json) const; +#endif + private: VkDeviceSize m_Alignment; VkDeviceSize m_Size; void* m_pUserData; VMA_ATOMIC_UINT32 m_LastUseFrameIndex; + uint32_t m_MemoryTypeIndex; uint8_t m_Type; // ALLOCATION_TYPE uint8_t m_SuballocationType; // VmaSuballocationType // Bit 0x80 is set when allocation was created with VMA_ALLOCATION_CREATE_MAPPED_BIT. @@ -3896,7 +4722,6 @@ private: // Allocation out of VmaDeviceMemoryBlock. struct BlockAllocation { - VmaPool m_hPool; // Null if belongs to general memory. VmaDeviceMemoryBlock* m_Block; VkDeviceSize m_Offset; bool m_CanBecomeLost; @@ -3905,9 +4730,10 @@ private: // Allocation for an object that has its own private VkDeviceMemory. struct DedicatedAllocation { - uint32_t m_MemoryTypeIndex; VkDeviceMemory m_hMemory; void* m_pMappedData; // Not null means memory is mapped. + VmaAllocation_T* m_Prev; + VmaAllocation_T* m_Next; }; union @@ -3918,7 +4744,38 @@ private: DedicatedAllocation m_DedicatedAllocation; }; +#if VMA_STATS_STRING_ENABLED + uint32_t m_CreationFrameIndex; + uint32_t m_BufferImageUsage; // 0 if unknown. +#endif + void FreeUserDataString(VmaAllocator hAllocator); + + friend struct VmaDedicatedAllocationListItemTraits; +}; + +struct VmaDedicatedAllocationListItemTraits +{ + typedef VmaAllocation_T ItemType; + static ItemType* GetPrev(const ItemType* item) + { + VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); + return item->m_DedicatedAllocation.m_Prev; + } + static ItemType* GetNext(const ItemType* item) + { + VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); + return item->m_DedicatedAllocation.m_Next; + } + static ItemType*& AccessPrev(ItemType* item) + { + VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); + return item->m_DedicatedAllocation.m_Prev; + } + static ItemType*& AccessNext(ItemType* item){ + VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); + return item->m_DedicatedAllocation.m_Next; + } }; /* @@ -3933,11 +4790,36 @@ struct VmaSuballocation VmaSuballocationType type; }; +// Comparator for offsets. +struct VmaSuballocationOffsetLess +{ + bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const + { + return lhs.offset < rhs.offset; + } +}; +struct VmaSuballocationOffsetGreater +{ + bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const + { + return lhs.offset > rhs.offset; + } +}; + typedef VmaList< VmaSuballocation, VmaStlAllocator > VmaSuballocationList; // Cost of one additional allocation lost, as equivalent in bytes. static const VkDeviceSize VMA_LOST_ALLOCATION_COST = 1048576; +enum class VmaAllocationRequestType +{ + Normal, + // Used by "Linear" algorithm. + UpperAddress, + EndOf1st, + EndOf2nd, +}; + /* Parameters of planned allocation inside a VmaDeviceMemoryBlock. @@ -3958,6 +4840,8 @@ struct VmaAllocationRequest VkDeviceSize sumItemSize; // Sum size of items to make lost that overlap with proposed allocation. VmaSuballocationList::iterator item; size_t itemsToMakeLostCount; + void* customData; + VmaAllocationRequestType type; VkDeviceSize CalcCost() const { @@ -3973,61 +4857,151 @@ class VmaBlockMetadata { public: VmaBlockMetadata(VmaAllocator hAllocator); - ~VmaBlockMetadata(); - void Init(VkDeviceSize size); + virtual ~VmaBlockMetadata() { } + virtual void Init(VkDeviceSize size) { m_Size = size; } // Validates all data structures inside this object. If not valid, returns false. - bool Validate() const; + virtual bool Validate() const = 0; VkDeviceSize GetSize() const { return m_Size; } - size_t GetAllocationCount() const { return m_Suballocations.size() - m_FreeCount; } - VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; } - VkDeviceSize GetUnusedRangeSizeMax() const; + virtual size_t GetAllocationCount() const = 0; + virtual VkDeviceSize GetSumFreeSize() const = 0; + virtual VkDeviceSize GetUnusedRangeSizeMax() const = 0; // Returns true if this block is empty - contains only single free suballocation. - bool IsEmpty() const; + virtual bool IsEmpty() const = 0; - void CalcAllocationStatInfo(VmaStatInfo& outInfo) const; - void AddPoolStats(VmaPoolStats& inoutStats) const; + virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const = 0; + // Shouldn't modify blockCount. + virtual void AddPoolStats(VmaPoolStats& inoutStats) const = 0; #if VMA_STATS_STRING_ENABLED - void PrintDetailedMap(class VmaJsonWriter& json) const; + virtual void PrintDetailedMap(class VmaJsonWriter& json) const = 0; #endif - // Creates trivial request for case when block is empty. - void CreateFirstAllocationRequest(VmaAllocationRequest* pAllocationRequest); - // Tries to find a place for suballocation with given parameters inside this block. // If succeeded, fills pAllocationRequest and returns true. // If failed, returns false. - bool CreateAllocationRequest( + virtual bool CreateAllocationRequest( uint32_t currentFrameIndex, uint32_t frameInUseCount, VkDeviceSize bufferImageGranularity, VkDeviceSize allocSize, VkDeviceSize allocAlignment, + bool upperAddress, VmaSuballocationType allocType, bool canMakeOtherLost, + // Always one of VMA_ALLOCATION_CREATE_STRATEGY_* or VMA_ALLOCATION_INTERNAL_STRATEGY_* flags. + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) = 0; + + virtual bool MakeRequestedAllocationsLost( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VmaAllocationRequest* pAllocationRequest) = 0; + + virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) = 0; + + virtual VkResult CheckCorruption(const void* pBlockData) = 0; + + // Makes actual allocation based on request. Request must already be checked and valid. + virtual void Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + VkDeviceSize allocSize, + VmaAllocation hAllocation) = 0; + + // Frees suballocation assigned to given memory region. + virtual void Free(const VmaAllocation allocation) = 0; + virtual void FreeAtOffset(VkDeviceSize offset) = 0; + +protected: + const VkAllocationCallbacks* GetAllocationCallbacks() const { return m_pAllocationCallbacks; } + +#if VMA_STATS_STRING_ENABLED + void PrintDetailedMap_Begin(class VmaJsonWriter& json, + VkDeviceSize unusedBytes, + size_t allocationCount, + size_t unusedRangeCount) const; + void PrintDetailedMap_Allocation(class VmaJsonWriter& json, + VkDeviceSize offset, + VmaAllocation hAllocation) const; + void PrintDetailedMap_UnusedRange(class VmaJsonWriter& json, + VkDeviceSize offset, + VkDeviceSize size) const; + void PrintDetailedMap_End(class VmaJsonWriter& json) const; +#endif + +private: + VkDeviceSize m_Size; + const VkAllocationCallbacks* m_pAllocationCallbacks; +}; + +#define VMA_VALIDATE(cond) do { if(!(cond)) { \ + VMA_ASSERT(0 && "Validation failed: " #cond); \ + return false; \ + } } while(false) + +class VmaBlockMetadata_Generic : public VmaBlockMetadata +{ + VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic) +public: + VmaBlockMetadata_Generic(VmaAllocator hAllocator); + virtual ~VmaBlockMetadata_Generic(); + virtual void Init(VkDeviceSize size); + + virtual bool Validate() const; + virtual size_t GetAllocationCount() const { return m_Suballocations.size() - m_FreeCount; } + virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; } + virtual VkDeviceSize GetUnusedRangeSizeMax() const; + virtual bool IsEmpty() const; + + virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const; + virtual void AddPoolStats(VmaPoolStats& inoutStats) const; + +#if VMA_STATS_STRING_ENABLED + virtual void PrintDetailedMap(class VmaJsonWriter& json) const; +#endif + + virtual bool CreateAllocationRequest( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, VmaAllocationRequest* pAllocationRequest); - bool MakeRequestedAllocationsLost( + virtual bool MakeRequestedAllocationsLost( uint32_t currentFrameIndex, uint32_t frameInUseCount, VmaAllocationRequest* pAllocationRequest); - uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); + virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); - // Makes actual allocation based on request. Request must already be checked and valid. - void Alloc( + virtual VkResult CheckCorruption(const void* pBlockData); + + virtual void Alloc( const VmaAllocationRequest& request, VmaSuballocationType type, VkDeviceSize allocSize, VmaAllocation hAllocation); - // Frees suballocation assigned to given memory region. - void Free(const VmaAllocation allocation); - void FreeAtOffset(VkDeviceSize offset); + virtual void Free(const VmaAllocation allocation); + virtual void FreeAtOffset(VkDeviceSize offset); + + //////////////////////////////////////////////////////////////////////////////// + // For defragmentation + + bool IsBufferImageGranularityConflictPossible( + VkDeviceSize bufferImageGranularity, + VmaSuballocationType& inOutPrevSuballocType) const; private: - VkDeviceSize m_Size; + friend class VmaDefragmentationAlgorithm_Generic; + friend class VmaDefragmentationAlgorithm_Fast; + uint32_t m_FreeCount; VkDeviceSize m_SumFreeSize; VmaSuballocationList m_Suballocations; @@ -4059,13 +5033,357 @@ private: // Returns iterator to new free suballocation at this place. VmaSuballocationList::iterator FreeSuballocation(VmaSuballocationList::iterator suballocItem); // Given free suballocation, it inserts it into sorted list of - // m_FreeSuballocationsBySize if it's suitable. + // m_FreeSuballocationsBySize if it is suitable. void RegisterFreeSuballocation(VmaSuballocationList::iterator item); // Given free suballocation, it removes it from sorted list of - // m_FreeSuballocationsBySize if it's suitable. + // m_FreeSuballocationsBySize if it is suitable. void UnregisterFreeSuballocation(VmaSuballocationList::iterator item); }; +/* +Allocations and their references in internal data structure look like this: + +if(m_2ndVectorMode == SECOND_VECTOR_EMPTY): + + 0 +-------+ + | | + | | + | | + +-------+ + | Alloc | 1st[m_1stNullItemsBeginCount] + +-------+ + | Alloc | 1st[m_1stNullItemsBeginCount + 1] + +-------+ + | ... | + +-------+ + | Alloc | 1st[1st.size() - 1] + +-------+ + | | + | | + | | +GetSize() +-------+ + +if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER): + + 0 +-------+ + | Alloc | 2nd[0] + +-------+ + | Alloc | 2nd[1] + +-------+ + | ... | + +-------+ + | Alloc | 2nd[2nd.size() - 1] + +-------+ + | | + | | + | | + +-------+ + | Alloc | 1st[m_1stNullItemsBeginCount] + +-------+ + | Alloc | 1st[m_1stNullItemsBeginCount + 1] + +-------+ + | ... | + +-------+ + | Alloc | 1st[1st.size() - 1] + +-------+ + | | +GetSize() +-------+ + +if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK): + + 0 +-------+ + | | + | | + | | + +-------+ + | Alloc | 1st[m_1stNullItemsBeginCount] + +-------+ + | Alloc | 1st[m_1stNullItemsBeginCount + 1] + +-------+ + | ... | + +-------+ + | Alloc | 1st[1st.size() - 1] + +-------+ + | | + | | + | | + +-------+ + | Alloc | 2nd[2nd.size() - 1] + +-------+ + | ... | + +-------+ + | Alloc | 2nd[1] + +-------+ + | Alloc | 2nd[0] +GetSize() +-------+ + +*/ +class VmaBlockMetadata_Linear : public VmaBlockMetadata +{ + VMA_CLASS_NO_COPY(VmaBlockMetadata_Linear) +public: + VmaBlockMetadata_Linear(VmaAllocator hAllocator); + virtual ~VmaBlockMetadata_Linear(); + virtual void Init(VkDeviceSize size); + + virtual bool Validate() const; + virtual size_t GetAllocationCount() const; + virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; } + virtual VkDeviceSize GetUnusedRangeSizeMax() const; + virtual bool IsEmpty() const { return GetAllocationCount() == 0; } + + virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const; + virtual void AddPoolStats(VmaPoolStats& inoutStats) const; + +#if VMA_STATS_STRING_ENABLED + virtual void PrintDetailedMap(class VmaJsonWriter& json) const; +#endif + + virtual bool CreateAllocationRequest( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest); + + virtual bool MakeRequestedAllocationsLost( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VmaAllocationRequest* pAllocationRequest); + + virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); + + virtual VkResult CheckCorruption(const void* pBlockData); + + virtual void Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + VkDeviceSize allocSize, + VmaAllocation hAllocation); + + virtual void Free(const VmaAllocation allocation); + virtual void FreeAtOffset(VkDeviceSize offset); + +private: + /* + There are two suballocation vectors, used in ping-pong way. + The one with index m_1stVectorIndex is called 1st. + The one with index (m_1stVectorIndex ^ 1) is called 2nd. + 2nd can be non-empty only when 1st is not empty. + When 2nd is not empty, m_2ndVectorMode indicates its mode of operation. + */ + typedef VmaVector< VmaSuballocation, VmaStlAllocator > SuballocationVectorType; + + enum SECOND_VECTOR_MODE + { + SECOND_VECTOR_EMPTY, + /* + Suballocations in 2nd vector are created later than the ones in 1st, but they + all have smaller offset. + */ + SECOND_VECTOR_RING_BUFFER, + /* + Suballocations in 2nd vector are upper side of double stack. + They all have offsets higher than those in 1st vector. + Top of this stack means smaller offsets, but higher indices in this vector. + */ + SECOND_VECTOR_DOUBLE_STACK, + }; + + VkDeviceSize m_SumFreeSize; + SuballocationVectorType m_Suballocations0, m_Suballocations1; + uint32_t m_1stVectorIndex; + SECOND_VECTOR_MODE m_2ndVectorMode; + + SuballocationVectorType& AccessSuballocations1st() { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; } + SuballocationVectorType& AccessSuballocations2nd() { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; } + const SuballocationVectorType& AccessSuballocations1st() const { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; } + const SuballocationVectorType& AccessSuballocations2nd() const { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; } + + // Number of items in 1st vector with hAllocation = null at the beginning. + size_t m_1stNullItemsBeginCount; + // Number of other items in 1st vector with hAllocation = null somewhere in the middle. + size_t m_1stNullItemsMiddleCount; + // Number of items in 2nd vector with hAllocation = null. + size_t m_2ndNullItemsCount; + + bool ShouldCompact1st() const; + void CleanupAfterFree(); + + bool CreateAllocationRequest_LowerAddress( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest); + bool CreateAllocationRequest_UpperAddress( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest); +}; + +/* +- GetSize() is the original size of allocated memory block. +- m_UsableSize is this size aligned down to a power of two. + All allocations and calculations happen relative to m_UsableSize. +- GetUnusableSize() is the difference between them. + It is reported as separate, unused range, not available for allocations. + +Node at level 0 has size = m_UsableSize. +Each next level contains nodes with size 2 times smaller than current level. +m_LevelCount is the maximum number of levels to use in the current object. +*/ +class VmaBlockMetadata_Buddy : public VmaBlockMetadata +{ + VMA_CLASS_NO_COPY(VmaBlockMetadata_Buddy) +public: + VmaBlockMetadata_Buddy(VmaAllocator hAllocator); + virtual ~VmaBlockMetadata_Buddy(); + virtual void Init(VkDeviceSize size); + + virtual bool Validate() const; + virtual size_t GetAllocationCount() const { return m_AllocationCount; } + virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize + GetUnusableSize(); } + virtual VkDeviceSize GetUnusedRangeSizeMax() const; + virtual bool IsEmpty() const { return m_Root->type == Node::TYPE_FREE; } + + virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const; + virtual void AddPoolStats(VmaPoolStats& inoutStats) const; + +#if VMA_STATS_STRING_ENABLED + virtual void PrintDetailedMap(class VmaJsonWriter& json) const; +#endif + + virtual bool CreateAllocationRequest( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest); + + virtual bool MakeRequestedAllocationsLost( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VmaAllocationRequest* pAllocationRequest); + + virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); + + virtual VkResult CheckCorruption(const void* pBlockData) { return VK_ERROR_FEATURE_NOT_PRESENT; } + + virtual void Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + VkDeviceSize allocSize, + VmaAllocation hAllocation); + + virtual void Free(const VmaAllocation allocation) { FreeAtOffset(allocation, allocation->GetOffset()); } + virtual void FreeAtOffset(VkDeviceSize offset) { FreeAtOffset(VMA_NULL, offset); } + +private: + static const VkDeviceSize MIN_NODE_SIZE = 32; + static const size_t MAX_LEVELS = 30; + + struct ValidationContext + { + size_t calculatedAllocationCount; + size_t calculatedFreeCount; + VkDeviceSize calculatedSumFreeSize; + + ValidationContext() : + calculatedAllocationCount(0), + calculatedFreeCount(0), + calculatedSumFreeSize(0) { } + }; + + struct Node + { + VkDeviceSize offset; + enum TYPE + { + TYPE_FREE, + TYPE_ALLOCATION, + TYPE_SPLIT, + TYPE_COUNT + } type; + Node* parent; + Node* buddy; + + union + { + struct + { + Node* prev; + Node* next; + } free; + struct + { + VmaAllocation alloc; + } allocation; + struct + { + Node* leftChild; + } split; + }; + }; + + // Size of the memory block aligned down to a power of two. + VkDeviceSize m_UsableSize; + uint32_t m_LevelCount; + + Node* m_Root; + struct { + Node* front; + Node* back; + } m_FreeList[MAX_LEVELS]; + // Number of nodes in the tree with type == TYPE_ALLOCATION. + size_t m_AllocationCount; + // Number of nodes in the tree with type == TYPE_FREE. + size_t m_FreeCount; + // This includes space wasted due to internal fragmentation. Doesn't include unusable size. + VkDeviceSize m_SumFreeSize; + + VkDeviceSize GetUnusableSize() const { return GetSize() - m_UsableSize; } + void DeleteNode(Node* node); + bool ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const; + uint32_t AllocSizeToLevel(VkDeviceSize allocSize) const; + inline VkDeviceSize LevelToNodeSize(uint32_t level) const { return m_UsableSize >> level; } + // Alloc passed just for validation. Can be null. + void FreeAtOffset(VmaAllocation alloc, VkDeviceSize offset); + void CalcAllocationStatInfoNode(VmaStatInfo& outInfo, const Node* node, VkDeviceSize levelNodeSize) const; + // Adds node to the front of FreeList at given level. + // node->type must be FREE. + // node->free.prev, next can be undefined. + void AddToFreeListFront(uint32_t level, Node* node); + // Removes node from FreeList at given level. + // node->type must be FREE. + // node->free.prev, next stay untouched. + void RemoveFromFreeList(uint32_t level, Node* node); + +#if VMA_STATS_STRING_ENABLED + void PrintDetailedMapNode(class VmaJsonWriter& json, const Node* node, VkDeviceSize levelNodeSize) const; +#endif +}; + /* Represents a single block of device memory (`VkDeviceMemory`) with all the data about its regions (aka suballocations, #VmaAllocation), assigned and free. @@ -4074,8 +5392,9 @@ Thread-safety: This class must be externally synchronized. */ class VmaDeviceMemoryBlock { + VMA_CLASS_NO_COPY(VmaDeviceMemoryBlock) public: - VmaBlockMetadata m_Metadata; + VmaBlockMetadata* m_pMetadata; VmaDeviceMemoryBlock(VmaAllocator hAllocator); @@ -4087,52 +5406,76 @@ public: // Always call after construction. void Init( + VmaAllocator hAllocator, + VmaPool hParentPool, uint32_t newMemoryTypeIndex, VkDeviceMemory newMemory, - VkDeviceSize newSize); + VkDeviceSize newSize, + uint32_t id, + uint32_t algorithm); // Always call before destruction. void Destroy(VmaAllocator allocator); - + + VmaPool GetParentPool() const { return m_hParentPool; } VkDeviceMemory GetDeviceMemory() const { return m_hMemory; } uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; } + uint32_t GetId() const { return m_Id; } void* GetMappedData() const { return m_pMappedData; } // Validates all data structures inside this object. If not valid, returns false. bool Validate() const; + VkResult CheckCorruption(VmaAllocator hAllocator); + // ppData can be null. VkResult Map(VmaAllocator hAllocator, uint32_t count, void** ppData); void Unmap(VmaAllocator hAllocator, uint32_t count); + VkResult WriteMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize); + VkResult ValidateMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize); + VkResult BindBufferMemory( const VmaAllocator hAllocator, const VmaAllocation hAllocation, - VkBuffer hBuffer); + VkDeviceSize allocationLocalOffset, + VkBuffer hBuffer, + const void* pNext); VkResult BindImageMemory( const VmaAllocator hAllocator, const VmaAllocation hAllocation, - VkImage hImage); + VkDeviceSize allocationLocalOffset, + VkImage hImage, + const void* pNext); private: + VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool. uint32_t m_MemoryTypeIndex; + uint32_t m_Id; VkDeviceMemory m_hMemory; - // Protects access to m_hMemory so it's not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory. - // Also protects m_MapCount, m_pMappedData. + /* + Protects access to m_hMemory so it is not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory. + Also protects m_MapCount, m_pMappedData. + Allocations, deallocations, any change in m_pMetadata is protected by parent's VmaBlockVector::m_Mutex. + */ VMA_MUTEX m_Mutex; uint32_t m_MapCount; void* m_pMappedData; }; -struct VmaPointerLess +struct VmaDefragmentationMove { - bool operator()(const void* lhs, const void* rhs) const - { - return lhs < rhs; - } + size_t srcBlockIndex; + size_t dstBlockIndex; + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; + VmaAllocation hAllocation; + VmaDeviceMemoryBlock* pSrcBlock; + VmaDeviceMemoryBlock* pDstBlock; }; -class VmaDefragmentator; +class VmaDefragmentationAlgorithm; /* Sequence of VmaDeviceMemoryBlock. Represents memory blocks allocated for a specific @@ -4142,38 +5485,50 @@ Synchronized internally with a mutex. */ struct VmaBlockVector { + VMA_CLASS_NO_COPY(VmaBlockVector) +public: VmaBlockVector( VmaAllocator hAllocator, + VmaPool hParentPool, uint32_t memoryTypeIndex, VkDeviceSize preferredBlockSize, size_t minBlockCount, size_t maxBlockCount, VkDeviceSize bufferImageGranularity, uint32_t frameInUseCount, - bool isCustomPool); + bool explicitBlockSize, + uint32_t algorithm, + float priority, + VkDeviceSize minAllocationAlignment, + void* pMemoryAllocateNext); ~VmaBlockVector(); VkResult CreateMinBlocks(); + VmaAllocator GetAllocator() const { return m_hAllocator; } + VmaPool GetParentPool() const { return m_hParentPool; } + bool IsCustomPool() const { return m_hParentPool != VMA_NULL; } uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; } VkDeviceSize GetPreferredBlockSize() const { return m_PreferredBlockSize; } VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; } uint32_t GetFrameInUseCount() const { return m_FrameInUseCount; } + uint32_t GetAlgorithm() const { return m_Algorithm; } void GetPoolStats(VmaPoolStats* pStats); - bool IsEmpty() const { return m_Blocks.empty(); } + bool IsEmpty(); + bool IsCorruptionDetectionEnabled() const; VkResult Allocate( - VmaPool hCurrentPool, uint32_t currentFrameIndex, - const VkMemoryRequirements& vkMemReq, + VkDeviceSize size, + VkDeviceSize alignment, const VmaAllocationCreateInfo& createInfo, VmaSuballocationType suballocType, - VmaAllocation* pAllocation); + size_t allocationCount, + VmaAllocation* pAllocations); - void Free( - VmaAllocation hAllocation); + void Free(const VmaAllocation hAllocation); // Adds statistics of this BlockVector to pStats. void AddStats(VmaStats* pStats); @@ -4185,39 +5540,62 @@ struct VmaBlockVector void MakePoolAllocationsLost( uint32_t currentFrameIndex, size_t* pLostAllocationCount); + VkResult CheckCorruption(); - VmaDefragmentator* EnsureDefragmentator( - VmaAllocator hAllocator, - uint32_t currentFrameIndex); + // Saves results in pCtx->res. + void Defragment( + class VmaBlockVectorDefragmentationContext* pCtx, + VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags, + VkDeviceSize& maxCpuBytesToMove, uint32_t& maxCpuAllocationsToMove, + VkDeviceSize& maxGpuBytesToMove, uint32_t& maxGpuAllocationsToMove, + VkCommandBuffer commandBuffer); + void DefragmentationEnd( + class VmaBlockVectorDefragmentationContext* pCtx, + uint32_t flags, + VmaDefragmentationStats* pStats); - VkResult Defragment( - VmaDefragmentationStats* pDefragmentationStats, - VkDeviceSize& maxBytesToMove, - uint32_t& maxAllocationsToMove); + uint32_t ProcessDefragmentations( + class VmaBlockVectorDefragmentationContext *pCtx, + VmaDefragmentationPassMoveInfo* pMove, uint32_t maxMoves); - void DestroyDefragmentator(); + void CommitDefragmentations( + class VmaBlockVectorDefragmentationContext *pCtx, + VmaDefragmentationStats* pStats); + + //////////////////////////////////////////////////////////////////////////////// + // To be used only while the m_Mutex is locked. Used during defragmentation. + + size_t GetBlockCount() const { return m_Blocks.size(); } + VmaDeviceMemoryBlock* GetBlock(size_t index) const { return m_Blocks[index]; } + size_t CalcAllocationCount() const; + bool IsBufferImageGranularityConflictPossible() const; private: - friend class VmaDefragmentator; + friend class VmaDefragmentationAlgorithm_Generic; const VmaAllocator m_hAllocator; + const VmaPool m_hParentPool; const uint32_t m_MemoryTypeIndex; const VkDeviceSize m_PreferredBlockSize; const size_t m_MinBlockCount; const size_t m_MaxBlockCount; const VkDeviceSize m_BufferImageGranularity; const uint32_t m_FrameInUseCount; - const bool m_IsCustomPool; - VMA_MUTEX m_Mutex; + const bool m_ExplicitBlockSize; + const uint32_t m_Algorithm; + const float m_Priority; + const VkDeviceSize m_MinAllocationAlignment; + void* const m_pMemoryAllocateNext; + VMA_RW_MUTEX m_Mutex; + + /* There can be at most one allocation that is completely empty (except when minBlockCount > 0) - + a hysteresis to avoid pessimistic case of alternating creation and destruction of a VkDeviceMemory. */ + bool m_HasEmptyBlock; // Incrementally sorted by sumFreeSize, ascending. VmaVector< VmaDeviceMemoryBlock*, VmaStlAllocator > m_Blocks; - /* There can be at most one allocation that is completely empty - a - hysteresis to avoid pessimistic case of alternating creation and destruction - of a VkDeviceMemory. */ - bool m_HasEmptyBlock; - VmaDefragmentator* m_pDefragmentator; + uint32_t m_NextBlockId; - size_t CalcMaxBlockSize() const; + VkDeviceSize CalcMaxBlockSize() const; // Finds and removes given block from vector. void Remove(VmaDeviceMemoryBlock* pBlock); @@ -4226,34 +5604,126 @@ private: // after this call. void IncrementallySortBlocks(); + VkResult AllocatePage( + uint32_t currentFrameIndex, + VkDeviceSize size, + VkDeviceSize alignment, + const VmaAllocationCreateInfo& createInfo, + VmaSuballocationType suballocType, + VmaAllocation* pAllocation); + + // To be used only without CAN_MAKE_OTHER_LOST flag. + VkResult AllocateFromBlock( + VmaDeviceMemoryBlock* pBlock, + uint32_t currentFrameIndex, + VkDeviceSize size, + VkDeviceSize alignment, + VmaAllocationCreateFlags allocFlags, + void* pUserData, + VmaSuballocationType suballocType, + uint32_t strategy, + VmaAllocation* pAllocation); + VkResult CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex); + + // Saves result to pCtx->res. + void ApplyDefragmentationMovesCpu( + class VmaBlockVectorDefragmentationContext* pDefragCtx, + const VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves); + // Saves result to pCtx->res. + void ApplyDefragmentationMovesGpu( + class VmaBlockVectorDefragmentationContext* pDefragCtx, + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, + VkCommandBuffer commandBuffer); + + /* + Used during defragmentation. pDefragmentationStats is optional. It is in/out + - updated with new data. + */ + void FreeEmptyBlocks(VmaDefragmentationStats* pDefragmentationStats); + + void UpdateHasEmptyBlock(); }; struct VmaPool_T { + VMA_CLASS_NO_COPY(VmaPool_T) public: VmaBlockVector m_BlockVector; - // Takes ownership. VmaPool_T( VmaAllocator hAllocator, - const VmaPoolCreateInfo& createInfo); + const VmaPoolCreateInfo& createInfo, + VkDeviceSize preferredBlockSize); ~VmaPool_T(); - VmaBlockVector& GetBlockVector() { return m_BlockVector; } + uint32_t GetId() const { return m_Id; } + void SetId(uint32_t id) { VMA_ASSERT(m_Id == 0); m_Id = id; } + + const char* GetName() const { return m_Name; } + void SetName(const char* pName); #if VMA_STATS_STRING_ENABLED //void PrintDetailedMap(class VmaStringBuilder& sb); #endif + +private: + uint32_t m_Id; + char* m_Name; + VmaPool_T* m_PrevPool = VMA_NULL; + VmaPool_T* m_NextPool = VMA_NULL; + friend struct VmaPoolListItemTraits; }; -class VmaDefragmentator +struct VmaPoolListItemTraits { - const VmaAllocator m_hAllocator; + typedef VmaPool_T ItemType; + static ItemType* GetPrev(const ItemType* item) { return item->m_PrevPool; } + static ItemType* GetNext(const ItemType* item) { return item->m_NextPool; } + static ItemType*& AccessPrev(ItemType* item) { return item->m_PrevPool; } + static ItemType*& AccessNext(ItemType* item) { return item->m_NextPool; } +}; + +/* +Performs defragmentation: + +- Updates `pBlockVector->m_pMetadata`. +- Updates allocations by calling ChangeBlockAllocation() or ChangeOffset(). +- Does not move actual data, only returns requested moves as `moves`. +*/ +class VmaDefragmentationAlgorithm +{ + VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm) +public: + VmaDefragmentationAlgorithm( + VmaAllocator hAllocator, + VmaBlockVector* pBlockVector, + uint32_t currentFrameIndex) : + m_hAllocator(hAllocator), + m_pBlockVector(pBlockVector), + m_CurrentFrameIndex(currentFrameIndex) + { + } + virtual ~VmaDefragmentationAlgorithm() + { + } + + virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) = 0; + virtual void AddAll() = 0; + + virtual VkResult Defragment( + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, + VkDeviceSize maxBytesToMove, + uint32_t maxAllocationsToMove, + VmaDefragmentationFlags flags) = 0; + + virtual VkDeviceSize GetBytesMoved() const = 0; + virtual uint32_t GetAllocationsMoved() const = 0; + +protected: + VmaAllocator const m_hAllocator; VmaBlockVector* const m_pBlockVector; - uint32_t m_CurrentFrameIndex; - VkDeviceSize m_BytesMoved; - uint32_t m_AllocationsMoved; + const uint32_t m_CurrentFrameIndex; struct AllocationInfo { @@ -4265,7 +5735,43 @@ class VmaDefragmentator m_pChanged(VMA_NULL) { } + AllocationInfo(VmaAllocation hAlloc, VkBool32* pChanged) : + m_hAllocation(hAlloc), + m_pChanged(pChanged) + { + } }; +}; + +class VmaDefragmentationAlgorithm_Generic : public VmaDefragmentationAlgorithm +{ + VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm_Generic) +public: + VmaDefragmentationAlgorithm_Generic( + VmaAllocator hAllocator, + VmaBlockVector* pBlockVector, + uint32_t currentFrameIndex, + bool overlappingMoveSupported); + virtual ~VmaDefragmentationAlgorithm_Generic(); + + virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged); + virtual void AddAll() { m_AllAllocations = true; } + + virtual VkResult Defragment( + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, + VkDeviceSize maxBytesToMove, + uint32_t maxAllocationsToMove, + VmaDefragmentationFlags flags); + + virtual VkDeviceSize GetBytesMoved() const { return m_BytesMoved; } + virtual uint32_t GetAllocationsMoved() const { return m_AllocationsMoved; } + +private: + uint32_t m_AllocationCount; + bool m_AllAllocations; + + VkDeviceSize m_BytesMoved; + uint32_t m_AllocationsMoved; struct AllocationInfoSizeGreater { @@ -4275,41 +5781,45 @@ class VmaDefragmentator } }; - // Used between AddAllocation and Defragment. - VmaVector< AllocationInfo, VmaStlAllocator > m_Allocations; + struct AllocationInfoOffsetGreater + { + bool operator()(const AllocationInfo& lhs, const AllocationInfo& rhs) const + { + return lhs.m_hAllocation->GetOffset() > rhs.m_hAllocation->GetOffset(); + } + }; struct BlockInfo { + size_t m_OriginalBlockIndex; VmaDeviceMemoryBlock* m_pBlock; bool m_HasNonMovableAllocations; VmaVector< AllocationInfo, VmaStlAllocator > m_Allocations; BlockInfo(const VkAllocationCallbacks* pAllocationCallbacks) : + m_OriginalBlockIndex(SIZE_MAX), m_pBlock(VMA_NULL), m_HasNonMovableAllocations(true), - m_Allocations(pAllocationCallbacks), - m_pMappedDataForDefragmentation(VMA_NULL) + m_Allocations(pAllocationCallbacks) { } void CalcHasNonMovableAllocations() { - const size_t blockAllocCount = m_pBlock->m_Metadata.GetAllocationCount(); + const size_t blockAllocCount = m_pBlock->m_pMetadata->GetAllocationCount(); const size_t defragmentAllocCount = m_Allocations.size(); m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount; } - void SortAllocationsBySizeDescecnding() + void SortAllocationsBySizeDescending() { VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater()); } - VkResult EnsureMapping(VmaAllocator hAllocator, void** ppMappedData); - void Unmap(VmaAllocator hAllocator); - - private: - // Not null if mapped for defragmentation only, not originally mapped. - void* m_pMappedDataForDefragmentation; + void SortAllocationsByOffsetDescending() + { + VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoOffsetGreater()); + } }; struct BlockPointerLess @@ -4338,7 +5848,7 @@ class VmaDefragmentator { return false; } - if(pLhsBlockInfo->m_pBlock->m_Metadata.GetSumFreeSize() < pRhsBlockInfo->m_pBlock->m_Metadata.GetSumFreeSize()) + if(pLhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize() < pRhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize()) { return true; } @@ -4350,44 +5860,497 @@ class VmaDefragmentator BlockInfoVector m_Blocks; VkResult DefragmentRound( + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove); + uint32_t maxAllocationsToMove, + bool freeOldAllocations); + + size_t CalcBlocksWithNonMovableCount() const; static bool MoveMakesSense( size_t dstBlockIndex, VkDeviceSize dstOffset, size_t srcBlockIndex, VkDeviceSize srcOffset); +}; +class VmaDefragmentationAlgorithm_Fast : public VmaDefragmentationAlgorithm +{ + VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm_Fast) public: - VmaDefragmentator( + VmaDefragmentationAlgorithm_Fast( VmaAllocator hAllocator, VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex); + uint32_t currentFrameIndex, + bool overlappingMoveSupported); + virtual ~VmaDefragmentationAlgorithm_Fast(); - ~VmaDefragmentator(); + virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) { ++m_AllocationCount; } + virtual void AddAll() { m_AllAllocations = true; } - VkDeviceSize GetBytesMoved() const { return m_BytesMoved; } - uint32_t GetAllocationsMoved() const { return m_AllocationsMoved; } + virtual VkResult Defragment( + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, + VkDeviceSize maxBytesToMove, + uint32_t maxAllocationsToMove, + VmaDefragmentationFlags flags); + + virtual VkDeviceSize GetBytesMoved() const { return m_BytesMoved; } + virtual uint32_t GetAllocationsMoved() const { return m_AllocationsMoved; } + +private: + struct BlockInfo + { + size_t origBlockIndex; + }; + + class FreeSpaceDatabase + { + public: + FreeSpaceDatabase() + { + FreeSpace s = {}; + s.blockInfoIndex = SIZE_MAX; + for(size_t i = 0; i < MAX_COUNT; ++i) + { + m_FreeSpaces[i] = s; + } + } + + void Register(size_t blockInfoIndex, VkDeviceSize offset, VkDeviceSize size) + { + if(size < VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) + { + return; + } + + // Find first invalid or the smallest structure. + size_t bestIndex = SIZE_MAX; + for(size_t i = 0; i < MAX_COUNT; ++i) + { + // Empty structure. + if(m_FreeSpaces[i].blockInfoIndex == SIZE_MAX) + { + bestIndex = i; + break; + } + if(m_FreeSpaces[i].size < size && + (bestIndex == SIZE_MAX || m_FreeSpaces[bestIndex].size > m_FreeSpaces[i].size)) + { + bestIndex = i; + } + } + + if(bestIndex != SIZE_MAX) + { + m_FreeSpaces[bestIndex].blockInfoIndex = blockInfoIndex; + m_FreeSpaces[bestIndex].offset = offset; + m_FreeSpaces[bestIndex].size = size; + } + } + + bool Fetch(VkDeviceSize alignment, VkDeviceSize size, + size_t& outBlockInfoIndex, VkDeviceSize& outDstOffset) + { + size_t bestIndex = SIZE_MAX; + VkDeviceSize bestFreeSpaceAfter = 0; + for(size_t i = 0; i < MAX_COUNT; ++i) + { + // Structure is valid. + if(m_FreeSpaces[i].blockInfoIndex != SIZE_MAX) + { + const VkDeviceSize dstOffset = VmaAlignUp(m_FreeSpaces[i].offset, alignment); + // Allocation fits into this structure. + if(dstOffset + size <= m_FreeSpaces[i].offset + m_FreeSpaces[i].size) + { + const VkDeviceSize freeSpaceAfter = (m_FreeSpaces[i].offset + m_FreeSpaces[i].size) - + (dstOffset + size); + if(bestIndex == SIZE_MAX || freeSpaceAfter > bestFreeSpaceAfter) + { + bestIndex = i; + bestFreeSpaceAfter = freeSpaceAfter; + } + } + } + } + + if(bestIndex != SIZE_MAX) + { + outBlockInfoIndex = m_FreeSpaces[bestIndex].blockInfoIndex; + outDstOffset = VmaAlignUp(m_FreeSpaces[bestIndex].offset, alignment); + + if(bestFreeSpaceAfter >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) + { + // Leave this structure for remaining empty space. + const VkDeviceSize alignmentPlusSize = (outDstOffset - m_FreeSpaces[bestIndex].offset) + size; + m_FreeSpaces[bestIndex].offset += alignmentPlusSize; + m_FreeSpaces[bestIndex].size -= alignmentPlusSize; + } + else + { + // This structure becomes invalid. + m_FreeSpaces[bestIndex].blockInfoIndex = SIZE_MAX; + } + + return true; + } + + return false; + } + + private: + static const size_t MAX_COUNT = 4; + + struct FreeSpace + { + size_t blockInfoIndex; // SIZE_MAX means this structure is invalid. + VkDeviceSize offset; + VkDeviceSize size; + } m_FreeSpaces[MAX_COUNT]; + }; + + const bool m_OverlappingMoveSupported; + + uint32_t m_AllocationCount; + bool m_AllAllocations; + + VkDeviceSize m_BytesMoved; + uint32_t m_AllocationsMoved; + + VmaVector< BlockInfo, VmaStlAllocator > m_BlockInfos; + + void PreprocessMetadata(); + void PostprocessMetadata(); + void InsertSuballoc(VmaBlockMetadata_Generic* pMetadata, const VmaSuballocation& suballoc); +}; + +struct VmaBlockDefragmentationContext +{ + enum BLOCK_FLAG + { + BLOCK_FLAG_USED = 0x00000001, + }; + uint32_t flags; + VkBuffer hBuffer; +}; + +class VmaBlockVectorDefragmentationContext +{ + VMA_CLASS_NO_COPY(VmaBlockVectorDefragmentationContext) +public: + VkResult res; + bool mutexLocked; + VmaVector< VmaBlockDefragmentationContext, VmaStlAllocator > blockContexts; + VmaVector< VmaDefragmentationMove, VmaStlAllocator > defragmentationMoves; + uint32_t defragmentationMovesProcessed; + uint32_t defragmentationMovesCommitted; + bool hasDefragmentationPlan; + + VmaBlockVectorDefragmentationContext( + VmaAllocator hAllocator, + VmaPool hCustomPool, // Optional. + VmaBlockVector* pBlockVector, + uint32_t currFrameIndex); + ~VmaBlockVectorDefragmentationContext(); + + VmaPool GetCustomPool() const { return m_hCustomPool; } + VmaBlockVector* GetBlockVector() const { return m_pBlockVector; } + VmaDefragmentationAlgorithm* GetAlgorithm() const { return m_pAlgorithm; } void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged); + void AddAll() { m_AllAllocations = true; } + void Begin(bool overlappingMoveSupported, VmaDefragmentationFlags flags); + +private: + const VmaAllocator m_hAllocator; + // Null if not from custom pool. + const VmaPool m_hCustomPool; + // Redundant, for convenience not to fetch from m_hCustomPool->m_BlockVector or m_hAllocator->m_pBlockVectors. + VmaBlockVector* const m_pBlockVector; + const uint32_t m_CurrFrameIndex; + // Owner of this object. + VmaDefragmentationAlgorithm* m_pAlgorithm; + + struct AllocInfo + { + VmaAllocation hAlloc; + VkBool32* pChanged; + }; + // Used between constructor and Begin. + VmaVector< AllocInfo, VmaStlAllocator > m_Allocations; + bool m_AllAllocations; +}; + +struct VmaDefragmentationContext_T +{ +private: + VMA_CLASS_NO_COPY(VmaDefragmentationContext_T) +public: + VmaDefragmentationContext_T( + VmaAllocator hAllocator, + uint32_t currFrameIndex, + uint32_t flags, + VmaDefragmentationStats* pStats); + ~VmaDefragmentationContext_T(); + + void AddPools(uint32_t poolCount, const VmaPool* pPools); + void AddAllocations( + uint32_t allocationCount, + const VmaAllocation* pAllocations, + VkBool32* pAllocationsChanged); + + /* + Returns: + - `VK_SUCCESS` if succeeded and object can be destroyed immediately. + - `VK_NOT_READY` if succeeded but the object must remain alive until vmaDefragmentationEnd(). + - Negative value if error occurred and object can be destroyed immediately. + */ VkResult Defragment( - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove); + VkDeviceSize maxCpuBytesToMove, uint32_t maxCpuAllocationsToMove, + VkDeviceSize maxGpuBytesToMove, uint32_t maxGpuAllocationsToMove, + VkCommandBuffer commandBuffer, VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags); + + VkResult DefragmentPassBegin(VmaDefragmentationPassInfo* pInfo); + VkResult DefragmentPassEnd(); + +private: + const VmaAllocator m_hAllocator; + const uint32_t m_CurrFrameIndex; + const uint32_t m_Flags; + VmaDefragmentationStats* const m_pStats; + + VkDeviceSize m_MaxCpuBytesToMove; + uint32_t m_MaxCpuAllocationsToMove; + VkDeviceSize m_MaxGpuBytesToMove; + uint32_t m_MaxGpuAllocationsToMove; + + // Owner of these objects. + VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES]; + // Owner of these objects. + VmaVector< VmaBlockVectorDefragmentationContext*, VmaStlAllocator > m_CustomPoolContexts; +}; + +#if VMA_RECORDING_ENABLED + +class VmaRecorder +{ +public: + VmaRecorder(); + VkResult Init(const VmaRecordSettings& settings, bool useMutex); + void WriteConfiguration( + const VkPhysicalDeviceProperties& devProps, + const VkPhysicalDeviceMemoryProperties& memProps, + uint32_t vulkanApiVersion, + bool dedicatedAllocationExtensionEnabled, + bool bindMemory2ExtensionEnabled, + bool memoryBudgetExtensionEnabled, + bool deviceCoherentMemoryExtensionEnabled); + ~VmaRecorder(); + + void RecordCreateAllocator(uint32_t frameIndex); + void RecordDestroyAllocator(uint32_t frameIndex); + void RecordCreatePool(uint32_t frameIndex, + const VmaPoolCreateInfo& createInfo, + VmaPool pool); + void RecordDestroyPool(uint32_t frameIndex, VmaPool pool); + void RecordAllocateMemory(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + const VmaAllocationCreateInfo& createInfo, + VmaAllocation allocation); + void RecordAllocateMemoryPages(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + const VmaAllocationCreateInfo& createInfo, + uint64_t allocationCount, + const VmaAllocation* pAllocations); + void RecordAllocateMemoryForBuffer(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + bool requiresDedicatedAllocation, + bool prefersDedicatedAllocation, + const VmaAllocationCreateInfo& createInfo, + VmaAllocation allocation); + void RecordAllocateMemoryForImage(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + bool requiresDedicatedAllocation, + bool prefersDedicatedAllocation, + const VmaAllocationCreateInfo& createInfo, + VmaAllocation allocation); + void RecordFreeMemory(uint32_t frameIndex, + VmaAllocation allocation); + void RecordFreeMemoryPages(uint32_t frameIndex, + uint64_t allocationCount, + const VmaAllocation* pAllocations); + void RecordSetAllocationUserData(uint32_t frameIndex, + VmaAllocation allocation, + const void* pUserData); + void RecordCreateLostAllocation(uint32_t frameIndex, + VmaAllocation allocation); + void RecordMapMemory(uint32_t frameIndex, + VmaAllocation allocation); + void RecordUnmapMemory(uint32_t frameIndex, + VmaAllocation allocation); + void RecordFlushAllocation(uint32_t frameIndex, + VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size); + void RecordInvalidateAllocation(uint32_t frameIndex, + VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size); + void RecordCreateBuffer(uint32_t frameIndex, + const VkBufferCreateInfo& bufCreateInfo, + const VmaAllocationCreateInfo& allocCreateInfo, + VmaAllocation allocation); + void RecordCreateImage(uint32_t frameIndex, + const VkImageCreateInfo& imageCreateInfo, + const VmaAllocationCreateInfo& allocCreateInfo, + VmaAllocation allocation); + void RecordDestroyBuffer(uint32_t frameIndex, + VmaAllocation allocation); + void RecordDestroyImage(uint32_t frameIndex, + VmaAllocation allocation); + void RecordTouchAllocation(uint32_t frameIndex, + VmaAllocation allocation); + void RecordGetAllocationInfo(uint32_t frameIndex, + VmaAllocation allocation); + void RecordMakePoolAllocationsLost(uint32_t frameIndex, + VmaPool pool); + void RecordDefragmentationBegin(uint32_t frameIndex, + const VmaDefragmentationInfo2& info, + VmaDefragmentationContext ctx); + void RecordDefragmentationEnd(uint32_t frameIndex, + VmaDefragmentationContext ctx); + void RecordSetPoolName(uint32_t frameIndex, + VmaPool pool, + const char* name); + +private: + struct CallParams + { + uint32_t threadId; + double time; + }; + + class UserDataString + { + public: + UserDataString(VmaAllocationCreateFlags allocFlags, const void* pUserData); + const char* GetString() const { return m_Str; } + + private: + char m_PtrStr[17]; + const char* m_Str; + }; + + bool m_UseMutex; + VmaRecordFlags m_Flags; + FILE* m_File; + VMA_MUTEX m_FileMutex; + std::chrono::time_point m_RecordingStartTime; + + void GetBasicParams(CallParams& outParams); + + // T must be a pointer type, e.g. VmaAllocation, VmaPool. + template + void PrintPointerList(uint64_t count, const T* pItems) + { + if(count) + { + fprintf(m_File, "%p", pItems[0]); + for(uint64_t i = 1; i < count; ++i) + { + fprintf(m_File, " %p", pItems[i]); + } + } + } + + void PrintPointerList(uint64_t count, const VmaAllocation* pItems); + void Flush(); +}; + +#endif // #if VMA_RECORDING_ENABLED + +/* +Thread-safe wrapper over VmaPoolAllocator free list, for allocation of VmaAllocation_T objects. +*/ +class VmaAllocationObjectAllocator +{ + VMA_CLASS_NO_COPY(VmaAllocationObjectAllocator) +public: + VmaAllocationObjectAllocator(const VkAllocationCallbacks* pAllocationCallbacks); + + template VmaAllocation Allocate(Types&&... args); + void Free(VmaAllocation hAlloc); + +private: + VMA_MUTEX m_Mutex; + VmaPoolAllocator m_Allocator; +}; + +struct VmaCurrentBudgetData +{ + VMA_ATOMIC_UINT64 m_BlockBytes[VK_MAX_MEMORY_HEAPS]; + VMA_ATOMIC_UINT64 m_AllocationBytes[VK_MAX_MEMORY_HEAPS]; + +#if VMA_MEMORY_BUDGET + VMA_ATOMIC_UINT32 m_OperationsSinceBudgetFetch; + VMA_RW_MUTEX m_BudgetMutex; + uint64_t m_VulkanUsage[VK_MAX_MEMORY_HEAPS]; + uint64_t m_VulkanBudget[VK_MAX_MEMORY_HEAPS]; + uint64_t m_BlockBytesAtBudgetFetch[VK_MAX_MEMORY_HEAPS]; +#endif // #if VMA_MEMORY_BUDGET + + VmaCurrentBudgetData() + { + for(uint32_t heapIndex = 0; heapIndex < VK_MAX_MEMORY_HEAPS; ++heapIndex) + { + m_BlockBytes[heapIndex] = 0; + m_AllocationBytes[heapIndex] = 0; +#if VMA_MEMORY_BUDGET + m_VulkanUsage[heapIndex] = 0; + m_VulkanBudget[heapIndex] = 0; + m_BlockBytesAtBudgetFetch[heapIndex] = 0; +#endif + } + +#if VMA_MEMORY_BUDGET + m_OperationsSinceBudgetFetch = 0; +#endif + } + + void AddAllocation(uint32_t heapIndex, VkDeviceSize allocationSize) + { + m_AllocationBytes[heapIndex] += allocationSize; +#if VMA_MEMORY_BUDGET + ++m_OperationsSinceBudgetFetch; +#endif + } + + void RemoveAllocation(uint32_t heapIndex, VkDeviceSize allocationSize) + { + VMA_ASSERT(m_AllocationBytes[heapIndex] >= allocationSize); // DELME + m_AllocationBytes[heapIndex] -= allocationSize; +#if VMA_MEMORY_BUDGET + ++m_OperationsSinceBudgetFetch; +#endif + } }; // Main allocator object. struct VmaAllocator_T { + VMA_CLASS_NO_COPY(VmaAllocator_T) +public: bool m_UseMutex; - bool m_UseKhrDedicatedAllocation; + uint32_t m_VulkanApiVersion; + bool m_UseKhrDedicatedAllocation; // Can be set only if m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0). + bool m_UseKhrBindMemory2; // Can be set only if m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0). + bool m_UseExtMemoryBudget; + bool m_UseAmdDeviceCoherentMemory; + bool m_UseKhrBufferDeviceAddress; + bool m_UseExtMemoryPriority; VkDevice m_hDevice; + VkInstance m_hInstance; bool m_AllocationCallbacksSpecified; VkAllocationCallbacks m_AllocationCallbacks; VmaDeviceMemoryCallbacks m_DeviceMemoryCallbacks; - - // Number of bytes free out of limit, or VK_WHOLE_SIZE if not limit for that heap. - VkDeviceSize m_HeapSizeLimit[VK_MAX_MEMORY_HEAPS]; - VMA_MUTEX m_HeapSizeLimitMutex; + VmaAllocationObjectAllocator m_AllocationObjectAllocator; + + // Each bit (1 << i) is set if HeapSizeLimit is enabled for that heap, so cannot allocate more than the heap size. + uint32_t m_HeapSizeLimitMask; VkPhysicalDeviceProperties m_PhysicalDeviceProperties; VkPhysicalDeviceMemoryProperties m_MemProps; @@ -4395,12 +6358,15 @@ struct VmaAllocator_T // Default pools. VmaBlockVector* m_pBlockVectors[VK_MAX_MEMORY_TYPES]; - // Each vector is sorted by memory (handle value). - typedef VmaVector< VmaAllocation, VmaStlAllocator > AllocationVectorType; - AllocationVectorType* m_pDedicatedAllocations[VK_MAX_MEMORY_TYPES]; - VMA_MUTEX m_DedicatedAllocationsMutex[VK_MAX_MEMORY_TYPES]; + typedef VmaIntrusiveLinkedList DedicatedAllocationLinkedList; + DedicatedAllocationLinkedList m_DedicatedAllocations[VK_MAX_MEMORY_TYPES]; + VMA_RW_MUTEX m_DedicatedAllocationsMutex[VK_MAX_MEMORY_TYPES]; + + VmaCurrentBudgetData m_Budget; + VMA_ATOMIC_UINT32 m_DeviceMemoryCount; // Total number of VkDeviceMemory objects. VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo); + VkResult Init(const VmaAllocatorCreateInfo* pCreateInfo); ~VmaAllocator_T(); const VkAllocationCallbacks* GetAllocationCallbacks() const @@ -4412,6 +6378,8 @@ struct VmaAllocator_T return m_VulkanFunctions; } + VkPhysicalDevice GetPhysicalDevice() const { return m_PhysicalDevice; } + VkDeviceSize GetBufferImageGranularity() const { return VMA_MAX( @@ -4427,6 +6395,30 @@ struct VmaAllocator_T VMA_ASSERT(memTypeIndex < m_MemProps.memoryTypeCount); return m_MemProps.memoryTypes[memTypeIndex].heapIndex; } + // True when specific memory type is HOST_VISIBLE but not HOST_COHERENT. + bool IsMemoryTypeNonCoherent(uint32_t memTypeIndex) const + { + return (m_MemProps.memoryTypes[memTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) == + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + } + // Minimum alignment for all allocations in specific memory type. + VkDeviceSize GetMemoryTypeMinAlignment(uint32_t memTypeIndex) const + { + return IsMemoryTypeNonCoherent(memTypeIndex) ? + VMA_MAX((VkDeviceSize)VMA_MIN_ALIGNMENT, m_PhysicalDeviceProperties.limits.nonCoherentAtomSize) : + (VkDeviceSize)VMA_MIN_ALIGNMENT; + } + + bool IsIntegratedGpu() const + { + return m_PhysicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; + } + + uint32_t GetGlobalMemoryTypeBits() const { return m_GlobalMemoryTypeBits; } + +#if VMA_RECORDING_ENABLED + VmaRecorder* GetRecorder() const { return m_pRecorder; } +#endif void GetBufferMemoryRequirements( VkBuffer hBuffer, @@ -4445,26 +6437,39 @@ struct VmaAllocator_T bool requiresDedicatedAllocation, bool prefersDedicatedAllocation, VkBuffer dedicatedBuffer, + VkBufferUsageFlags dedicatedBufferUsage, // UINT32_MAX when unknown. VkImage dedicatedImage, const VmaAllocationCreateInfo& createInfo, VmaSuballocationType suballocType, - VmaAllocation* pAllocation); + size_t allocationCount, + VmaAllocation* pAllocations); // Main deallocation function. - void FreeMemory(const VmaAllocation allocation); + void FreeMemory( + size_t allocationCount, + const VmaAllocation* pAllocations); void CalculateStats(VmaStats* pStats); + void GetBudget( + VmaBudget* outBudget, uint32_t firstHeap, uint32_t heapCount); + #if VMA_STATS_STRING_ENABLED void PrintDetailedMap(class VmaJsonWriter& json); #endif - VkResult Defragment( - VmaAllocation* pAllocations, - size_t allocationCount, - VkBool32* pAllocationsChanged, - const VmaDefragmentationInfo* pDefragmentationInfo, - VmaDefragmentationStats* pDefragmentationStats); + VkResult DefragmentationBegin( + const VmaDefragmentationInfo2& info, + VmaDefragmentationStats* pStats, + VmaDefragmentationContext* pContext); + VkResult DefragmentationEnd( + VmaDefragmentationContext context); + + VkResult DefragmentationPassBegin( + VmaDefragmentationPassInfo* pInfo, + VmaDefragmentationContext context); + VkResult DefragmentationPassEnd( + VmaDefragmentationContext context); void GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo); bool TouchAllocation(VmaAllocation hAllocation); @@ -4474,62 +6479,171 @@ struct VmaAllocator_T void GetPoolStats(VmaPool pool, VmaPoolStats* pPoolStats); void SetCurrentFrameIndex(uint32_t frameIndex); + uint32_t GetCurrentFrameIndex() const { return m_CurrentFrameIndex.load(); } void MakePoolAllocationsLost( VmaPool hPool, size_t* pLostAllocationCount); + VkResult CheckPoolCorruption(VmaPool hPool); + VkResult CheckCorruption(uint32_t memoryTypeBits); void CreateLostAllocation(VmaAllocation* pAllocation); + // Call to Vulkan function vkAllocateMemory with accompanying bookkeeping. VkResult AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory); + // Call to Vulkan function vkFreeMemory with accompanying bookkeeping. void FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory); + // Call to Vulkan function vkBindBufferMemory or vkBindBufferMemory2KHR. + VkResult BindVulkanBuffer( + VkDeviceMemory memory, + VkDeviceSize memoryOffset, + VkBuffer buffer, + const void* pNext); + // Call to Vulkan function vkBindImageMemory or vkBindImageMemory2KHR. + VkResult BindVulkanImage( + VkDeviceMemory memory, + VkDeviceSize memoryOffset, + VkImage image, + const void* pNext); VkResult Map(VmaAllocation hAllocation, void** ppData); void Unmap(VmaAllocation hAllocation); - VkResult BindBufferMemory(VmaAllocation hAllocation, VkBuffer hBuffer); - VkResult BindImageMemory(VmaAllocation hAllocation, VkImage hImage); + VkResult BindBufferMemory( + VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkBuffer hBuffer, + const void* pNext); + VkResult BindImageMemory( + VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkImage hImage, + const void* pNext); + + VkResult FlushOrInvalidateAllocation( + VmaAllocation hAllocation, + VkDeviceSize offset, VkDeviceSize size, + VMA_CACHE_OPERATION op); + VkResult FlushOrInvalidateAllocations( + uint32_t allocationCount, + const VmaAllocation* allocations, + const VkDeviceSize* offsets, const VkDeviceSize* sizes, + VMA_CACHE_OPERATION op); + + void FillAllocation(const VmaAllocation hAllocation, uint8_t pattern); + + /* + Returns bit mask of memory types that can support defragmentation on GPU as + they support creation of required buffer for copy operations. + */ + uint32_t GetGpuDefragmentationMemoryTypeBits(); + +#if VMA_EXTERNAL_MEMORY + VkExternalMemoryHandleTypeFlagsKHR GetExternalMemoryHandleTypeFlags(uint32_t memTypeIndex) const + { + return m_TypeExternalMemoryHandleTypes[memTypeIndex]; + } +#endif // #if VMA_EXTERNAL_MEMORY private: VkDeviceSize m_PreferredLargeHeapBlockSize; VkPhysicalDevice m_PhysicalDevice; VMA_ATOMIC_UINT32 m_CurrentFrameIndex; - - VMA_MUTEX m_PoolsMutex; - // Protected by m_PoolsMutex. Sorted by pointer value. - VmaVector > m_Pools; + VMA_ATOMIC_UINT32 m_GpuDefragmentationMemoryTypeBits; // UINT32_MAX means uninitialized. +#if VMA_EXTERNAL_MEMORY + VkExternalMemoryHandleTypeFlagsKHR m_TypeExternalMemoryHandleTypes[VK_MAX_MEMORY_TYPES]; +#endif // #if VMA_EXTERNAL_MEMORY + + VMA_RW_MUTEX m_PoolsMutex; + typedef VmaIntrusiveLinkedList PoolList; + // Protected by m_PoolsMutex. + PoolList m_Pools; + uint32_t m_NextPoolId; VmaVulkanFunctions m_VulkanFunctions; + // Global bit mask AND-ed with any memoryTypeBits to disallow certain memory types. + uint32_t m_GlobalMemoryTypeBits; + +#if VMA_RECORDING_ENABLED + VmaRecorder* m_pRecorder; +#endif + void ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunctions); +#if VMA_STATIC_VULKAN_FUNCTIONS == 1 + void ImportVulkanFunctions_Static(); +#endif + + void ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVulkanFunctions); + +#if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1 + void ImportVulkanFunctions_Dynamic(); +#endif + + void ValidateVulkanFunctions(); + VkDeviceSize CalcPreferredBlockSize(uint32_t memTypeIndex); VkResult AllocateMemoryOfType( - const VkMemoryRequirements& vkMemReq, + VkDeviceSize size, + VkDeviceSize alignment, bool dedicatedAllocation, VkBuffer dedicatedBuffer, + VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, const VmaAllocationCreateInfo& createInfo, uint32_t memTypeIndex, VmaSuballocationType suballocType, + size_t allocationCount, + VmaAllocation* pAllocations); + + // Helper function only to be used inside AllocateDedicatedMemory. + VkResult AllocateDedicatedMemoryPage( + VkDeviceSize size, + VmaSuballocationType suballocType, + uint32_t memTypeIndex, + const VkMemoryAllocateInfo& allocInfo, + bool map, + bool isUserDataString, + void* pUserData, VmaAllocation* pAllocation); - // Allocates and registers new VkDeviceMemory specifically for single allocation. + // Allocates and registers new VkDeviceMemory specifically for dedicated allocations. VkResult AllocateDedicatedMemory( VkDeviceSize size, VmaSuballocationType suballocType, uint32_t memTypeIndex, + bool withinBudget, bool map, bool isUserDataString, void* pUserData, + float priority, VkBuffer dedicatedBuffer, + VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, - VmaAllocation* pAllocation); + size_t allocationCount, + VmaAllocation* pAllocations); - // Tries to free pMemory as Dedicated Memory. Returns true if found and freed. - void FreeDedicatedMemory(VmaAllocation allocation); + void FreeDedicatedMemory(const VmaAllocation allocation); + + /* + Calculates and returns bit mask of memory types that can support defragmentation + on GPU as they support creation of required buffer for copy operations. + */ + uint32_t CalculateGpuDefragmentationMemoryTypeBits() const; + + uint32_t CalculateGlobalMemoryTypeBits() const; + + bool GetFlushOrInvalidateRange( + VmaAllocation allocation, + VkDeviceSize offset, VkDeviceSize size, + VkMappedMemoryRange& outRange) const; + +#if VMA_MEMORY_BUDGET + void UpdateVulkanBudget(); +#endif // #if VMA_MEMORY_BUDGET }; //////////////////////////////////////////////////////////////////////////////// @@ -4615,15 +6729,29 @@ void VmaStringBuilder::Add(const char* pStr) void VmaStringBuilder::AddNumber(uint32_t num) { char buf[11]; - VmaUint32ToStr(buf, sizeof(buf), num); - Add(buf); + buf[10] = '\0'; + char *p = &buf[10]; + do + { + *--p = '0' + (num % 10); + num /= 10; + } + while(num); + Add(p); } void VmaStringBuilder::AddNumber(uint64_t num) { char buf[21]; - VmaUint64ToStr(buf, sizeof(buf), num); - Add(buf); + buf[20] = '\0'; + char *p = &buf[20]; + do + { + *--p = '0' + (num % 10); + num /= 10; + } + while(num); + Add(p); } void VmaStringBuilder::AddPointer(const void* ptr) @@ -4642,16 +6770,17 @@ void VmaStringBuilder::AddPointer(const void* ptr) class VmaJsonWriter { + VMA_CLASS_NO_COPY(VmaJsonWriter) public: VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb); ~VmaJsonWriter(); void BeginObject(bool singleLine = false); void EndObject(); - + void BeginArray(bool singleLine = false); void EndArray(); - + void WriteString(const char* pStr); void BeginString(const char* pStr = VMA_NULL); void ContinueString(const char* pStr); @@ -4659,7 +6788,7 @@ public: void ContinueString(uint64_t n); void ContinueString_Pointer(const void* ptr); void EndString(const char* pStr = VMA_NULL); - + void WriteNumber(uint32_t n); void WriteNumber(uint64_t n); void WriteBool(bool b); @@ -4780,7 +6909,7 @@ void VmaJsonWriter::ContinueString(const char* pStr) for(size_t i = 0; i < strLen; ++i) { char ch = pStr[i]; - if(ch == '\'') + if(ch == '\\') { m_SB.Add("\\\\"); } @@ -4907,7 +7036,7 @@ void VmaJsonWriter::WriteIndent(bool oneLess) if(!m_Stack.empty() && !m_Stack.back().singleLineMode) { m_SB.AddNewLine(); - + size_t count = m_Stack.size(); if(count > 0 && oneLess) { @@ -4934,11 +7063,7 @@ void VmaAllocation_T::SetUserData(VmaAllocator hAllocator, void* pUserData) if(pUserData != VMA_NULL) { - const char* const newStrSrc = (char*)pUserData; - const size_t newStrLen = strlen(newStrSrc); - char* const newStrDst = vma_new_array(hAllocator, char, newStrLen + 1); - memcpy(newStrDst, newStrSrc, newStrLen + 1); - m_pUserData = newStrDst; + m_pUserData = VmaCreateStringCopy(hAllocator->GetAllocationCallbacks(), (const char*)pUserData); } } else @@ -4969,6 +7094,12 @@ void VmaAllocation_T::ChangeBlockAllocation( m_BlockAllocation.m_Offset = offset; } +void VmaAllocation_T::ChangeOffset(VkDeviceSize newOffset) +{ + VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK); + m_BlockAllocation.m_Offset = newOffset; +} + VkDeviceSize VmaAllocation_T::GetOffset() const { switch(m_Type) @@ -4997,20 +7128,6 @@ VkDeviceMemory VmaAllocation_T::GetMemory() const } } -uint32_t VmaAllocation_T::GetMemoryTypeIndex() const -{ - switch(m_Type) - { - case ALLOCATION_TYPE_BLOCK: - return m_BlockAllocation.m_Block->GetMemoryTypeIndex(); - case ALLOCATION_TYPE_DEDICATED: - return m_DedicatedAllocation.m_MemoryTypeIndex; - default: - VMA_ASSERT(0); - return UINT32_MAX; - } -} - void* VmaAllocation_T::GetMappedData() const { switch(m_Type) @@ -5050,12 +7167,6 @@ bool VmaAllocation_T::CanBecomeLost() const } } -VmaPool VmaAllocation_T::GetPool() const -{ - VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK); - return m_BlockAllocation.m_hPool; -} - bool VmaAllocation_T::MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) { VMA_ASSERT(CanBecomeLost()); @@ -5088,16 +7199,61 @@ bool VmaAllocation_T::MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCo } } +#if VMA_STATS_STRING_ENABLED + +// Correspond to values of enum VmaSuballocationType. +static const char* VMA_SUBALLOCATION_TYPE_NAMES[] = { + "FREE", + "UNKNOWN", + "BUFFER", + "IMAGE_UNKNOWN", + "IMAGE_LINEAR", + "IMAGE_OPTIMAL", +}; + +void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const +{ + json.WriteString("Type"); + json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[m_SuballocationType]); + + json.WriteString("Size"); + json.WriteNumber(m_Size); + + if(m_pUserData != VMA_NULL) + { + json.WriteString("UserData"); + if(IsUserDataString()) + { + json.WriteString((const char*)m_pUserData); + } + else + { + json.BeginString(); + json.ContinueString_Pointer(m_pUserData); + json.EndString(); + } + } + + json.WriteString("CreationFrameIndex"); + json.WriteNumber(m_CreationFrameIndex); + + json.WriteString("LastUseFrameIndex"); + json.WriteNumber(GetLastUseFrameIndex()); + + if(m_BufferImageUsage != 0) + { + json.WriteString("Usage"); + json.WriteNumber(m_BufferImageUsage); + } +} + +#endif + void VmaAllocation_T::FreeUserDataString(VmaAllocator hAllocator) { VMA_ASSERT(IsUserDataString()); - if(m_pUserData != VMA_NULL) - { - char* const oldStr = (char*)m_pUserData; - const size_t oldStrLen = strlen(oldStr); - vma_delete_array(hAllocator, oldStr, oldStrLen + 1); - m_pUserData = VMA_NULL; - } + VmaFreeString(hAllocator->GetAllocationCallbacks(), (char*)m_pUserData); + m_pUserData = VMA_NULL; } void VmaAllocation_T::BlockAllocMap() @@ -5188,16 +7344,6 @@ void VmaAllocation_T::DedicatedAllocUnmap(VmaAllocator hAllocator) #if VMA_STATS_STRING_ENABLED -// Correspond to values of enum VmaSuballocationType. -static const char* VMA_SUBALLOCATION_TYPE_NAMES[] = { - "FREE", - "UNKNOWN", - "BUFFER", - "IMAGE_UNKNOWN", - "IMAGE_LINEAR", - "IMAGE_OPTIMAL", -}; - static void VmaPrintStatInfo(VmaJsonWriter& json, const VmaStatInfo& stat) { json.BeginObject(); @@ -5264,11 +7410,86 @@ struct VmaSuballocationItemSizeLess } }; + //////////////////////////////////////////////////////////////////////////////// // class VmaBlockMetadata VmaBlockMetadata::VmaBlockMetadata(VmaAllocator hAllocator) : m_Size(0), + m_pAllocationCallbacks(hAllocator->GetAllocationCallbacks()) +{ +} + +#if VMA_STATS_STRING_ENABLED + +void VmaBlockMetadata::PrintDetailedMap_Begin(class VmaJsonWriter& json, + VkDeviceSize unusedBytes, + size_t allocationCount, + size_t unusedRangeCount) const +{ + json.BeginObject(); + + json.WriteString("TotalBytes"); + json.WriteNumber(GetSize()); + + json.WriteString("UnusedBytes"); + json.WriteNumber(unusedBytes); + + json.WriteString("Allocations"); + json.WriteNumber((uint64_t)allocationCount); + + json.WriteString("UnusedRanges"); + json.WriteNumber((uint64_t)unusedRangeCount); + + json.WriteString("Suballocations"); + json.BeginArray(); +} + +void VmaBlockMetadata::PrintDetailedMap_Allocation(class VmaJsonWriter& json, + VkDeviceSize offset, + VmaAllocation hAllocation) const +{ + json.BeginObject(true); + + json.WriteString("Offset"); + json.WriteNumber(offset); + + hAllocation->PrintParameters(json); + + json.EndObject(); +} + +void VmaBlockMetadata::PrintDetailedMap_UnusedRange(class VmaJsonWriter& json, + VkDeviceSize offset, + VkDeviceSize size) const +{ + json.BeginObject(true); + + json.WriteString("Offset"); + json.WriteNumber(offset); + + json.WriteString("Type"); + json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[VMA_SUBALLOCATION_TYPE_FREE]); + + json.WriteString("Size"); + json.WriteNumber(size); + + json.EndObject(); +} + +void VmaBlockMetadata::PrintDetailedMap_End(class VmaJsonWriter& json) const +{ + json.EndArray(); + json.EndObject(); +} + +#endif // #if VMA_STATS_STRING_ENABLED + +//////////////////////////////////////////////////////////////////////////////// +// class VmaBlockMetadata_Generic + +VmaBlockMetadata_Generic::VmaBlockMetadata_Generic(VmaAllocator hAllocator) : + VmaBlockMetadata(hAllocator), m_FreeCount(0), m_SumFreeSize(0), m_Suballocations(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), @@ -5276,13 +7497,14 @@ VmaBlockMetadata::VmaBlockMetadata(VmaAllocator hAllocator) : { } -VmaBlockMetadata::~VmaBlockMetadata() +VmaBlockMetadata_Generic::~VmaBlockMetadata_Generic() { } -void VmaBlockMetadata::Init(VkDeviceSize size) +void VmaBlockMetadata_Generic::Init(VkDeviceSize size) { - m_Size = size; + VmaBlockMetadata::Init(size); + m_FreeCount = 1; m_SumFreeSize = size; @@ -5292,20 +7514,18 @@ void VmaBlockMetadata::Init(VkDeviceSize size) suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; suballoc.hAllocation = VK_NULL_HANDLE; + VMA_ASSERT(size > VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER); m_Suballocations.push_back(suballoc); VmaSuballocationList::iterator suballocItem = m_Suballocations.end(); --suballocItem; m_FreeSuballocationsBySize.push_back(suballocItem); } -bool VmaBlockMetadata::Validate() const +bool VmaBlockMetadata_Generic::Validate() const { - if(m_Suballocations.empty()) - { - return false; - } - - // Expected offset of new suballocation as calculates from previous ones. + VMA_VALIDATE(!m_Suballocations.empty()); + + // Expected offset of new suballocation as calculated from previous ones. VkDeviceSize calculatedOffset = 0; // Expected number of free suballocations as calculated from traversing their list. uint32_t calculatedFreeCount = 0; @@ -5314,32 +7534,19 @@ bool VmaBlockMetadata::Validate() const // Expected number of free suballocations that should be registered in // m_FreeSuballocationsBySize calculated from traversing their list. size_t freeSuballocationsToRegister = 0; - // True if previous visisted suballocation was free. + // True if previous visited suballocation was free. bool prevFree = false; - for(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin(); - suballocItem != m_Suballocations.cend(); - ++suballocItem) + for(const auto& subAlloc : m_Suballocations) { - const VmaSuballocation& subAlloc = *suballocItem; - // Actual offset of this suballocation doesn't match expected one. - if(subAlloc.offset != calculatedOffset) - { - return false; - } + VMA_VALIDATE(subAlloc.offset == calculatedOffset); const bool currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE); // Two adjacent free suballocations are invalid. They should be merged. - if(prevFree && currFree) - { - return false; - } + VMA_VALIDATE(!prevFree || !currFree); - if(currFree != (subAlloc.hAllocation == VK_NULL_HANDLE)) - { - return false; - } + VMA_VALIDATE(currFree == (subAlloc.hAllocation == VK_NULL_HANDLE)); if(currFree) { @@ -5349,17 +7556,17 @@ bool VmaBlockMetadata::Validate() const { ++freeSuballocationsToRegister; } + + // Margin required between allocations - every free space must be at least that large. + VMA_VALIDATE(subAlloc.size >= VMA_DEBUG_MARGIN); } else { - if(subAlloc.hAllocation->GetOffset() != subAlloc.offset) - { - return false; - } - if(subAlloc.hAllocation->GetSize() != subAlloc.size) - { - return false; - } + VMA_VALIDATE(subAlloc.hAllocation->GetOffset() == subAlloc.offset); + VMA_VALIDATE(subAlloc.hAllocation->GetSize() == subAlloc.size); + + // Margin required between allocations - previous allocation must be free. + VMA_VALIDATE(VMA_DEBUG_MARGIN == 0 || prevFree); } calculatedOffset += subAlloc.size; @@ -5368,43 +7575,31 @@ bool VmaBlockMetadata::Validate() const // Number of free suballocations registered in m_FreeSuballocationsBySize doesn't // match expected one. - if(m_FreeSuballocationsBySize.size() != freeSuballocationsToRegister) - { - return false; - } + VMA_VALIDATE(m_FreeSuballocationsBySize.size() == freeSuballocationsToRegister); VkDeviceSize lastSize = 0; for(size_t i = 0; i < m_FreeSuballocationsBySize.size(); ++i) { VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i]; - + // Only free suballocations can be registered in m_FreeSuballocationsBySize. - if(suballocItem->type != VMA_SUBALLOCATION_TYPE_FREE) - { - return false; - } + VMA_VALIDATE(suballocItem->type == VMA_SUBALLOCATION_TYPE_FREE); // They must be sorted by size ascending. - if(suballocItem->size < lastSize) - { - return false; - } + VMA_VALIDATE(suballocItem->size >= lastSize); lastSize = suballocItem->size; } - // Check if totals match calculacted values. - if(!ValidateFreeSuballocationList() || - (calculatedOffset != m_Size) || - (calculatedSumFreeSize != m_SumFreeSize) || - (calculatedFreeCount != m_FreeCount)) - { - return false; - } + // Check if totals match calculated values. + VMA_VALIDATE(ValidateFreeSuballocationList()); + VMA_VALIDATE(calculatedOffset == GetSize()); + VMA_VALIDATE(calculatedSumFreeSize == m_SumFreeSize); + VMA_VALIDATE(calculatedFreeCount == m_FreeCount); return true; } -VkDeviceSize VmaBlockMetadata::GetUnusedRangeSizeMax() const +VkDeviceSize VmaBlockMetadata_Generic::GetUnusedRangeSizeMax() const { if(!m_FreeSuballocationsBySize.empty()) { @@ -5416,32 +7611,29 @@ VkDeviceSize VmaBlockMetadata::GetUnusedRangeSizeMax() const } } -bool VmaBlockMetadata::IsEmpty() const +bool VmaBlockMetadata_Generic::IsEmpty() const { return (m_Suballocations.size() == 1) && (m_FreeCount == 1); } -void VmaBlockMetadata::CalcAllocationStatInfo(VmaStatInfo& outInfo) const +void VmaBlockMetadata_Generic::CalcAllocationStatInfo(VmaStatInfo& outInfo) const { outInfo.blockCount = 1; const uint32_t rangeCount = (uint32_t)m_Suballocations.size(); outInfo.allocationCount = rangeCount - m_FreeCount; outInfo.unusedRangeCount = m_FreeCount; - + outInfo.unusedBytes = m_SumFreeSize; - outInfo.usedBytes = m_Size - outInfo.unusedBytes; + outInfo.usedBytes = GetSize() - outInfo.unusedBytes; outInfo.allocationSizeMin = UINT64_MAX; outInfo.allocationSizeMax = 0; outInfo.unusedRangeSizeMin = UINT64_MAX; outInfo.unusedRangeSizeMax = 0; - for(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin(); - suballocItem != m_Suballocations.cend(); - ++suballocItem) + for(const auto& suballoc : m_Suballocations) { - const VmaSuballocation& suballoc = *suballocItem; if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) { outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); @@ -5455,11 +7647,11 @@ void VmaBlockMetadata::CalcAllocationStatInfo(VmaStatInfo& outInfo) const } } -void VmaBlockMetadata::AddPoolStats(VmaPoolStats& inoutStats) const +void VmaBlockMetadata_Generic::AddPoolStats(VmaPoolStats& inoutStats) const { const uint32_t rangeCount = (uint32_t)m_Suballocations.size(); - inoutStats.size += m_Size; + inoutStats.size += GetSize(); inoutStats.unusedSize += m_SumFreeSize; inoutStats.allocationCount += rangeCount - m_FreeCount; inoutStats.unusedRangeCount += m_FreeCount; @@ -5468,105 +7660,53 @@ void VmaBlockMetadata::AddPoolStats(VmaPoolStats& inoutStats) const #if VMA_STATS_STRING_ENABLED -void VmaBlockMetadata::PrintDetailedMap(class VmaJsonWriter& json) const +void VmaBlockMetadata_Generic::PrintDetailedMap(class VmaJsonWriter& json) const { - json.BeginObject(); + PrintDetailedMap_Begin(json, + m_SumFreeSize, // unusedBytes + m_Suballocations.size() - (size_t)m_FreeCount, // allocationCount + m_FreeCount); // unusedRangeCount - json.WriteString("TotalBytes"); - json.WriteNumber(m_Size); - - json.WriteString("UnusedBytes"); - json.WriteNumber(m_SumFreeSize); - - json.WriteString("Allocations"); - json.WriteNumber((uint64_t)m_Suballocations.size() - m_FreeCount); - - json.WriteString("UnusedRanges"); - json.WriteNumber(m_FreeCount); - - json.WriteString("Suballocations"); - json.BeginArray(); - size_t i = 0; - for(VmaSuballocationList::const_iterator suballocItem = m_Suballocations.cbegin(); - suballocItem != m_Suballocations.cend(); - ++suballocItem, ++i) + for(const auto& suballoc : m_Suballocations) { - json.BeginObject(true); - - json.WriteString("Type"); - json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[suballocItem->type]); - - json.WriteString("Size"); - json.WriteNumber(suballocItem->size); - - json.WriteString("Offset"); - json.WriteNumber(suballocItem->offset); - - if(suballocItem->type != VMA_SUBALLOCATION_TYPE_FREE) + if(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE) { - const void* pUserData = suballocItem->hAllocation->GetUserData(); - if(pUserData != VMA_NULL) - { - json.WriteString("UserData"); - if(suballocItem->hAllocation->IsUserDataString()) - { - json.WriteString((const char*)pUserData); - } - else - { - json.BeginString(); - json.ContinueString_Pointer(pUserData); - json.EndString(); - } - } + PrintDetailedMap_UnusedRange(json, suballoc.offset, suballoc.size); + } + else + { + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); } - - json.EndObject(); } - json.EndArray(); - json.EndObject(); + PrintDetailedMap_End(json); } #endif // #if VMA_STATS_STRING_ENABLED -/* -How many suitable free suballocations to analyze before choosing best one. -- Set to 1 to use First-Fit algorithm - first suitable free suballocation will - be chosen. -- Set to UINT32_MAX to use Best-Fit/Worst-Fit algorithm - all suitable free - suballocations will be analized and best one will be chosen. -- Any other value is also acceptable. -*/ -//static const uint32_t MAX_SUITABLE_SUBALLOCATIONS_TO_CHECK = 8; - -void VmaBlockMetadata::CreateFirstAllocationRequest(VmaAllocationRequest* pAllocationRequest) -{ - VMA_ASSERT(IsEmpty()); - pAllocationRequest->offset = 0; - pAllocationRequest->sumFreeSize = m_SumFreeSize; - pAllocationRequest->sumItemSize = 0; - pAllocationRequest->item = m_Suballocations.begin(); - pAllocationRequest->itemsToMakeLostCount = 0; -} - -bool VmaBlockMetadata::CreateAllocationRequest( +bool VmaBlockMetadata_Generic::CreateAllocationRequest( uint32_t currentFrameIndex, uint32_t frameInUseCount, VkDeviceSize bufferImageGranularity, VkDeviceSize allocSize, VkDeviceSize allocAlignment, + bool upperAddress, VmaSuballocationType allocType, bool canMakeOtherLost, + uint32_t strategy, VmaAllocationRequest* pAllocationRequest) { VMA_ASSERT(allocSize > 0); + VMA_ASSERT(!upperAddress); VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); VMA_ASSERT(pAllocationRequest != VMA_NULL); VMA_HEAVY_ASSERT(Validate()); + pAllocationRequest->type = VmaAllocationRequestType::Normal; + // There is not enough total free space in this block to fullfill the request: Early return. - if(canMakeOtherLost == false && m_SumFreeSize < allocSize) + if(canMakeOtherLost == false && + m_SumFreeSize < allocSize + 2 * VMA_DEBUG_MARGIN) { return false; } @@ -5575,13 +7715,13 @@ bool VmaBlockMetadata::CreateAllocationRequest( const size_t freeSuballocCount = m_FreeSuballocationsBySize.size(); if(freeSuballocCount > 0) { - if(VMA_BEST_FIT) + if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT) { - // Find first free suballocation with size not less than allocSize. + // Find first free suballocation with size not less than allocSize + 2 * VMA_DEBUG_MARGIN. VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess( m_FreeSuballocationsBySize.data(), m_FreeSuballocationsBySize.data() + freeSuballocCount, - allocSize, + allocSize + 2 * VMA_DEBUG_MARGIN, VmaSuballocationItemSizeLess()); size_t index = it - m_FreeSuballocationsBySize.data(); for(; index < freeSuballocCount; ++index) @@ -5605,7 +7745,32 @@ bool VmaBlockMetadata::CreateAllocationRequest( } } } - else + else if(strategy == VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET) + { + for(VmaSuballocationList::iterator it = m_Suballocations.begin(); + it != m_Suballocations.end(); + ++it) + { + if(it->type == VMA_SUBALLOCATION_TYPE_FREE && CheckAllocation( + currentFrameIndex, + frameInUseCount, + bufferImageGranularity, + allocSize, + allocAlignment, + allocType, + it, + false, // canMakeOtherLost + &pAllocationRequest->offset, + &pAllocationRequest->itemsToMakeLostCount, + &pAllocationRequest->sumFreeSize, + &pAllocationRequest->sumItemSize)) + { + pAllocationRequest->item = it; + return true; + } + } + } + else // WORST_FIT, FIRST_FIT { // Search staring from biggest suballocations. for(size_t index = freeSuballocCount; index--; ) @@ -5635,10 +7800,9 @@ bool VmaBlockMetadata::CreateAllocationRequest( { // Brute-force algorithm. TODO: Come up with something better. - pAllocationRequest->sumFreeSize = VK_WHOLE_SIZE; - pAllocationRequest->sumItemSize = VK_WHOLE_SIZE; - + bool found = false; VmaAllocationRequest tmpAllocRequest = {}; + tmpAllocRequest.type = VmaAllocationRequestType::Normal; for(VmaSuballocationList::iterator suballocIt = m_Suballocations.begin(); suballocIt != m_Suballocations.end(); ++suballocIt) @@ -5660,30 +7824,35 @@ bool VmaBlockMetadata::CreateAllocationRequest( &tmpAllocRequest.sumFreeSize, &tmpAllocRequest.sumItemSize)) { - tmpAllocRequest.item = suballocIt; - - if(tmpAllocRequest.CalcCost() < pAllocationRequest->CalcCost()) + if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT) { *pAllocationRequest = tmpAllocRequest; + pAllocationRequest->item = suballocIt; + break; + } + if(!found || tmpAllocRequest.CalcCost() < pAllocationRequest->CalcCost()) + { + *pAllocationRequest = tmpAllocRequest; + pAllocationRequest->item = suballocIt; + found = true; } } } } - if(pAllocationRequest->sumItemSize != VK_WHOLE_SIZE) - { - return true; - } + return found; } return false; } -bool VmaBlockMetadata::MakeRequestedAllocationsLost( +bool VmaBlockMetadata_Generic::MakeRequestedAllocationsLost( uint32_t currentFrameIndex, uint32_t frameInUseCount, VmaAllocationRequest* pAllocationRequest) { + VMA_ASSERT(pAllocationRequest && pAllocationRequest->type == VmaAllocationRequestType::Normal); + while(pAllocationRequest->itemsToMakeLostCount > 0) { if(pAllocationRequest->item->type == VMA_SUBALLOCATION_TYPE_FREE) @@ -5707,11 +7876,11 @@ bool VmaBlockMetadata::MakeRequestedAllocationsLost( VMA_HEAVY_ASSERT(Validate()); VMA_ASSERT(pAllocationRequest->item != m_Suballocations.end()); VMA_ASSERT(pAllocationRequest->item->type == VMA_SUBALLOCATION_TYPE_FREE); - + return true; } -uint32_t VmaBlockMetadata::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) +uint32_t VmaBlockMetadata_Generic::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) { uint32_t lostAllocationCount = 0; for(VmaSuballocationList::iterator it = m_Suballocations.begin(); @@ -5729,12 +7898,35 @@ uint32_t VmaBlockMetadata::MakeAllocationsLost(uint32_t currentFrameIndex, uint3 return lostAllocationCount; } -void VmaBlockMetadata::Alloc( +VkResult VmaBlockMetadata_Generic::CheckCorruption(const void* pBlockData) +{ + for(auto& suballoc : m_Suballocations) + { + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + { + if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN; + } + if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN; + } + } + } + + return VK_SUCCESS; +} + +void VmaBlockMetadata_Generic::Alloc( const VmaAllocationRequest& request, VmaSuballocationType type, VkDeviceSize allocSize, VmaAllocation hAllocation) { + VMA_ASSERT(request.type == VmaAllocationRequestType::Normal); VMA_ASSERT(request.item != m_Suballocations.end()); VmaSuballocation& suballoc = *request.item; // Given suballocation is a free block. @@ -5793,7 +7985,7 @@ void VmaBlockMetadata::Alloc( m_SumFreeSize -= allocSize; } -void VmaBlockMetadata::Free(const VmaAllocation allocation) +void VmaBlockMetadata_Generic::Free(const VmaAllocation allocation) { for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin(); suballocItem != m_Suballocations.end(); @@ -5810,7 +8002,7 @@ void VmaBlockMetadata::Free(const VmaAllocation allocation) VMA_ASSERT(0 && "Not found!"); } -void VmaBlockMetadata::FreeAtOffset(VkDeviceSize offset) +void VmaBlockMetadata_Generic::FreeAtOffset(VkDeviceSize offset) { for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin(); suballocItem != m_Suballocations.end(); @@ -5826,35 +8018,22 @@ void VmaBlockMetadata::FreeAtOffset(VkDeviceSize offset) VMA_ASSERT(0 && "Not found!"); } -bool VmaBlockMetadata::ValidateFreeSuballocationList() const +bool VmaBlockMetadata_Generic::ValidateFreeSuballocationList() const { VkDeviceSize lastSize = 0; for(size_t i = 0, count = m_FreeSuballocationsBySize.size(); i < count; ++i) { const VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i]; - if(it->type != VMA_SUBALLOCATION_TYPE_FREE) - { - VMA_ASSERT(0); - return false; - } - if(it->size < VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - VMA_ASSERT(0); - return false; - } - if(it->size < lastSize) - { - VMA_ASSERT(0); - return false; - } - + VMA_VALIDATE(it->type == VMA_SUBALLOCATION_TYPE_FREE); + VMA_VALIDATE(it->size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER); + VMA_VALIDATE(it->size >= lastSize); lastSize = it->size; } return true; } -bool VmaBlockMetadata::CheckAllocation( +bool VmaBlockMetadata_Generic::CheckAllocation( uint32_t currentFrameIndex, uint32_t frameInUseCount, VkDeviceSize bufferImageGranularity, @@ -5872,7 +8051,7 @@ bool VmaBlockMetadata::CheckAllocation( VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); VMA_ASSERT(suballocItem != m_Suballocations.cend()); VMA_ASSERT(pOffset != VMA_NULL); - + *itemsToMakeLostCount = 0; *pSumFreeSize = 0; *pSumItemSize = 0; @@ -5898,27 +8077,26 @@ bool VmaBlockMetadata::CheckAllocation( } // Remaining size is too small for this request: Early return. - if(m_Size - suballocItem->offset < allocSize) + if(GetSize() - suballocItem->offset < allocSize) { return false; } // Start from offset equal to beginning of this suballocation. *pOffset = suballocItem->offset; - + // Apply VMA_DEBUG_MARGIN at the beginning. - if((VMA_DEBUG_MARGIN > 0) && suballocItem != m_Suballocations.cbegin()) + if(VMA_DEBUG_MARGIN > 0) { *pOffset += VMA_DEBUG_MARGIN; } - + // Apply alignment. - const VkDeviceSize alignment = VMA_MAX(allocAlignment, static_cast(VMA_DEBUG_ALIGNMENT)); - *pOffset = VmaAlignUp(*pOffset, alignment); + *pOffset = VmaAlignUp(*pOffset, allocAlignment); // Check previous suballocations for BufferImageGranularity conflicts. // Make bigger alignment if necessary. - if(bufferImageGranularity > 1) + if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment) { bool bufferImageGranularityConflict = false; VmaSuballocationList::const_iterator prevSuballocItem = suballocItem; @@ -5943,26 +8121,23 @@ bool VmaBlockMetadata::CheckAllocation( *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity); } } - + // Now that we have final *pOffset, check if we are past suballocItem. // If yes, return false - this function should be called for another suballocItem as starting point. if(*pOffset >= suballocItem->offset + suballocItem->size) { return false; } - + // Calculate padding at the beginning based on current offset. const VkDeviceSize paddingBegin = *pOffset - suballocItem->offset; - // Calculate required margin at the end if this is not last suballocation. - VmaSuballocationList::const_iterator next = suballocItem; - ++next; - const VkDeviceSize requiredEndMargin = - (next != m_Suballocations.cend()) ? VMA_DEBUG_MARGIN : 0; + // Calculate required margin at the end. + const VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN; const VkDeviceSize totalSize = paddingBegin + allocSize + requiredEndMargin; // Another early return check. - if(suballocItem->offset + totalSize > m_Size) + if(suballocItem->offset + totalSize > GetSize()) { return false; } @@ -6005,7 +8180,7 @@ bool VmaBlockMetadata::CheckAllocation( // Check next suballocations for BufferImageGranularity conflicts. // If conflict exists, we must mark more allocations lost or fail. - if(bufferImageGranularity > 1) + if(allocSize % bufferImageGranularity || *pOffset % bufferImageGranularity) { VmaSuballocationList::const_iterator nextSuballocItem = lastSuballocItem; ++nextSuballocItem; @@ -6052,20 +8227,19 @@ bool VmaBlockMetadata::CheckAllocation( // Start from offset equal to beginning of this suballocation. *pOffset = suballoc.offset; - + // Apply VMA_DEBUG_MARGIN at the beginning. - if((VMA_DEBUG_MARGIN > 0) && suballocItem != m_Suballocations.cbegin()) + if(VMA_DEBUG_MARGIN > 0) { *pOffset += VMA_DEBUG_MARGIN; } - + // Apply alignment. - const VkDeviceSize alignment = VMA_MAX(allocAlignment, static_cast(VMA_DEBUG_ALIGNMENT)); - *pOffset = VmaAlignUp(*pOffset, alignment); - + *pOffset = VmaAlignUp(*pOffset, allocAlignment); + // Check previous suballocations for BufferImageGranularity conflicts. // Make bigger alignment if necessary. - if(bufferImageGranularity > 1) + if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment) { bool bufferImageGranularityConflict = false; VmaSuballocationList::const_iterator prevSuballocItem = suballocItem; @@ -6090,15 +8264,12 @@ bool VmaBlockMetadata::CheckAllocation( *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity); } } - + // Calculate padding at the beginning based on current offset. const VkDeviceSize paddingBegin = *pOffset - suballoc.offset; - // Calculate required margin at the end if this is not last suballocation. - VmaSuballocationList::const_iterator next = suballocItem; - ++next; - const VkDeviceSize requiredEndMargin = - (next != m_Suballocations.cend()) ? VMA_DEBUG_MARGIN : 0; + // Calculate required margin at the end. + const VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN; // Fail if requested size plus margin before and after is bigger than size of this suballocation. if(paddingBegin + allocSize + requiredEndMargin > suballoc.size) @@ -6108,7 +8279,7 @@ bool VmaBlockMetadata::CheckAllocation( // Check next suballocations for BufferImageGranularity conflicts. // If conflict exists, allocation cannot be made here. - if(bufferImageGranularity > 1) + if(allocSize % bufferImageGranularity || *pOffset % bufferImageGranularity) { VmaSuballocationList::const_iterator nextSuballocItem = suballocItem; ++nextSuballocItem; @@ -6136,11 +8307,11 @@ bool VmaBlockMetadata::CheckAllocation( return true; } -void VmaBlockMetadata::MergeFreeWithNext(VmaSuballocationList::iterator item) +void VmaBlockMetadata_Generic::MergeFreeWithNext(VmaSuballocationList::iterator item) { VMA_ASSERT(item != m_Suballocations.end()); VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); - + VmaSuballocationList::iterator nextItem = item; ++nextItem; VMA_ASSERT(nextItem != m_Suballocations.end()); @@ -6151,13 +8322,13 @@ void VmaBlockMetadata::MergeFreeWithNext(VmaSuballocationList::iterator item) m_Suballocations.erase(nextItem); } -VmaSuballocationList::iterator VmaBlockMetadata::FreeSuballocation(VmaSuballocationList::iterator suballocItem) +VmaSuballocationList::iterator VmaBlockMetadata_Generic::FreeSuballocation(VmaSuballocationList::iterator suballocItem) { // Change this suballocation to be marked as free. VmaSuballocation& suballoc = *suballocItem; suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; suballoc.hAllocation = VK_NULL_HANDLE; - + // Update totals. ++m_FreeCount; m_SumFreeSize += suballoc.size; @@ -6165,7 +8336,7 @@ VmaSuballocationList::iterator VmaBlockMetadata::FreeSuballocation(VmaSuballocat // Merge with previous and/or next suballocation if it's also free. bool mergeWithNext = false; bool mergeWithPrev = false; - + VmaSuballocationList::iterator nextItem = suballocItem; ++nextItem; if((nextItem != m_Suballocations.end()) && (nextItem->type == VMA_SUBALLOCATION_TYPE_FREE)) @@ -6203,7 +8374,7 @@ VmaSuballocationList::iterator VmaBlockMetadata::FreeSuballocation(VmaSuballocat } } -void VmaBlockMetadata::RegisterFreeSuballocation(VmaSuballocationList::iterator item) +void VmaBlockMetadata_Generic::RegisterFreeSuballocation(VmaSuballocationList::iterator item) { VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); VMA_ASSERT(item->size > 0); @@ -6228,7 +8399,7 @@ void VmaBlockMetadata::RegisterFreeSuballocation(VmaSuballocationList::iterator } -void VmaBlockMetadata::UnregisterFreeSuballocation(VmaSuballocationList::iterator item) +void VmaBlockMetadata_Generic::UnregisterFreeSuballocation(VmaSuballocationList::iterator item) { VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); VMA_ASSERT(item->size > 0); @@ -6261,12 +8432,2355 @@ void VmaBlockMetadata::UnregisterFreeSuballocation(VmaSuballocationList::iterato //VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); } +bool VmaBlockMetadata_Generic::IsBufferImageGranularityConflictPossible( + VkDeviceSize bufferImageGranularity, + VmaSuballocationType& inOutPrevSuballocType) const +{ + if(bufferImageGranularity == 1 || IsEmpty()) + { + return false; + } + + VkDeviceSize minAlignment = VK_WHOLE_SIZE; + bool typeConflictFound = false; + for(const auto& suballoc : m_Suballocations) + { + const VmaSuballocationType suballocType = suballoc.type; + if(suballocType != VMA_SUBALLOCATION_TYPE_FREE) + { + minAlignment = VMA_MIN(minAlignment, suballoc.hAllocation->GetAlignment()); + if(VmaIsBufferImageGranularityConflict(inOutPrevSuballocType, suballocType)) + { + typeConflictFound = true; + } + inOutPrevSuballocType = suballocType; + } + } + + return typeConflictFound || minAlignment >= bufferImageGranularity; +} + +//////////////////////////////////////////////////////////////////////////////// +// class VmaBlockMetadata_Linear + +VmaBlockMetadata_Linear::VmaBlockMetadata_Linear(VmaAllocator hAllocator) : + VmaBlockMetadata(hAllocator), + m_SumFreeSize(0), + m_Suballocations0(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), + m_Suballocations1(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), + m_1stVectorIndex(0), + m_2ndVectorMode(SECOND_VECTOR_EMPTY), + m_1stNullItemsBeginCount(0), + m_1stNullItemsMiddleCount(0), + m_2ndNullItemsCount(0) +{ +} + +VmaBlockMetadata_Linear::~VmaBlockMetadata_Linear() +{ +} + +void VmaBlockMetadata_Linear::Init(VkDeviceSize size) +{ + VmaBlockMetadata::Init(size); + m_SumFreeSize = size; +} + +bool VmaBlockMetadata_Linear::Validate() const +{ + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + VMA_VALIDATE(suballocations2nd.empty() == (m_2ndVectorMode == SECOND_VECTOR_EMPTY)); + VMA_VALIDATE(!suballocations1st.empty() || + suballocations2nd.empty() || + m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER); + + if(!suballocations1st.empty()) + { + // Null item at the beginning should be accounted into m_1stNullItemsBeginCount. + VMA_VALIDATE(suballocations1st[m_1stNullItemsBeginCount].hAllocation != VK_NULL_HANDLE); + // Null item at the end should be just pop_back(). + VMA_VALIDATE(suballocations1st.back().hAllocation != VK_NULL_HANDLE); + } + if(!suballocations2nd.empty()) + { + // Null item at the end should be just pop_back(). + VMA_VALIDATE(suballocations2nd.back().hAllocation != VK_NULL_HANDLE); + } + + VMA_VALIDATE(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount <= suballocations1st.size()); + VMA_VALIDATE(m_2ndNullItemsCount <= suballocations2nd.size()); + + VkDeviceSize sumUsedSize = 0; + const size_t suballoc1stCount = suballocations1st.size(); + VkDeviceSize offset = VMA_DEBUG_MARGIN; + + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const size_t suballoc2ndCount = suballocations2nd.size(); + size_t nullItem2ndCount = 0; + for(size_t i = 0; i < suballoc2ndCount; ++i) + { + const VmaSuballocation& suballoc = suballocations2nd[i]; + const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE)); + VMA_VALIDATE(suballoc.offset >= offset); + + if(!currFree) + { + VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset); + VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size); + sumUsedSize += suballoc.size; + } + else + { + ++nullItem2ndCount; + } + + offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN; + } + + VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount); + } + + for(size_t i = 0; i < m_1stNullItemsBeginCount; ++i) + { + const VmaSuballocation& suballoc = suballocations1st[i]; + VMA_VALIDATE(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE && + suballoc.hAllocation == VK_NULL_HANDLE); + } + + size_t nullItem1stCount = m_1stNullItemsBeginCount; + + for(size_t i = m_1stNullItemsBeginCount; i < suballoc1stCount; ++i) + { + const VmaSuballocation& suballoc = suballocations1st[i]; + const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE)); + VMA_VALIDATE(suballoc.offset >= offset); + VMA_VALIDATE(i >= m_1stNullItemsBeginCount || currFree); + + if(!currFree) + { + VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset); + VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size); + sumUsedSize += suballoc.size; + } + else + { + ++nullItem1stCount; + } + + offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN; + } + VMA_VALIDATE(nullItem1stCount == m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount); + + if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + const size_t suballoc2ndCount = suballocations2nd.size(); + size_t nullItem2ndCount = 0; + for(size_t i = suballoc2ndCount; i--; ) + { + const VmaSuballocation& suballoc = suballocations2nd[i]; + const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE)); + VMA_VALIDATE(suballoc.offset >= offset); + + if(!currFree) + { + VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset); + VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size); + sumUsedSize += suballoc.size; + } + else + { + ++nullItem2ndCount; + } + + offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN; + } + + VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount); + } + + VMA_VALIDATE(offset <= GetSize()); + VMA_VALIDATE(m_SumFreeSize == GetSize() - sumUsedSize); + + return true; +} + +size_t VmaBlockMetadata_Linear::GetAllocationCount() const +{ + return AccessSuballocations1st().size() - (m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount) + + AccessSuballocations2nd().size() - m_2ndNullItemsCount; +} + +VkDeviceSize VmaBlockMetadata_Linear::GetUnusedRangeSizeMax() const +{ + const VkDeviceSize size = GetSize(); + + /* + We don't consider gaps inside allocation vectors with freed allocations because + they are not suitable for reuse in linear allocator. We consider only space that + is available for new allocations. + */ + if(IsEmpty()) + { + return size; + } + + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + + switch(m_2ndVectorMode) + { + case SECOND_VECTOR_EMPTY: + /* + Available space is after end of 1st, as well as before beginning of 1st (which + would make it a ring buffer). + */ + { + const size_t suballocations1stCount = suballocations1st.size(); + VMA_ASSERT(suballocations1stCount > m_1stNullItemsBeginCount); + const VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount]; + const VmaSuballocation& lastSuballoc = suballocations1st[suballocations1stCount - 1]; + return VMA_MAX( + firstSuballoc.offset, + size - (lastSuballoc.offset + lastSuballoc.size)); + } + break; + + case SECOND_VECTOR_RING_BUFFER: + /* + Available space is only between end of 2nd and beginning of 1st. + */ + { + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const VmaSuballocation& lastSuballoc2nd = suballocations2nd.back(); + const VmaSuballocation& firstSuballoc1st = suballocations1st[m_1stNullItemsBeginCount]; + return firstSuballoc1st.offset - (lastSuballoc2nd.offset + lastSuballoc2nd.size); + } + break; + + case SECOND_VECTOR_DOUBLE_STACK: + /* + Available space is only between end of 1st and top of 2nd. + */ + { + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const VmaSuballocation& topSuballoc2nd = suballocations2nd.back(); + const VmaSuballocation& lastSuballoc1st = suballocations1st.back(); + return topSuballoc2nd.offset - (lastSuballoc1st.offset + lastSuballoc1st.size); + } + break; + + default: + VMA_ASSERT(0); + return 0; + } +} + +void VmaBlockMetadata_Linear::CalcAllocationStatInfo(VmaStatInfo& outInfo) const +{ + const VkDeviceSize size = GetSize(); + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const size_t suballoc1stCount = suballocations1st.size(); + const size_t suballoc2ndCount = suballocations2nd.size(); + + outInfo.blockCount = 1; + outInfo.allocationCount = (uint32_t)GetAllocationCount(); + outInfo.unusedRangeCount = 0; + outInfo.usedBytes = 0; + outInfo.allocationSizeMin = UINT64_MAX; + outInfo.allocationSizeMax = 0; + outInfo.unusedRangeSizeMin = UINT64_MAX; + outInfo.unusedRangeSizeMax = 0; + + VkDeviceSize lastOffset = 0; + + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = 0; + while(lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while(nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusedRangeSize; + outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); + outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + outInfo.usedBytes += suballoc.size; + outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); + outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + if(lastOffset < freeSpace2ndTo1stEnd) + { + const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusedRangeSize; + outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); + outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; + const VkDeviceSize freeSpace1stTo2ndEnd = + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; + while(lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while(nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if(nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusedRangeSize; + outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); + outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + outInfo.usedBytes += suballoc.size; + outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); + outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + if(lastOffset < freeSpace1stTo2ndEnd) + { + const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusedRangeSize; + outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); + outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while(lastOffset < size) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while(nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusedRangeSize; + outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); + outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + outInfo.usedBytes += suballoc.size; + outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); + outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + // There is free space from lastOffset to size. + if(lastOffset < size) + { + const VkDeviceSize unusedRangeSize = size - lastOffset; + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusedRangeSize; + outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); + outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); + } + + // End of loop. + lastOffset = size; + } + } + } + + outInfo.unusedBytes = size - outInfo.usedBytes; +} + +void VmaBlockMetadata_Linear::AddPoolStats(VmaPoolStats& inoutStats) const +{ + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const VkDeviceSize size = GetSize(); + const size_t suballoc1stCount = suballocations1st.size(); + const size_t suballoc2ndCount = suballocations2nd.size(); + + inoutStats.size += size; + + VkDeviceSize lastOffset = 0; + + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = m_1stNullItemsBeginCount; + while(lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while(nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + inoutStats.unusedSize += unusedRangeSize; + ++inoutStats.unusedRangeCount; + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++inoutStats.allocationCount; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + if(lastOffset < freeSpace2ndTo1stEnd) + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; + inoutStats.unusedSize += unusedRangeSize; + ++inoutStats.unusedRangeCount; + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; + const VkDeviceSize freeSpace1stTo2ndEnd = + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; + while(lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while(nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if(nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + inoutStats.unusedSize += unusedRangeSize; + ++inoutStats.unusedRangeCount; + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++inoutStats.allocationCount; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + if(lastOffset < freeSpace1stTo2ndEnd) + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; + inoutStats.unusedSize += unusedRangeSize; + ++inoutStats.unusedRangeCount; + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while(lastOffset < size) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while(nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + inoutStats.unusedSize += unusedRangeSize; + ++inoutStats.unusedRangeCount; + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++inoutStats.allocationCount; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + if(lastOffset < size) + { + // There is free space from lastOffset to size. + const VkDeviceSize unusedRangeSize = size - lastOffset; + inoutStats.unusedSize += unusedRangeSize; + ++inoutStats.unusedRangeCount; + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); + } + + // End of loop. + lastOffset = size; + } + } + } +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json) const +{ + const VkDeviceSize size = GetSize(); + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const size_t suballoc1stCount = suballocations1st.size(); + const size_t suballoc2ndCount = suballocations2nd.size(); + + // FIRST PASS + + size_t unusedRangeCount = 0; + VkDeviceSize usedBytes = 0; + + VkDeviceSize lastOffset = 0; + + size_t alloc2ndCount = 0; + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = 0; + while(lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while(nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + ++unusedRangeCount; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++alloc2ndCount; + usedBytes += suballoc.size; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + if(lastOffset < freeSpace2ndTo1stEnd) + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + ++unusedRangeCount; + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; + size_t alloc1stCount = 0; + const VkDeviceSize freeSpace1stTo2ndEnd = + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; + while(lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while(nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if(nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + ++unusedRangeCount; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++alloc1stCount; + usedBytes += suballoc.size; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + if(lastOffset < size) + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + ++unusedRangeCount; + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while(lastOffset < size) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while(nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + ++unusedRangeCount; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++alloc2ndCount; + usedBytes += suballoc.size; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + if(lastOffset < size) + { + // There is free space from lastOffset to size. + ++unusedRangeCount; + } + + // End of loop. + lastOffset = size; + } + } + } + + const VkDeviceSize unusedBytes = size - usedBytes; + PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount); + + // SECOND PASS + lastOffset = 0; + + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = 0; + while(lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while(nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + if(lastOffset < freeSpace2ndTo1stEnd) + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + nextAlloc1stIndex = m_1stNullItemsBeginCount; + while(lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while(nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if(nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + if(lastOffset < freeSpace1stTo2ndEnd) + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while(lastOffset < size) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while(nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if(nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if(lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + if(lastOffset < size) + { + // There is free space from lastOffset to size. + const VkDeviceSize unusedRangeSize = size - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // End of loop. + lastOffset = size; + } + } + } + + PrintDetailedMap_End(json); +} +#endif // #if VMA_STATS_STRING_ENABLED + +bool VmaBlockMetadata_Linear::CreateAllocationRequest( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + VMA_ASSERT(allocSize > 0); + VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); + VMA_ASSERT(pAllocationRequest != VMA_NULL); + VMA_HEAVY_ASSERT(Validate()); + return upperAddress ? + CreateAllocationRequest_UpperAddress( + currentFrameIndex, frameInUseCount, bufferImageGranularity, + allocSize, allocAlignment, allocType, canMakeOtherLost, strategy, pAllocationRequest) : + CreateAllocationRequest_LowerAddress( + currentFrameIndex, frameInUseCount, bufferImageGranularity, + allocSize, allocAlignment, allocType, canMakeOtherLost, strategy, pAllocationRequest); +} + +bool VmaBlockMetadata_Linear::CreateAllocationRequest_UpperAddress( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + const VkDeviceSize size = GetSize(); + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + VMA_ASSERT(0 && "Trying to use pool with linear algorithm as double stack, while it is already being used as ring buffer."); + return false; + } + + // Try to allocate before 2nd.back(), or end of block if 2nd.empty(). + if(allocSize > size) + { + return false; + } + VkDeviceSize resultBaseOffset = size - allocSize; + if(!suballocations2nd.empty()) + { + const VmaSuballocation& lastSuballoc = suballocations2nd.back(); + resultBaseOffset = lastSuballoc.offset - allocSize; + if(allocSize > lastSuballoc.offset) + { + return false; + } + } + + // Start from offset equal to end of free space. + VkDeviceSize resultOffset = resultBaseOffset; + + // Apply VMA_DEBUG_MARGIN at the end. + if(VMA_DEBUG_MARGIN > 0) + { + if(resultOffset < VMA_DEBUG_MARGIN) + { + return false; + } + resultOffset -= VMA_DEBUG_MARGIN; + } + + // Apply alignment. + resultOffset = VmaAlignDown(resultOffset, allocAlignment); + + // Check next suballocations from 2nd for BufferImageGranularity conflicts. + // Make bigger alignment if necessary. + if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty()) + { + bool bufferImageGranularityConflict = false; + for(size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; ) + { + const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex]; + if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) + { + if(VmaIsBufferImageGranularityConflict(nextSuballoc.type, allocType)) + { + bufferImageGranularityConflict = true; + break; + } + } + else + // Already on previous page. + break; + } + if(bufferImageGranularityConflict) + { + resultOffset = VmaAlignDown(resultOffset, bufferImageGranularity); + } + } + + // There is enough free space. + const VkDeviceSize endOf1st = !suballocations1st.empty() ? + suballocations1st.back().offset + suballocations1st.back().size : + 0; + if(endOf1st + VMA_DEBUG_MARGIN <= resultOffset) + { + // Check previous suballocations for BufferImageGranularity conflicts. + // If conflict exists, allocation cannot be made here. + if(bufferImageGranularity > 1) + { + for(size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; ) + { + const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex]; + if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) + { + if(VmaIsBufferImageGranularityConflict(allocType, prevSuballoc.type)) + { + return false; + } + } + else + { + // Already on next page. + break; + } + } + } + + // All tests passed: Success. + pAllocationRequest->offset = resultOffset; + pAllocationRequest->sumFreeSize = resultBaseOffset + allocSize - endOf1st; + pAllocationRequest->sumItemSize = 0; + // pAllocationRequest->item unused. + pAllocationRequest->itemsToMakeLostCount = 0; + pAllocationRequest->type = VmaAllocationRequestType::UpperAddress; + return true; + } + + return false; +} + +bool VmaBlockMetadata_Linear::CreateAllocationRequest_LowerAddress( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + const VkDeviceSize size = GetSize(); + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + if(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + // Try to allocate at the end of 1st vector. + + VkDeviceSize resultBaseOffset = 0; + if(!suballocations1st.empty()) + { + const VmaSuballocation& lastSuballoc = suballocations1st.back(); + resultBaseOffset = lastSuballoc.offset + lastSuballoc.size; + } + + // Start from offset equal to beginning of free space. + VkDeviceSize resultOffset = resultBaseOffset; + + // Apply VMA_DEBUG_MARGIN at the beginning. + if(VMA_DEBUG_MARGIN > 0) + { + resultOffset += VMA_DEBUG_MARGIN; + } + + // Apply alignment. + resultOffset = VmaAlignUp(resultOffset, allocAlignment); + + // Check previous suballocations for BufferImageGranularity conflicts. + // Make bigger alignment if necessary. + if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations1st.empty()) + { + bool bufferImageGranularityConflict = false; + for(size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; ) + { + const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex]; + if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) + { + if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) + { + bufferImageGranularityConflict = true; + break; + } + } + else + // Already on previous page. + break; + } + if(bufferImageGranularityConflict) + { + resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity); + } + } + + const VkDeviceSize freeSpaceEnd = m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? + suballocations2nd.back().offset : size; + + // There is enough free space at the end after alignment. + if(resultOffset + allocSize + VMA_DEBUG_MARGIN <= freeSpaceEnd) + { + // Check next suballocations for BufferImageGranularity conflicts. + // If conflict exists, allocation cannot be made here. + if((allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) && m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + for(size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; ) + { + const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex]; + if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) + { + if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) + { + return false; + } + } + else + { + // Already on previous page. + break; + } + } + } + + // All tests passed: Success. + pAllocationRequest->offset = resultOffset; + pAllocationRequest->sumFreeSize = freeSpaceEnd - resultBaseOffset; + pAllocationRequest->sumItemSize = 0; + // pAllocationRequest->item, customData unused. + pAllocationRequest->type = VmaAllocationRequestType::EndOf1st; + pAllocationRequest->itemsToMakeLostCount = 0; + return true; + } + } + + // Wrap-around to end of 2nd vector. Try to allocate there, watching for the + // beginning of 1st vector as the end of free space. + if(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + VMA_ASSERT(!suballocations1st.empty()); + + VkDeviceSize resultBaseOffset = 0; + if(!suballocations2nd.empty()) + { + const VmaSuballocation& lastSuballoc = suballocations2nd.back(); + resultBaseOffset = lastSuballoc.offset + lastSuballoc.size; + } + + // Start from offset equal to beginning of free space. + VkDeviceSize resultOffset = resultBaseOffset; + + // Apply VMA_DEBUG_MARGIN at the beginning. + if(VMA_DEBUG_MARGIN > 0) + { + resultOffset += VMA_DEBUG_MARGIN; + } + + // Apply alignment. + resultOffset = VmaAlignUp(resultOffset, allocAlignment); + + // Check previous suballocations for BufferImageGranularity conflicts. + // Make bigger alignment if necessary. + if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty()) + { + bool bufferImageGranularityConflict = false; + for(size_t prevSuballocIndex = suballocations2nd.size(); prevSuballocIndex--; ) + { + const VmaSuballocation& prevSuballoc = suballocations2nd[prevSuballocIndex]; + if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) + { + if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) + { + bufferImageGranularityConflict = true; + break; + } + } + else + // Already on previous page. + break; + } + if(bufferImageGranularityConflict) + { + resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity); + } + } + + pAllocationRequest->itemsToMakeLostCount = 0; + pAllocationRequest->sumItemSize = 0; + size_t index1st = m_1stNullItemsBeginCount; + + if(canMakeOtherLost) + { + while(index1st < suballocations1st.size() && + resultOffset + allocSize + VMA_DEBUG_MARGIN > suballocations1st[index1st].offset) + { + // Next colliding allocation at the beginning of 1st vector found. Try to make it lost. + const VmaSuballocation& suballoc = suballocations1st[index1st]; + if(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE) + { + // No problem. + } + else + { + VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE); + if(suballoc.hAllocation->CanBecomeLost() && + suballoc.hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex) + { + ++pAllocationRequest->itemsToMakeLostCount; + pAllocationRequest->sumItemSize += suballoc.size; + } + else + { + return false; + } + } + ++index1st; + } + + // Check next suballocations for BufferImageGranularity conflicts. + // If conflict exists, we must mark more allocations lost or fail. + if(allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) + { + while(index1st < suballocations1st.size()) + { + const VmaSuballocation& suballoc = suballocations1st[index1st]; + if(VmaBlocksOnSamePage(resultOffset, allocSize, suballoc.offset, bufferImageGranularity)) + { + if(suballoc.hAllocation != VK_NULL_HANDLE) + { + // Not checking actual VmaIsBufferImageGranularityConflict(allocType, suballoc.type). + if(suballoc.hAllocation->CanBecomeLost() && + suballoc.hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex) + { + ++pAllocationRequest->itemsToMakeLostCount; + pAllocationRequest->sumItemSize += suballoc.size; + } + else + { + return false; + } + } + } + else + { + // Already on next page. + break; + } + ++index1st; + } + } + + // Special case: There is not enough room at the end for this allocation, even after making all from the 1st lost. + if(index1st == suballocations1st.size() && + resultOffset + allocSize + VMA_DEBUG_MARGIN > size) + { + // TODO: This is a known bug that it's not yet implemented and the allocation is failing. + VMA_DEBUG_LOG("Unsupported special case in custom pool with linear allocation algorithm used as ring buffer with allocations that can be lost."); + } + } + + // There is enough free space at the end after alignment. + if((index1st == suballocations1st.size() && resultOffset + allocSize + VMA_DEBUG_MARGIN <= size) || + (index1st < suballocations1st.size() && resultOffset + allocSize + VMA_DEBUG_MARGIN <= suballocations1st[index1st].offset)) + { + // Check next suballocations for BufferImageGranularity conflicts. + // If conflict exists, allocation cannot be made here. + if(allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) + { + for(size_t nextSuballocIndex = index1st; + nextSuballocIndex < suballocations1st.size(); + nextSuballocIndex++) + { + const VmaSuballocation& nextSuballoc = suballocations1st[nextSuballocIndex]; + if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) + { + if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) + { + return false; + } + } + else + { + // Already on next page. + break; + } + } + } + + // All tests passed: Success. + pAllocationRequest->offset = resultOffset; + pAllocationRequest->sumFreeSize = + (index1st < suballocations1st.size() ? suballocations1st[index1st].offset : size) + - resultBaseOffset + - pAllocationRequest->sumItemSize; + pAllocationRequest->type = VmaAllocationRequestType::EndOf2nd; + // pAllocationRequest->item, customData unused. + return true; + } + } + + return false; +} + +bool VmaBlockMetadata_Linear::MakeRequestedAllocationsLost( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VmaAllocationRequest* pAllocationRequest) +{ + if(pAllocationRequest->itemsToMakeLostCount == 0) + { + return true; + } + + VMA_ASSERT(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER); + + // We always start from 1st. + SuballocationVectorType* suballocations = &AccessSuballocations1st(); + size_t index = m_1stNullItemsBeginCount; + size_t madeLostCount = 0; + while(madeLostCount < pAllocationRequest->itemsToMakeLostCount) + { + if(index == suballocations->size()) + { + index = 0; + // If we get to the end of 1st, we wrap around to beginning of 2nd of 1st. + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + suballocations = &AccessSuballocations2nd(); + } + // else: m_2ndVectorMode == SECOND_VECTOR_EMPTY: + // suballocations continues pointing at AccessSuballocations1st(). + VMA_ASSERT(!suballocations->empty()); + } + VmaSuballocation& suballoc = (*suballocations)[index]; + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + { + VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE); + VMA_ASSERT(suballoc.hAllocation->CanBecomeLost()); + if(suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) + { + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + suballoc.hAllocation = VK_NULL_HANDLE; + m_SumFreeSize += suballoc.size; + if(suballocations == &AccessSuballocations1st()) + { + ++m_1stNullItemsMiddleCount; + } + else + { + ++m_2ndNullItemsCount; + } + ++madeLostCount; + } + else + { + return false; + } + } + ++index; + } + + CleanupAfterFree(); + //VMA_HEAVY_ASSERT(Validate()); // Already called by CleanupAfterFree(). + + return true; +} + +uint32_t VmaBlockMetadata_Linear::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) +{ + uint32_t lostAllocationCount = 0; + + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + for(size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i) + { + VmaSuballocation& suballoc = suballocations1st[i]; + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE && + suballoc.hAllocation->CanBecomeLost() && + suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) + { + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + suballoc.hAllocation = VK_NULL_HANDLE; + ++m_1stNullItemsMiddleCount; + m_SumFreeSize += suballoc.size; + ++lostAllocationCount; + } + } + + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + for(size_t i = 0, count = suballocations2nd.size(); i < count; ++i) + { + VmaSuballocation& suballoc = suballocations2nd[i]; + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE && + suballoc.hAllocation->CanBecomeLost() && + suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) + { + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + suballoc.hAllocation = VK_NULL_HANDLE; + ++m_2ndNullItemsCount; + m_SumFreeSize += suballoc.size; + ++lostAllocationCount; + } + } + + if(lostAllocationCount) + { + CleanupAfterFree(); + } + + return lostAllocationCount; +} + +VkResult VmaBlockMetadata_Linear::CheckCorruption(const void* pBlockData) +{ + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + for(size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i) + { + const VmaSuballocation& suballoc = suballocations1st[i]; + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + { + if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN; + } + if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN; + } + } + } + + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + for(size_t i = 0, count = suballocations2nd.size(); i < count; ++i) + { + const VmaSuballocation& suballoc = suballocations2nd[i]; + if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + { + if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN; + } + if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN; + } + } + } + + return VK_SUCCESS; +} + +void VmaBlockMetadata_Linear::Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + VkDeviceSize allocSize, + VmaAllocation hAllocation) +{ + const VmaSuballocation newSuballoc = { request.offset, allocSize, hAllocation, type }; + + switch(request.type) + { + case VmaAllocationRequestType::UpperAddress: + { + VMA_ASSERT(m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER && + "CRITICAL ERROR: Trying to use linear allocator as double stack while it was already used as ring buffer."); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + suballocations2nd.push_back(newSuballoc); + m_2ndVectorMode = SECOND_VECTOR_DOUBLE_STACK; + } + break; + case VmaAllocationRequestType::EndOf1st: + { + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + + VMA_ASSERT(suballocations1st.empty() || + request.offset >= suballocations1st.back().offset + suballocations1st.back().size); + // Check if it fits before the end of the block. + VMA_ASSERT(request.offset + allocSize <= GetSize()); + + suballocations1st.push_back(newSuballoc); + } + break; + case VmaAllocationRequestType::EndOf2nd: + { + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + // New allocation at the end of 2-part ring buffer, so before first allocation from 1st vector. + VMA_ASSERT(!suballocations1st.empty() && + request.offset + allocSize <= suballocations1st[m_1stNullItemsBeginCount].offset); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + switch(m_2ndVectorMode) + { + case SECOND_VECTOR_EMPTY: + // First allocation from second part ring buffer. + VMA_ASSERT(suballocations2nd.empty()); + m_2ndVectorMode = SECOND_VECTOR_RING_BUFFER; + break; + case SECOND_VECTOR_RING_BUFFER: + // 2-part ring buffer is already started. + VMA_ASSERT(!suballocations2nd.empty()); + break; + case SECOND_VECTOR_DOUBLE_STACK: + VMA_ASSERT(0 && "CRITICAL ERROR: Trying to use linear allocator as ring buffer while it was already used as double stack."); + break; + default: + VMA_ASSERT(0); + } + + suballocations2nd.push_back(newSuballoc); + } + break; + default: + VMA_ASSERT(0 && "CRITICAL INTERNAL ERROR."); + } + + m_SumFreeSize -= newSuballoc.size; +} + +void VmaBlockMetadata_Linear::Free(const VmaAllocation allocation) +{ + FreeAtOffset(allocation->GetOffset()); +} + +void VmaBlockMetadata_Linear::FreeAtOffset(VkDeviceSize offset) +{ + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + if(!suballocations1st.empty()) + { + // First allocation: Mark it as next empty at the beginning. + VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount]; + if(firstSuballoc.offset == offset) + { + firstSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + firstSuballoc.hAllocation = VK_NULL_HANDLE; + m_SumFreeSize += firstSuballoc.size; + ++m_1stNullItemsBeginCount; + CleanupAfterFree(); + return; + } + } + + // Last allocation in 2-part ring buffer or top of upper stack (same logic). + if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER || + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + VmaSuballocation& lastSuballoc = suballocations2nd.back(); + if(lastSuballoc.offset == offset) + { + m_SumFreeSize += lastSuballoc.size; + suballocations2nd.pop_back(); + CleanupAfterFree(); + return; + } + } + // Last allocation in 1st vector. + else if(m_2ndVectorMode == SECOND_VECTOR_EMPTY) + { + VmaSuballocation& lastSuballoc = suballocations1st.back(); + if(lastSuballoc.offset == offset) + { + m_SumFreeSize += lastSuballoc.size; + suballocations1st.pop_back(); + CleanupAfterFree(); + return; + } + } + + // Item from the middle of 1st vector. + { + VmaSuballocation refSuballoc; + refSuballoc.offset = offset; + // Rest of members stays uninitialized intentionally for better performance. + SuballocationVectorType::iterator it = VmaBinaryFindSorted( + suballocations1st.begin() + m_1stNullItemsBeginCount, + suballocations1st.end(), + refSuballoc, + VmaSuballocationOffsetLess()); + if(it != suballocations1st.end()) + { + it->type = VMA_SUBALLOCATION_TYPE_FREE; + it->hAllocation = VK_NULL_HANDLE; + ++m_1stNullItemsMiddleCount; + m_SumFreeSize += it->size; + CleanupAfterFree(); + return; + } + } + + if(m_2ndVectorMode != SECOND_VECTOR_EMPTY) + { + // Item from the middle of 2nd vector. + VmaSuballocation refSuballoc; + refSuballoc.offset = offset; + // Rest of members stays uninitialized intentionally for better performance. + SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ? + VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetLess()) : + VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetGreater()); + if(it != suballocations2nd.end()) + { + it->type = VMA_SUBALLOCATION_TYPE_FREE; + it->hAllocation = VK_NULL_HANDLE; + ++m_2ndNullItemsCount; + m_SumFreeSize += it->size; + CleanupAfterFree(); + return; + } + } + + VMA_ASSERT(0 && "Allocation to free not found in linear allocator!"); +} + +bool VmaBlockMetadata_Linear::ShouldCompact1st() const +{ + const size_t nullItemCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount; + const size_t suballocCount = AccessSuballocations1st().size(); + return suballocCount > 32 && nullItemCount * 2 >= (suballocCount - nullItemCount) * 3; +} + +void VmaBlockMetadata_Linear::CleanupAfterFree() +{ + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + if(IsEmpty()) + { + suballocations1st.clear(); + suballocations2nd.clear(); + m_1stNullItemsBeginCount = 0; + m_1stNullItemsMiddleCount = 0; + m_2ndNullItemsCount = 0; + m_2ndVectorMode = SECOND_VECTOR_EMPTY; + } + else + { + const size_t suballoc1stCount = suballocations1st.size(); + const size_t nullItem1stCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount; + VMA_ASSERT(nullItem1stCount <= suballoc1stCount); + + // Find more null items at the beginning of 1st vector. + while(m_1stNullItemsBeginCount < suballoc1stCount && + suballocations1st[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE) + { + ++m_1stNullItemsBeginCount; + --m_1stNullItemsMiddleCount; + } + + // Find more null items at the end of 1st vector. + while(m_1stNullItemsMiddleCount > 0 && + suballocations1st.back().hAllocation == VK_NULL_HANDLE) + { + --m_1stNullItemsMiddleCount; + suballocations1st.pop_back(); + } + + // Find more null items at the end of 2nd vector. + while(m_2ndNullItemsCount > 0 && + suballocations2nd.back().hAllocation == VK_NULL_HANDLE) + { + --m_2ndNullItemsCount; + suballocations2nd.pop_back(); + } + + // Find more null items at the beginning of 2nd vector. + while(m_2ndNullItemsCount > 0 && + suballocations2nd[0].hAllocation == VK_NULL_HANDLE) + { + --m_2ndNullItemsCount; + VmaVectorRemove(suballocations2nd, 0); + } + + if(ShouldCompact1st()) + { + const size_t nonNullItemCount = suballoc1stCount - nullItem1stCount; + size_t srcIndex = m_1stNullItemsBeginCount; + for(size_t dstIndex = 0; dstIndex < nonNullItemCount; ++dstIndex) + { + while(suballocations1st[srcIndex].hAllocation == VK_NULL_HANDLE) + { + ++srcIndex; + } + if(dstIndex != srcIndex) + { + suballocations1st[dstIndex] = suballocations1st[srcIndex]; + } + ++srcIndex; + } + suballocations1st.resize(nonNullItemCount); + m_1stNullItemsBeginCount = 0; + m_1stNullItemsMiddleCount = 0; + } + + // 2nd vector became empty. + if(suballocations2nd.empty()) + { + m_2ndVectorMode = SECOND_VECTOR_EMPTY; + } + + // 1st vector became empty. + if(suballocations1st.size() - m_1stNullItemsBeginCount == 0) + { + suballocations1st.clear(); + m_1stNullItemsBeginCount = 0; + + if(!suballocations2nd.empty() && m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + // Swap 1st with 2nd. Now 2nd is empty. + m_2ndVectorMode = SECOND_VECTOR_EMPTY; + m_1stNullItemsMiddleCount = m_2ndNullItemsCount; + while(m_1stNullItemsBeginCount < suballocations2nd.size() && + suballocations2nd[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE) + { + ++m_1stNullItemsBeginCount; + --m_1stNullItemsMiddleCount; + } + m_2ndNullItemsCount = 0; + m_1stVectorIndex ^= 1; + } + } + } + + VMA_HEAVY_ASSERT(Validate()); +} + + +//////////////////////////////////////////////////////////////////////////////// +// class VmaBlockMetadata_Buddy + +VmaBlockMetadata_Buddy::VmaBlockMetadata_Buddy(VmaAllocator hAllocator) : + VmaBlockMetadata(hAllocator), + m_Root(VMA_NULL), + m_AllocationCount(0), + m_FreeCount(1), + m_SumFreeSize(0) +{ + memset(m_FreeList, 0, sizeof(m_FreeList)); +} + +VmaBlockMetadata_Buddy::~VmaBlockMetadata_Buddy() +{ + DeleteNode(m_Root); +} + +void VmaBlockMetadata_Buddy::Init(VkDeviceSize size) +{ + VmaBlockMetadata::Init(size); + + m_UsableSize = VmaPrevPow2(size); + m_SumFreeSize = m_UsableSize; + + // Calculate m_LevelCount. + m_LevelCount = 1; + while(m_LevelCount < MAX_LEVELS && + LevelToNodeSize(m_LevelCount) >= MIN_NODE_SIZE) + { + ++m_LevelCount; + } + + Node* rootNode = vma_new(GetAllocationCallbacks(), Node)(); + rootNode->offset = 0; + rootNode->type = Node::TYPE_FREE; + rootNode->parent = VMA_NULL; + rootNode->buddy = VMA_NULL; + + m_Root = rootNode; + AddToFreeListFront(0, rootNode); +} + +bool VmaBlockMetadata_Buddy::Validate() const +{ + // Validate tree. + ValidationContext ctx; + if(!ValidateNode(ctx, VMA_NULL, m_Root, 0, LevelToNodeSize(0))) + { + VMA_VALIDATE(false && "ValidateNode failed."); + } + VMA_VALIDATE(m_AllocationCount == ctx.calculatedAllocationCount); + VMA_VALIDATE(m_SumFreeSize == ctx.calculatedSumFreeSize); + + // Validate free node lists. + for(uint32_t level = 0; level < m_LevelCount; ++level) + { + VMA_VALIDATE(m_FreeList[level].front == VMA_NULL || + m_FreeList[level].front->free.prev == VMA_NULL); + + for(Node* node = m_FreeList[level].front; + node != VMA_NULL; + node = node->free.next) + { + VMA_VALIDATE(node->type == Node::TYPE_FREE); + + if(node->free.next == VMA_NULL) + { + VMA_VALIDATE(m_FreeList[level].back == node); + } + else + { + VMA_VALIDATE(node->free.next->free.prev == node); + } + } + } + + // Validate that free lists ar higher levels are empty. + for(uint32_t level = m_LevelCount; level < MAX_LEVELS; ++level) + { + VMA_VALIDATE(m_FreeList[level].front == VMA_NULL && m_FreeList[level].back == VMA_NULL); + } + + return true; +} + +VkDeviceSize VmaBlockMetadata_Buddy::GetUnusedRangeSizeMax() const +{ + for(uint32_t level = 0; level < m_LevelCount; ++level) + { + if(m_FreeList[level].front != VMA_NULL) + { + return LevelToNodeSize(level); + } + } + return 0; +} + +void VmaBlockMetadata_Buddy::CalcAllocationStatInfo(VmaStatInfo& outInfo) const +{ + const VkDeviceSize unusableSize = GetUnusableSize(); + + outInfo.blockCount = 1; + + outInfo.allocationCount = outInfo.unusedRangeCount = 0; + outInfo.usedBytes = outInfo.unusedBytes = 0; + + outInfo.allocationSizeMax = outInfo.unusedRangeSizeMax = 0; + outInfo.allocationSizeMin = outInfo.unusedRangeSizeMin = UINT64_MAX; + outInfo.allocationSizeAvg = outInfo.unusedRangeSizeAvg = 0; // Unused. + + CalcAllocationStatInfoNode(outInfo, m_Root, LevelToNodeSize(0)); + + if(unusableSize > 0) + { + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusableSize; + outInfo.unusedRangeSizeMax = VMA_MAX(outInfo.unusedRangeSizeMax, unusableSize); + outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusableSize); + } +} + +void VmaBlockMetadata_Buddy::AddPoolStats(VmaPoolStats& inoutStats) const +{ + const VkDeviceSize unusableSize = GetUnusableSize(); + + inoutStats.size += GetSize(); + inoutStats.unusedSize += m_SumFreeSize + unusableSize; + inoutStats.allocationCount += m_AllocationCount; + inoutStats.unusedRangeCount += m_FreeCount; + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, GetUnusedRangeSizeMax()); + + if(unusableSize > 0) + { + ++inoutStats.unusedRangeCount; + // Not updating inoutStats.unusedRangeSizeMax with unusableSize because this space is not available for allocations. + } +} + +#if VMA_STATS_STRING_ENABLED + +void VmaBlockMetadata_Buddy::PrintDetailedMap(class VmaJsonWriter& json) const +{ + // TODO optimize + VmaStatInfo stat; + CalcAllocationStatInfo(stat); + + PrintDetailedMap_Begin( + json, + stat.unusedBytes, + stat.allocationCount, + stat.unusedRangeCount); + + PrintDetailedMapNode(json, m_Root, LevelToNodeSize(0)); + + const VkDeviceSize unusableSize = GetUnusableSize(); + if(unusableSize > 0) + { + PrintDetailedMap_UnusedRange(json, + m_UsableSize, // offset + unusableSize); // size + } + + PrintDetailedMap_End(json); +} + +#endif // #if VMA_STATS_STRING_ENABLED + +bool VmaBlockMetadata_Buddy::CreateAllocationRequest( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VkDeviceSize bufferImageGranularity, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + bool canMakeOtherLost, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + VMA_ASSERT(!upperAddress && "VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT can be used only with linear algorithm."); + + // Simple way to respect bufferImageGranularity. May be optimized some day. + // Whenever it might be an OPTIMAL image... + if(allocType == VMA_SUBALLOCATION_TYPE_UNKNOWN || + allocType == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN || + allocType == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL) + { + allocAlignment = VMA_MAX(allocAlignment, bufferImageGranularity); + allocSize = VMA_MAX(allocSize, bufferImageGranularity); + } + + if(allocSize > m_UsableSize) + { + return false; + } + + const uint32_t targetLevel = AllocSizeToLevel(allocSize); + for(uint32_t level = targetLevel + 1; level--; ) + { + for(Node* freeNode = m_FreeList[level].front; + freeNode != VMA_NULL; + freeNode = freeNode->free.next) + { + if(freeNode->offset % allocAlignment == 0) + { + pAllocationRequest->type = VmaAllocationRequestType::Normal; + pAllocationRequest->offset = freeNode->offset; + pAllocationRequest->sumFreeSize = LevelToNodeSize(level); + pAllocationRequest->sumItemSize = 0; + pAllocationRequest->itemsToMakeLostCount = 0; + pAllocationRequest->customData = (void*)(uintptr_t)level; + return true; + } + } + } + + return false; +} + +bool VmaBlockMetadata_Buddy::MakeRequestedAllocationsLost( + uint32_t currentFrameIndex, + uint32_t frameInUseCount, + VmaAllocationRequest* pAllocationRequest) +{ + /* + Lost allocations are not supported in buddy allocator at the moment. + Support might be added in the future. + */ + return pAllocationRequest->itemsToMakeLostCount == 0; +} + +uint32_t VmaBlockMetadata_Buddy::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) +{ + /* + Lost allocations are not supported in buddy allocator at the moment. + Support might be added in the future. + */ + return 0; +} + +void VmaBlockMetadata_Buddy::Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + VkDeviceSize allocSize, + VmaAllocation hAllocation) +{ + VMA_ASSERT(request.type == VmaAllocationRequestType::Normal); + + const uint32_t targetLevel = AllocSizeToLevel(allocSize); + uint32_t currLevel = (uint32_t)(uintptr_t)request.customData; + + Node* currNode = m_FreeList[currLevel].front; + VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE); + while(currNode->offset != request.offset) + { + currNode = currNode->free.next; + VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE); + } + + // Go down, splitting free nodes. + while(currLevel < targetLevel) + { + // currNode is already first free node at currLevel. + // Remove it from list of free nodes at this currLevel. + RemoveFromFreeList(currLevel, currNode); + + const uint32_t childrenLevel = currLevel + 1; + + // Create two free sub-nodes. + Node* leftChild = vma_new(GetAllocationCallbacks(), Node)(); + Node* rightChild = vma_new(GetAllocationCallbacks(), Node)(); + + leftChild->offset = currNode->offset; + leftChild->type = Node::TYPE_FREE; + leftChild->parent = currNode; + leftChild->buddy = rightChild; + + rightChild->offset = currNode->offset + LevelToNodeSize(childrenLevel); + rightChild->type = Node::TYPE_FREE; + rightChild->parent = currNode; + rightChild->buddy = leftChild; + + // Convert current currNode to split type. + currNode->type = Node::TYPE_SPLIT; + currNode->split.leftChild = leftChild; + + // Add child nodes to free list. Order is important! + AddToFreeListFront(childrenLevel, rightChild); + AddToFreeListFront(childrenLevel, leftChild); + + ++m_FreeCount; + //m_SumFreeSize -= LevelToNodeSize(currLevel) % 2; // Useful only when level node sizes can be non power of 2. + ++currLevel; + currNode = m_FreeList[currLevel].front; + + /* + We can be sure that currNode, as left child of node previously split, + also fullfills the alignment requirement. + */ + } + + // Remove from free list. + VMA_ASSERT(currLevel == targetLevel && + currNode != VMA_NULL && + currNode->type == Node::TYPE_FREE); + RemoveFromFreeList(currLevel, currNode); + + // Convert to allocation node. + currNode->type = Node::TYPE_ALLOCATION; + currNode->allocation.alloc = hAllocation; + + ++m_AllocationCount; + --m_FreeCount; + m_SumFreeSize -= allocSize; +} + +void VmaBlockMetadata_Buddy::DeleteNode(Node* node) +{ + if(node->type == Node::TYPE_SPLIT) + { + DeleteNode(node->split.leftChild->buddy); + DeleteNode(node->split.leftChild); + } + + vma_delete(GetAllocationCallbacks(), node); +} + +bool VmaBlockMetadata_Buddy::ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const +{ + VMA_VALIDATE(level < m_LevelCount); + VMA_VALIDATE(curr->parent == parent); + VMA_VALIDATE((curr->buddy == VMA_NULL) == (parent == VMA_NULL)); + VMA_VALIDATE(curr->buddy == VMA_NULL || curr->buddy->buddy == curr); + switch(curr->type) + { + case Node::TYPE_FREE: + // curr->free.prev, next are validated separately. + ctx.calculatedSumFreeSize += levelNodeSize; + ++ctx.calculatedFreeCount; + break; + case Node::TYPE_ALLOCATION: + ++ctx.calculatedAllocationCount; + ctx.calculatedSumFreeSize += levelNodeSize - curr->allocation.alloc->GetSize(); + VMA_VALIDATE(curr->allocation.alloc != VK_NULL_HANDLE); + break; + case Node::TYPE_SPLIT: + { + const uint32_t childrenLevel = level + 1; + const VkDeviceSize childrenLevelNodeSize = levelNodeSize / 2; + const Node* const leftChild = curr->split.leftChild; + VMA_VALIDATE(leftChild != VMA_NULL); + VMA_VALIDATE(leftChild->offset == curr->offset); + if(!ValidateNode(ctx, curr, leftChild, childrenLevel, childrenLevelNodeSize)) + { + VMA_VALIDATE(false && "ValidateNode for left child failed."); + } + const Node* const rightChild = leftChild->buddy; + VMA_VALIDATE(rightChild->offset == curr->offset + childrenLevelNodeSize); + if(!ValidateNode(ctx, curr, rightChild, childrenLevel, childrenLevelNodeSize)) + { + VMA_VALIDATE(false && "ValidateNode for right child failed."); + } + } + break; + default: + return false; + } + + return true; +} + +uint32_t VmaBlockMetadata_Buddy::AllocSizeToLevel(VkDeviceSize allocSize) const +{ + // I know this could be optimized somehow e.g. by using std::log2p1 from C++20. + uint32_t level = 0; + VkDeviceSize currLevelNodeSize = m_UsableSize; + VkDeviceSize nextLevelNodeSize = currLevelNodeSize >> 1; + while(allocSize <= nextLevelNodeSize && level + 1 < m_LevelCount) + { + ++level; + currLevelNodeSize = nextLevelNodeSize; + nextLevelNodeSize = currLevelNodeSize >> 1; + } + return level; +} + +void VmaBlockMetadata_Buddy::FreeAtOffset(VmaAllocation alloc, VkDeviceSize offset) +{ + // Find node and level. + Node* node = m_Root; + VkDeviceSize nodeOffset = 0; + uint32_t level = 0; + VkDeviceSize levelNodeSize = LevelToNodeSize(0); + while(node->type == Node::TYPE_SPLIT) + { + const VkDeviceSize nextLevelSize = levelNodeSize >> 1; + if(offset < nodeOffset + nextLevelSize) + { + node = node->split.leftChild; + } + else + { + node = node->split.leftChild->buddy; + nodeOffset += nextLevelSize; + } + ++level; + levelNodeSize = nextLevelSize; + } + + VMA_ASSERT(node != VMA_NULL && node->type == Node::TYPE_ALLOCATION); + VMA_ASSERT(alloc == VK_NULL_HANDLE || node->allocation.alloc == alloc); + + ++m_FreeCount; + --m_AllocationCount; + m_SumFreeSize += alloc->GetSize(); + + node->type = Node::TYPE_FREE; + + // Join free nodes if possible. + while(level > 0 && node->buddy->type == Node::TYPE_FREE) + { + RemoveFromFreeList(level, node->buddy); + Node* const parent = node->parent; + + vma_delete(GetAllocationCallbacks(), node->buddy); + vma_delete(GetAllocationCallbacks(), node); + parent->type = Node::TYPE_FREE; + + node = parent; + --level; + //m_SumFreeSize += LevelToNodeSize(level) % 2; // Useful only when level node sizes can be non power of 2. + --m_FreeCount; + } + + AddToFreeListFront(level, node); +} + +void VmaBlockMetadata_Buddy::CalcAllocationStatInfoNode(VmaStatInfo& outInfo, const Node* node, VkDeviceSize levelNodeSize) const +{ + switch(node->type) + { + case Node::TYPE_FREE: + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += levelNodeSize; + outInfo.unusedRangeSizeMax = VMA_MAX(outInfo.unusedRangeSizeMax, levelNodeSize); + outInfo.unusedRangeSizeMin = VMA_MAX(outInfo.unusedRangeSizeMin, levelNodeSize); + break; + case Node::TYPE_ALLOCATION: + { + const VkDeviceSize allocSize = node->allocation.alloc->GetSize(); + ++outInfo.allocationCount; + outInfo.usedBytes += allocSize; + outInfo.allocationSizeMax = VMA_MAX(outInfo.allocationSizeMax, allocSize); + outInfo.allocationSizeMin = VMA_MAX(outInfo.allocationSizeMin, allocSize); + + const VkDeviceSize unusedRangeSize = levelNodeSize - allocSize; + if(unusedRangeSize > 0) + { + ++outInfo.unusedRangeCount; + outInfo.unusedBytes += unusedRangeSize; + outInfo.unusedRangeSizeMax = VMA_MAX(outInfo.unusedRangeSizeMax, unusedRangeSize); + outInfo.unusedRangeSizeMin = VMA_MAX(outInfo.unusedRangeSizeMin, unusedRangeSize); + } + } + break; + case Node::TYPE_SPLIT: + { + const VkDeviceSize childrenNodeSize = levelNodeSize / 2; + const Node* const leftChild = node->split.leftChild; + CalcAllocationStatInfoNode(outInfo, leftChild, childrenNodeSize); + const Node* const rightChild = leftChild->buddy; + CalcAllocationStatInfoNode(outInfo, rightChild, childrenNodeSize); + } + break; + default: + VMA_ASSERT(0); + } +} + +void VmaBlockMetadata_Buddy::AddToFreeListFront(uint32_t level, Node* node) +{ + VMA_ASSERT(node->type == Node::TYPE_FREE); + + // List is empty. + Node* const frontNode = m_FreeList[level].front; + if(frontNode == VMA_NULL) + { + VMA_ASSERT(m_FreeList[level].back == VMA_NULL); + node->free.prev = node->free.next = VMA_NULL; + m_FreeList[level].front = m_FreeList[level].back = node; + } + else + { + VMA_ASSERT(frontNode->free.prev == VMA_NULL); + node->free.prev = VMA_NULL; + node->free.next = frontNode; + frontNode->free.prev = node; + m_FreeList[level].front = node; + } +} + +void VmaBlockMetadata_Buddy::RemoveFromFreeList(uint32_t level, Node* node) +{ + VMA_ASSERT(m_FreeList[level].front != VMA_NULL); + + // It is at the front. + if(node->free.prev == VMA_NULL) + { + VMA_ASSERT(m_FreeList[level].front == node); + m_FreeList[level].front = node->free.next; + } + else + { + Node* const prevFreeNode = node->free.prev; + VMA_ASSERT(prevFreeNode->free.next == node); + prevFreeNode->free.next = node->free.next; + } + + // It is at the back. + if(node->free.next == VMA_NULL) + { + VMA_ASSERT(m_FreeList[level].back == node); + m_FreeList[level].back = node->free.prev; + } + else + { + Node* const nextFreeNode = node->free.next; + VMA_ASSERT(nextFreeNode->free.prev == node); + nextFreeNode->free.prev = node->free.prev; + } +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata_Buddy::PrintDetailedMapNode(class VmaJsonWriter& json, const Node* node, VkDeviceSize levelNodeSize) const +{ + switch(node->type) + { + case Node::TYPE_FREE: + PrintDetailedMap_UnusedRange(json, node->offset, levelNodeSize); + break; + case Node::TYPE_ALLOCATION: + { + PrintDetailedMap_Allocation(json, node->offset, node->allocation.alloc); + const VkDeviceSize allocSize = node->allocation.alloc->GetSize(); + if(allocSize < levelNodeSize) + { + PrintDetailedMap_UnusedRange(json, node->offset + allocSize, levelNodeSize - allocSize); + } + } + break; + case Node::TYPE_SPLIT: + { + const VkDeviceSize childrenNodeSize = levelNodeSize / 2; + const Node* const leftChild = node->split.leftChild; + PrintDetailedMapNode(json, leftChild, childrenNodeSize); + const Node* const rightChild = leftChild->buddy; + PrintDetailedMapNode(json, rightChild, childrenNodeSize); + } + break; + default: + VMA_ASSERT(0); + } +} +#endif // #if VMA_STATS_STRING_ENABLED + + //////////////////////////////////////////////////////////////////////////////// // class VmaDeviceMemoryBlock VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) : - m_Metadata(hAllocator), + m_pMetadata(VMA_NULL), m_MemoryTypeIndex(UINT32_MAX), + m_Id(0), m_hMemory(VK_NULL_HANDLE), m_MapCount(0), m_pMappedData(VMA_NULL) @@ -6274,38 +10788,74 @@ VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) : } void VmaDeviceMemoryBlock::Init( + VmaAllocator hAllocator, + VmaPool hParentPool, uint32_t newMemoryTypeIndex, VkDeviceMemory newMemory, - VkDeviceSize newSize) + VkDeviceSize newSize, + uint32_t id, + uint32_t algorithm) { VMA_ASSERT(m_hMemory == VK_NULL_HANDLE); + m_hParentPool = hParentPool; m_MemoryTypeIndex = newMemoryTypeIndex; + m_Id = id; m_hMemory = newMemory; - m_Metadata.Init(newSize); + switch(algorithm) + { + case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT: + m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Linear)(hAllocator); + break; + case VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT: + m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Buddy)(hAllocator); + break; + default: + VMA_ASSERT(0); + // Fall-through. + case 0: + m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Generic)(hAllocator); + } + m_pMetadata->Init(newSize); } void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator) { // This is the most important assert in the entire library. // Hitting it means you have some memory leak - unreleased VmaAllocation objects. - VMA_ASSERT(m_Metadata.IsEmpty() && "Some allocations were not freed before destruction of this memory block!"); - + VMA_ASSERT(m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!"); + VMA_ASSERT(m_hMemory != VK_NULL_HANDLE); - allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_Metadata.GetSize(), m_hMemory); + allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_pMetadata->GetSize(), m_hMemory); m_hMemory = VK_NULL_HANDLE; + + vma_delete(allocator, m_pMetadata); + m_pMetadata = VMA_NULL; } bool VmaDeviceMemoryBlock::Validate() const { - if((m_hMemory == VK_NULL_HANDLE) || - (m_Metadata.GetSize() == 0)) + VMA_VALIDATE((m_hMemory != VK_NULL_HANDLE) && + (m_pMetadata->GetSize() != 0)); + + return m_pMetadata->Validate(); +} + +VkResult VmaDeviceMemoryBlock::CheckCorruption(VmaAllocator hAllocator) +{ + void* pData = nullptr; + VkResult res = Map(hAllocator, 1, &pData); + if(res != VK_SUCCESS) { - return false; + return res; } - - return m_Metadata.Validate(); + + res = m_pMetadata->CheckCorruption(pData); + + Unmap(hAllocator, 1); + + return res; } VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void** ppData) @@ -6370,36 +10920,84 @@ void VmaDeviceMemoryBlock::Unmap(VmaAllocator hAllocator, uint32_t count) } } +VkResult VmaDeviceMemoryBlock::WriteMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize) +{ + VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION); + VMA_ASSERT(allocOffset >= VMA_DEBUG_MARGIN); + + void* pData; + VkResult res = Map(hAllocator, 1, &pData); + if(res != VK_SUCCESS) + { + return res; + } + + VmaWriteMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN); + VmaWriteMagicValue(pData, allocOffset + allocSize); + + Unmap(hAllocator, 1); + + return VK_SUCCESS; +} + +VkResult VmaDeviceMemoryBlock::ValidateMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize) +{ + VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION); + VMA_ASSERT(allocOffset >= VMA_DEBUG_MARGIN); + + void* pData; + VkResult res = Map(hAllocator, 1, &pData); + if(res != VK_SUCCESS) + { + return res; + } + + if(!VmaValidateMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE FREED ALLOCATION!"); + } + else if(!VmaValidateMagicValue(pData, allocOffset + allocSize)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER FREED ALLOCATION!"); + } + + Unmap(hAllocator, 1); + + return VK_SUCCESS; +} + VkResult VmaDeviceMemoryBlock::BindBufferMemory( const VmaAllocator hAllocator, const VmaAllocation hAllocation, - VkBuffer hBuffer) + VkDeviceSize allocationLocalOffset, + VkBuffer hBuffer, + const void* pNext) { VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK && hAllocation->GetBlock() == this); + VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() && + "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?"); + const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset; // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads. VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex); - return hAllocator->GetVulkanFunctions().vkBindBufferMemory( - hAllocator->m_hDevice, - hBuffer, - m_hMemory, - hAllocation->GetOffset()); + return hAllocator->BindVulkanBuffer(m_hMemory, memoryOffset, hBuffer, pNext); } VkResult VmaDeviceMemoryBlock::BindImageMemory( const VmaAllocator hAllocator, const VmaAllocation hAllocation, - VkImage hImage) + VkDeviceSize allocationLocalOffset, + VkImage hImage, + const void* pNext) { VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK && hAllocation->GetBlock() == this); + VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() && + "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?"); + const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset; // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads. VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex); - return hAllocator->GetVulkanFunctions().vkBindImageMemory( - hAllocator->m_hDevice, - hImage, - m_hMemory, - hAllocation->GetOffset()); + return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext); } static void InitStatInfo(VmaStatInfo& outInfo) @@ -6433,21 +11031,45 @@ static void VmaPostprocessCalcStatInfo(VmaStatInfo& inoutInfo) VmaPool_T::VmaPool_T( VmaAllocator hAllocator, - const VmaPoolCreateInfo& createInfo) : + const VmaPoolCreateInfo& createInfo, + VkDeviceSize preferredBlockSize) : m_BlockVector( hAllocator, + this, // hParentPool createInfo.memoryTypeIndex, - createInfo.blockSize, + createInfo.blockSize != 0 ? createInfo.blockSize : preferredBlockSize, createInfo.minBlockCount, createInfo.maxBlockCount, (createInfo.flags & VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT) != 0 ? 1 : hAllocator->GetBufferImageGranularity(), createInfo.frameInUseCount, - true) // isCustomPool + createInfo.blockSize != 0, // explicitBlockSize + createInfo.flags & VMA_POOL_CREATE_ALGORITHM_MASK, // algorithm + createInfo.priority, + VMA_MAX(hAllocator->GetMemoryTypeMinAlignment(createInfo.memoryTypeIndex), createInfo.minAllocationAlignment), + createInfo.pMemoryAllocateNext), + m_Id(0), + m_Name(VMA_NULL) { } VmaPool_T::~VmaPool_T() { + VMA_ASSERT(m_PrevPool == VMA_NULL && m_NextPool == VMA_NULL); +} + +void VmaPool_T::SetName(const char* pName) +{ + const VkAllocationCallbacks* allocs = m_BlockVector.GetAllocator()->GetAllocationCallbacks(); + VmaFreeString(allocs, m_Name); + + if(pName != VMA_NULL) + { + m_Name = VmaCreateStringCopy(allocs, pName); + } + else + { + m_Name = VMA_NULL; + } } #if VMA_STATS_STRING_ENABLED @@ -6456,31 +11078,39 @@ VmaPool_T::~VmaPool_T() VmaBlockVector::VmaBlockVector( VmaAllocator hAllocator, + VmaPool hParentPool, uint32_t memoryTypeIndex, VkDeviceSize preferredBlockSize, size_t minBlockCount, size_t maxBlockCount, VkDeviceSize bufferImageGranularity, uint32_t frameInUseCount, - bool isCustomPool) : + bool explicitBlockSize, + uint32_t algorithm, + float priority, + VkDeviceSize minAllocationAlignment, + void* pMemoryAllocateNext) : m_hAllocator(hAllocator), + m_hParentPool(hParentPool), m_MemoryTypeIndex(memoryTypeIndex), m_PreferredBlockSize(preferredBlockSize), m_MinBlockCount(minBlockCount), m_MaxBlockCount(maxBlockCount), m_BufferImageGranularity(bufferImageGranularity), m_FrameInUseCount(frameInUseCount), - m_IsCustomPool(isCustomPool), - m_Blocks(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), + m_ExplicitBlockSize(explicitBlockSize), + m_Algorithm(algorithm), + m_Priority(priority), + m_MinAllocationAlignment(minAllocationAlignment), + m_pMemoryAllocateNext(pMemoryAllocateNext), m_HasEmptyBlock(false), - m_pDefragmentator(VMA_NULL) + m_Blocks(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), + m_NextBlockId(0) { } VmaBlockVector::~VmaBlockVector() { - VMA_ASSERT(m_pDefragmentator == VMA_NULL); - for(size_t i = m_Blocks.size(); i--; ) { m_Blocks[i]->Destroy(m_hAllocator); @@ -6503,181 +11133,325 @@ VkResult VmaBlockVector::CreateMinBlocks() void VmaBlockVector::GetPoolStats(VmaPoolStats* pStats) { + VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); + + const size_t blockCount = m_Blocks.size(); + pStats->size = 0; pStats->unusedSize = 0; pStats->allocationCount = 0; pStats->unusedRangeCount = 0; pStats->unusedRangeSizeMax = 0; + pStats->blockCount = blockCount; - VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex); - - for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) + for(uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) { const VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; VMA_ASSERT(pBlock); VMA_HEAVY_ASSERT(pBlock->Validate()); - pBlock->m_Metadata.AddPoolStats(*pStats); + pBlock->m_pMetadata->AddPoolStats(*pStats); } } +bool VmaBlockVector::IsEmpty() +{ + VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); + return m_Blocks.empty(); +} + +bool VmaBlockVector::IsCorruptionDetectionEnabled() const +{ + const uint32_t requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + return (VMA_DEBUG_DETECT_CORRUPTION != 0) && + (VMA_DEBUG_MARGIN > 0) && + (m_Algorithm == 0 || m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) && + (m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags & requiredMemFlags) == requiredMemFlags; +} + static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32; VkResult VmaBlockVector::Allocate( - VmaPool hCurrentPool, uint32_t currentFrameIndex, - const VkMemoryRequirements& vkMemReq, + VkDeviceSize size, + VkDeviceSize alignment, + const VmaAllocationCreateInfo& createInfo, + VmaSuballocationType suballocType, + size_t allocationCount, + VmaAllocation* pAllocations) +{ + size_t allocIndex; + VkResult res = VK_SUCCESS; + + alignment = VMA_MAX(alignment, m_MinAllocationAlignment); + + if(IsCorruptionDetectionEnabled()) + { + size = VmaAlignUp(size, sizeof(VMA_CORRUPTION_DETECTION_MAGIC_VALUE)); + alignment = VmaAlignUp(alignment, sizeof(VMA_CORRUPTION_DETECTION_MAGIC_VALUE)); + } + + { + VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); + for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex) + { + res = AllocatePage( + currentFrameIndex, + size, + alignment, + createInfo, + suballocType, + pAllocations + allocIndex); + if(res != VK_SUCCESS) + { + break; + } + } + } + + if(res != VK_SUCCESS) + { + // Free all already created allocations. + const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex); + while(allocIndex--) + { + VmaAllocation_T* const alloc = pAllocations[allocIndex]; + const VkDeviceSize allocSize = alloc->GetSize(); + Free(alloc); + m_hAllocator->m_Budget.RemoveAllocation(heapIndex, allocSize); + } + memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount); + } + + return res; +} + +VkResult VmaBlockVector::AllocatePage( + uint32_t currentFrameIndex, + VkDeviceSize size, + VkDeviceSize alignment, const VmaAllocationCreateInfo& createInfo, VmaSuballocationType suballocType, VmaAllocation* pAllocation) { + const bool isUpperAddress = (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0; + bool canMakeOtherLost = (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) != 0; const bool mapped = (createInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0; const bool isUserDataString = (createInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0; - VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex); - - // 1. Search existing allocations. Try to allocate without making other allocations lost. - // Forward order in m_Blocks - prefer blocks with smallest amount of free space. - for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex ) + VkDeviceSize freeMemory; { - VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; - VMA_ASSERT(pCurrBlock); - VmaAllocationRequest currRequest = {}; - if(pCurrBlock->m_Metadata.CreateAllocationRequest( - currentFrameIndex, - m_FrameInUseCount, - m_BufferImageGranularity, - vkMemReq.size, - vkMemReq.alignment, - suballocType, - false, // canMakeOtherLost - &currRequest)) - { - // Allocate from pCurrBlock. - VMA_ASSERT(currRequest.itemsToMakeLostCount == 0); - - if(mapped) - { - VkResult res = pCurrBlock->Map(m_hAllocator, 1, VMA_NULL); - if(res != VK_SUCCESS) - { - return res; - } - } - - // We no longer have an empty Allocation. - if(pCurrBlock->m_Metadata.IsEmpty()) - { - m_HasEmptyBlock = false; - } - - *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString); - pCurrBlock->m_Metadata.Alloc(currRequest, suballocType, vkMemReq.size, *pAllocation); - (*pAllocation)->InitBlockAllocation( - hCurrentPool, - pCurrBlock, - currRequest.offset, - vkMemReq.alignment, - vkMemReq.size, - suballocType, - mapped, - (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0); - VMA_HEAVY_ASSERT(pCurrBlock->Validate()); - VMA_DEBUG_LOG(" Returned from existing allocation #%u", (uint32_t)blockIndex); - (*pAllocation)->SetUserData(m_hAllocator, createInfo.pUserData); - return VK_SUCCESS; - } + const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex); + VmaBudget heapBudget = {}; + m_hAllocator->GetBudget(&heapBudget, heapIndex, 1); + freeMemory = (heapBudget.usage < heapBudget.budget) ? (heapBudget.budget - heapBudget.usage) : 0; } + const bool canFallbackToDedicated = !IsCustomPool(); const bool canCreateNewBlock = ((createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0) && - (m_Blocks.size() < m_MaxBlockCount); + (m_Blocks.size() < m_MaxBlockCount) && + (freeMemory >= size || !canFallbackToDedicated); + uint32_t strategy = createInfo.flags & VMA_ALLOCATION_CREATE_STRATEGY_MASK; - // 2. Try to create new block. - if(canCreateNewBlock) + // If linearAlgorithm is used, canMakeOtherLost is available only when used as ring buffer. + // Which in turn is available only when maxBlockCount = 1. + if(m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT && m_MaxBlockCount > 1) { - // Calculate optimal size for new block. - VkDeviceSize newBlockSize = m_PreferredBlockSize; - uint32_t newBlockSizeShift = 0; - const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3; - - // Allocating blocks of other sizes is allowed only in default pools. - // In custom pools block size is fixed. - if(m_IsCustomPool == false) - { - // Allocate 1/8, 1/4, 1/2 as first blocks. - const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize(); - for(uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i) - { - const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; - if(smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= vkMemReq.size * 2) - { - newBlockSize = smallerNewBlockSize; - ++newBlockSizeShift; - } - else - { - break; - } - } - } - - size_t newBlockIndex = 0; - VkResult res = CreateBlock(newBlockSize, &newBlockIndex); - // Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize. - if(m_IsCustomPool == false) - { - while(res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX) - { - const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; - if(smallerNewBlockSize >= vkMemReq.size) - { - newBlockSize = smallerNewBlockSize; - ++newBlockSizeShift; - res = CreateBlock(newBlockSize, &newBlockIndex); - } - else - { - break; - } - } - } - - if(res == VK_SUCCESS) - { - VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex]; - VMA_ASSERT(pBlock->m_Metadata.GetSize() >= vkMemReq.size); - - if(mapped) - { - res = pBlock->Map(m_hAllocator, 1, VMA_NULL); - if(res != VK_SUCCESS) - { - return res; - } - } - - // Allocate from pBlock. Because it is empty, dstAllocRequest can be trivially filled. - VmaAllocationRequest allocRequest; - pBlock->m_Metadata.CreateFirstAllocationRequest(&allocRequest); - *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString); - pBlock->m_Metadata.Alloc(allocRequest, suballocType, vkMemReq.size, *pAllocation); - (*pAllocation)->InitBlockAllocation( - hCurrentPool, - pBlock, - allocRequest.offset, - vkMemReq.alignment, - vkMemReq.size, - suballocType, - mapped, - (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0); - VMA_HEAVY_ASSERT(pBlock->Validate()); - VMA_DEBUG_LOG(" Created new allocation Size=%llu", allocInfo.allocationSize); - (*pAllocation)->SetUserData(m_hAllocator, createInfo.pUserData); - return VK_SUCCESS; - } + canMakeOtherLost = false; } - const bool canMakeOtherLost = (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) != 0; + // Upper address can only be used with linear allocator and within single memory block. + if(isUpperAddress && + (m_Algorithm != VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT || m_MaxBlockCount > 1)) + { + return VK_ERROR_FEATURE_NOT_PRESENT; + } + + // Validate strategy. + switch(strategy) + { + case 0: + strategy = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT; + break; + case VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT: + case VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT: + case VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT: + break; + default: + return VK_ERROR_FEATURE_NOT_PRESENT; + } + + // Early reject: requested allocation size is larger that maximum block size for this block vector. + if(size + 2 * VMA_DEBUG_MARGIN > m_PreferredBlockSize) + { + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + + /* + Under certain condition, this whole section can be skipped for optimization, so + we move on directly to trying to allocate with canMakeOtherLost. That is the case + e.g. for custom pools with linear algorithm. + */ + if(!canMakeOtherLost || canCreateNewBlock) + { + // 1. Search existing allocations. Try to allocate without making other allocations lost. + VmaAllocationCreateFlags allocFlagsCopy = createInfo.flags; + allocFlagsCopy &= ~VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT; + + if(m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) + { + // Use only last block. + if(!m_Blocks.empty()) + { + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks.back(); + VMA_ASSERT(pCurrBlock); + VkResult res = AllocateFromBlock( + pCurrBlock, + currentFrameIndex, + size, + alignment, + allocFlagsCopy, + createInfo.pUserData, + suballocType, + strategy, + pAllocation); + if(res == VK_SUCCESS) + { + VMA_DEBUG_LOG(" Returned from last block #%u", pCurrBlock->GetId()); + return VK_SUCCESS; + } + } + } + else + { + if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT) + { + // Forward order in m_Blocks - prefer blocks with smallest amount of free space. + for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex ) + { + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pCurrBlock); + VkResult res = AllocateFromBlock( + pCurrBlock, + currentFrameIndex, + size, + alignment, + allocFlagsCopy, + createInfo.pUserData, + suballocType, + strategy, + pAllocation); + if(res == VK_SUCCESS) + { + VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId()); + return VK_SUCCESS; + } + } + } + else // WORST_FIT, FIRST_FIT + { + // Backward order in m_Blocks - prefer blocks with largest amount of free space. + for(size_t blockIndex = m_Blocks.size(); blockIndex--; ) + { + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pCurrBlock); + VkResult res = AllocateFromBlock( + pCurrBlock, + currentFrameIndex, + size, + alignment, + allocFlagsCopy, + createInfo.pUserData, + suballocType, + strategy, + pAllocation); + if(res == VK_SUCCESS) + { + VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId()); + return VK_SUCCESS; + } + } + } + } + + // 2. Try to create new block. + if(canCreateNewBlock) + { + // Calculate optimal size for new block. + VkDeviceSize newBlockSize = m_PreferredBlockSize; + uint32_t newBlockSizeShift = 0; + const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3; + + if(!m_ExplicitBlockSize) + { + // Allocate 1/8, 1/4, 1/2 as first blocks. + const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize(); + for(uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i) + { + const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; + if(smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= size * 2) + { + newBlockSize = smallerNewBlockSize; + ++newBlockSizeShift; + } + else + { + break; + } + } + } + + size_t newBlockIndex = 0; + VkResult res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ? + CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY; + // Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize. + if(!m_ExplicitBlockSize) + { + while(res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX) + { + const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; + if(smallerNewBlockSize >= size) + { + newBlockSize = smallerNewBlockSize; + ++newBlockSizeShift; + res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ? + CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + else + { + break; + } + } + } + + if(res == VK_SUCCESS) + { + VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex]; + VMA_ASSERT(pBlock->m_pMetadata->GetSize() >= size); + + res = AllocateFromBlock( + pBlock, + currentFrameIndex, + size, + alignment, + allocFlagsCopy, + createInfo.pUserData, + suballocType, + strategy, + pAllocation); + if(res == VK_SUCCESS) + { + VMA_DEBUG_LOG(" Created new block #%u Size=%llu", pBlock->GetId(), newBlockSize); + return VK_SUCCESS; + } + else + { + // Allocation from new block failed, possibly due to VMA_DEBUG_MARGIN or alignment. + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + } + } + } // 3. Try to allocate from existing blocks with making other allocations lost. if(canMakeOtherLost) @@ -6690,33 +11464,76 @@ VkResult VmaBlockVector::Allocate( VkDeviceSize bestRequestCost = VK_WHOLE_SIZE; // 1. Search existing allocations. - // Forward order in m_Blocks - prefer blocks with smallest amount of free space. - for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex ) + if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT) { - VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; - VMA_ASSERT(pCurrBlock); - VmaAllocationRequest currRequest = {}; - if(pCurrBlock->m_Metadata.CreateAllocationRequest( - currentFrameIndex, - m_FrameInUseCount, - m_BufferImageGranularity, - vkMemReq.size, - vkMemReq.alignment, - suballocType, - canMakeOtherLost, - &currRequest)) + // Forward order in m_Blocks - prefer blocks with smallest amount of free space. + for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex ) { - const VkDeviceSize currRequestCost = currRequest.CalcCost(); - if(pBestRequestBlock == VMA_NULL || - currRequestCost < bestRequestCost) + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pCurrBlock); + VmaAllocationRequest currRequest = {}; + if(pCurrBlock->m_pMetadata->CreateAllocationRequest( + currentFrameIndex, + m_FrameInUseCount, + m_BufferImageGranularity, + size, + alignment, + (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0, + suballocType, + canMakeOtherLost, + strategy, + &currRequest)) { - pBestRequestBlock = pCurrBlock; - bestRequest = currRequest; - bestRequestCost = currRequestCost; - - if(bestRequestCost == 0) + const VkDeviceSize currRequestCost = currRequest.CalcCost(); + if(pBestRequestBlock == VMA_NULL || + currRequestCost < bestRequestCost) { - break; + pBestRequestBlock = pCurrBlock; + bestRequest = currRequest; + bestRequestCost = currRequestCost; + + if(bestRequestCost == 0) + { + break; + } + } + } + } + } + else // WORST_FIT, FIRST_FIT + { + // Backward order in m_Blocks - prefer blocks with largest amount of free space. + for(size_t blockIndex = m_Blocks.size(); blockIndex--; ) + { + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pCurrBlock); + VmaAllocationRequest currRequest = {}; + if(pCurrBlock->m_pMetadata->CreateAllocationRequest( + currentFrameIndex, + m_FrameInUseCount, + m_BufferImageGranularity, + size, + alignment, + (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0, + suballocType, + canMakeOtherLost, + strategy, + &currRequest)) + { + const VkDeviceSize currRequestCost = currRequest.CalcCost(); + if(pBestRequestBlock == VMA_NULL || + currRequestCost < bestRequestCost || + strategy == VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT) + { + pBestRequestBlock = pCurrBlock; + bestRequest = currRequest; + bestRequestCost = currRequestCost; + + if(bestRequestCost == 0 || + strategy == VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT) + { + break; + } } } } @@ -6733,31 +11550,37 @@ VkResult VmaBlockVector::Allocate( } } - if(pBestRequestBlock->m_Metadata.MakeRequestedAllocationsLost( + if(pBestRequestBlock->m_pMetadata->MakeRequestedAllocationsLost( currentFrameIndex, m_FrameInUseCount, &bestRequest)) { - // We no longer have an empty Allocation. - if(pBestRequestBlock->m_Metadata.IsEmpty()) - { - m_HasEmptyBlock = false; - } // Allocate from this pBlock. - *pAllocation = vma_new(m_hAllocator, VmaAllocation_T)(currentFrameIndex, isUserDataString); - pBestRequestBlock->m_Metadata.Alloc(bestRequest, suballocType, vkMemReq.size, *pAllocation); + *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(currentFrameIndex, isUserDataString); + pBestRequestBlock->m_pMetadata->Alloc(bestRequest, suballocType, size, *pAllocation); + UpdateHasEmptyBlock(); (*pAllocation)->InitBlockAllocation( - hCurrentPool, pBestRequestBlock, bestRequest.offset, - vkMemReq.alignment, - vkMemReq.size, + alignment, + size, + m_MemoryTypeIndex, suballocType, mapped, (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0); VMA_HEAVY_ASSERT(pBestRequestBlock->Validate()); - VMA_DEBUG_LOG(" Returned from existing allocation #%u", (uint32_t)blockIndex); + VMA_DEBUG_LOG(" Returned from existing block #%u", pBestRequestBlock->GetId()); (*pAllocation)->SetUserData(m_hAllocator, createInfo.pUserData); + m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), size); + if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) + { + m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED); + } + if(IsCorruptionDetectionEnabled()) + { + VkResult res = pBestRequestBlock->WriteMagicValueAroundAllocation(m_hAllocator, bestRequest.offset, size); + VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value."); + } return VK_SUCCESS; } // else: Some allocations must have been touched while we are here. Next try. @@ -6781,73 +11604,84 @@ VkResult VmaBlockVector::Allocate( } void VmaBlockVector::Free( - VmaAllocation hAllocation) + const VmaAllocation hAllocation) { VmaDeviceMemoryBlock* pBlockToDelete = VMA_NULL; + bool budgetExceeded = false; + { + const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex); + VmaBudget heapBudget = {}; + m_hAllocator->GetBudget(&heapBudget, heapIndex, 1); + budgetExceeded = heapBudget.usage >= heapBudget.budget; + } + // Scope for lock. { - VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex); + VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock(); + if(IsCorruptionDetectionEnabled()) + { + VkResult res = pBlock->ValidateMagicValueAroundAllocation(m_hAllocator, hAllocation->GetOffset(), hAllocation->GetSize()); + VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to validate magic value."); + } + if(hAllocation->IsPersistentMap()) { pBlock->Unmap(m_hAllocator, 1); } - pBlock->m_Metadata.Free(hAllocation); + pBlock->m_pMetadata->Free(hAllocation); VMA_HEAVY_ASSERT(pBlock->Validate()); - VMA_DEBUG_LOG(" Freed from MemoryTypeIndex=%u", memTypeIndex); + VMA_DEBUG_LOG(" Freed from MemoryTypeIndex=%u", m_MemoryTypeIndex); + const bool canDeleteBlock = m_Blocks.size() > m_MinBlockCount; // pBlock became empty after this deallocation. - if(pBlock->m_Metadata.IsEmpty()) + if(pBlock->m_pMetadata->IsEmpty()) { - // Already has empty Allocation. We don't want to have two, so delete this one. - if(m_HasEmptyBlock && m_Blocks.size() > m_MinBlockCount) + // Already has empty block. We don't want to have two, so delete this one. + if((m_HasEmptyBlock || budgetExceeded) && canDeleteBlock) { pBlockToDelete = pBlock; Remove(pBlock); } - // We now have first empty Allocation. - else - { - m_HasEmptyBlock = true; - } + // else: We now have an empty block - leave it. } // pBlock didn't become empty, but we have another empty block - find and free that one. // (This is optional, heuristics.) - else if(m_HasEmptyBlock) + else if(m_HasEmptyBlock && canDeleteBlock) { VmaDeviceMemoryBlock* pLastBlock = m_Blocks.back(); - if(pLastBlock->m_Metadata.IsEmpty() && m_Blocks.size() > m_MinBlockCount) + if(pLastBlock->m_pMetadata->IsEmpty()) { pBlockToDelete = pLastBlock; m_Blocks.pop_back(); - m_HasEmptyBlock = false; } } + UpdateHasEmptyBlock(); IncrementallySortBlocks(); } - // Destruction of a free Allocation. Deferred until this point, outside of mutex + // Destruction of a free block. Deferred until this point, outside of mutex // lock, for performance reason. if(pBlockToDelete != VMA_NULL) { - VMA_DEBUG_LOG(" Deleted empty allocation"); + VMA_DEBUG_LOG(" Deleted empty block #%u", pBlockToDelete->GetId()); pBlockToDelete->Destroy(m_hAllocator); vma_delete(m_hAllocator, pBlockToDelete); } } -size_t VmaBlockVector::CalcMaxBlockSize() const +VkDeviceSize VmaBlockVector::CalcMaxBlockSize() const { - size_t result = 0; + VkDeviceSize result = 0; for(size_t i = m_Blocks.size(); i--; ) { - result = VMA_MAX((uint64_t)result, (uint64_t)m_Blocks[i]->m_Metadata.GetSize()); + result = VMA_MAX(result, m_Blocks[i]->m_pMetadata->GetSize()); if(result >= m_PreferredBlockSize) { break; @@ -6871,22 +11705,126 @@ void VmaBlockVector::Remove(VmaDeviceMemoryBlock* pBlock) void VmaBlockVector::IncrementallySortBlocks() { - // Bubble sort only until first swap. - for(size_t i = 1; i < m_Blocks.size(); ++i) + if(m_Algorithm != VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) { - if(m_Blocks[i - 1]->m_Metadata.GetSumFreeSize() > m_Blocks[i]->m_Metadata.GetSumFreeSize()) + // Bubble sort only until first swap. + for(size_t i = 1; i < m_Blocks.size(); ++i) { - VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]); - return; + if(m_Blocks[i - 1]->m_pMetadata->GetSumFreeSize() > m_Blocks[i]->m_pMetadata->GetSumFreeSize()) + { + VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]); + return; + } } } } +VkResult VmaBlockVector::AllocateFromBlock( + VmaDeviceMemoryBlock* pBlock, + uint32_t currentFrameIndex, + VkDeviceSize size, + VkDeviceSize alignment, + VmaAllocationCreateFlags allocFlags, + void* pUserData, + VmaSuballocationType suballocType, + uint32_t strategy, + VmaAllocation* pAllocation) +{ + VMA_ASSERT((allocFlags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) == 0); + const bool isUpperAddress = (allocFlags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0; + const bool mapped = (allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0; + const bool isUserDataString = (allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0; + + VmaAllocationRequest currRequest = {}; + if(pBlock->m_pMetadata->CreateAllocationRequest( + currentFrameIndex, + m_FrameInUseCount, + m_BufferImageGranularity, + size, + alignment, + isUpperAddress, + suballocType, + false, // canMakeOtherLost + strategy, + &currRequest)) + { + // Allocate from pCurrBlock. + VMA_ASSERT(currRequest.itemsToMakeLostCount == 0); + + if(mapped) + { + VkResult res = pBlock->Map(m_hAllocator, 1, VMA_NULL); + if(res != VK_SUCCESS) + { + return res; + } + } + + *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(currentFrameIndex, isUserDataString); + pBlock->m_pMetadata->Alloc(currRequest, suballocType, size, *pAllocation); + UpdateHasEmptyBlock(); + (*pAllocation)->InitBlockAllocation( + pBlock, + currRequest.offset, + alignment, + size, + m_MemoryTypeIndex, + suballocType, + mapped, + (allocFlags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0); + VMA_HEAVY_ASSERT(pBlock->Validate()); + (*pAllocation)->SetUserData(m_hAllocator, pUserData); + m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), size); + if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) + { + m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED); + } + if(IsCorruptionDetectionEnabled()) + { + VkResult res = pBlock->WriteMagicValueAroundAllocation(m_hAllocator, currRequest.offset, size); + VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value."); + } + return VK_SUCCESS; + } + return VK_ERROR_OUT_OF_DEVICE_MEMORY; +} + VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex) { VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + allocInfo.pNext = m_pMemoryAllocateNext; allocInfo.memoryTypeIndex = m_MemoryTypeIndex; allocInfo.allocationSize = blockSize; + +#if VMA_BUFFER_DEVICE_ADDRESS + // Every standalone block can potentially contain a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - always enable the feature. + VkMemoryAllocateFlagsInfoKHR allocFlagsInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR }; + if(m_hAllocator->m_UseKhrBufferDeviceAddress) + { + allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR; + VmaPnextChainPushFront(&allocInfo, &allocFlagsInfo); + } +#endif // #if VMA_BUFFER_DEVICE_ADDRESS + +#if VMA_MEMORY_PRIORITY + VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT }; + if(m_hAllocator->m_UseExtMemoryPriority) + { + priorityInfo.priority = m_Priority; + VmaPnextChainPushFront(&allocInfo, &priorityInfo); + } +#endif // #if VMA_MEMORY_PRIORITY + +#if VMA_EXTERNAL_MEMORY + // Attach VkExportMemoryAllocateInfoKHR if necessary. + VkExportMemoryAllocateInfoKHR exportMemoryAllocInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR }; + exportMemoryAllocInfo.handleTypes = m_hAllocator->GetExternalMemoryHandleTypeFlags(m_MemoryTypeIndex); + if(exportMemoryAllocInfo.handleTypes != 0) + { + VmaPnextChainPushFront(&allocInfo, &exportMemoryAllocInfo); + } +#endif // #if VMA_EXTERNAL_MEMORY + VkDeviceMemory mem = VK_NULL_HANDLE; VkResult res = m_hAllocator->AllocateVulkanMemory(&allocInfo, &mem); if(res < 0) @@ -6899,9 +11837,13 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn // Create new Allocation for it. VmaDeviceMemoryBlock* const pBlock = vma_new(m_hAllocator, VmaDeviceMemoryBlock)(m_hAllocator); pBlock->Init( + m_hAllocator, + m_hParentPool, m_MemoryTypeIndex, mem, - allocInfo.allocationSize); + allocInfo.allocationSize, + m_NextBlockId++, + m_Algorithm); m_Blocks.push_back(pBlock); if(pNewBlockIndex != VMA_NULL) @@ -6912,16 +11854,261 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn return VK_SUCCESS; } +void VmaBlockVector::ApplyDefragmentationMovesCpu( + class VmaBlockVectorDefragmentationContext* pDefragCtx, + const VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves) +{ + const size_t blockCount = m_Blocks.size(); + const bool isNonCoherent = m_hAllocator->IsMemoryTypeNonCoherent(m_MemoryTypeIndex); + + enum BLOCK_FLAG + { + BLOCK_FLAG_USED = 0x00000001, + BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION = 0x00000002, + }; + + struct BlockInfo + { + uint32_t flags; + void* pMappedData; + }; + VmaVector< BlockInfo, VmaStlAllocator > + blockInfo(blockCount, BlockInfo(), VmaStlAllocator(m_hAllocator->GetAllocationCallbacks())); + memset(blockInfo.data(), 0, blockCount * sizeof(BlockInfo)); + + // Go over all moves. Mark blocks that are used with BLOCK_FLAG_USED. + const size_t moveCount = moves.size(); + for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) + { + const VmaDefragmentationMove& move = moves[moveIndex]; + blockInfo[move.srcBlockIndex].flags |= BLOCK_FLAG_USED; + blockInfo[move.dstBlockIndex].flags |= BLOCK_FLAG_USED; + } + + VMA_ASSERT(pDefragCtx->res == VK_SUCCESS); + + // Go over all blocks. Get mapped pointer or map if necessary. + for(size_t blockIndex = 0; pDefragCtx->res == VK_SUCCESS && blockIndex < blockCount; ++blockIndex) + { + BlockInfo& currBlockInfo = blockInfo[blockIndex]; + VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; + if((currBlockInfo.flags & BLOCK_FLAG_USED) != 0) + { + currBlockInfo.pMappedData = pBlock->GetMappedData(); + // It is not originally mapped - map it. + if(currBlockInfo.pMappedData == VMA_NULL) + { + pDefragCtx->res = pBlock->Map(m_hAllocator, 1, &currBlockInfo.pMappedData); + if(pDefragCtx->res == VK_SUCCESS) + { + currBlockInfo.flags |= BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION; + } + } + } + } + + // Go over all moves. Do actual data transfer. + if(pDefragCtx->res == VK_SUCCESS) + { + const VkDeviceSize nonCoherentAtomSize = m_hAllocator->m_PhysicalDeviceProperties.limits.nonCoherentAtomSize; + VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; + + for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) + { + const VmaDefragmentationMove& move = moves[moveIndex]; + + const BlockInfo& srcBlockInfo = blockInfo[move.srcBlockIndex]; + const BlockInfo& dstBlockInfo = blockInfo[move.dstBlockIndex]; + + VMA_ASSERT(srcBlockInfo.pMappedData && dstBlockInfo.pMappedData); + + // Invalidate source. + if(isNonCoherent) + { + VmaDeviceMemoryBlock* const pSrcBlock = m_Blocks[move.srcBlockIndex]; + memRange.memory = pSrcBlock->GetDeviceMemory(); + memRange.offset = VmaAlignDown(move.srcOffset, nonCoherentAtomSize); + memRange.size = VMA_MIN( + VmaAlignUp(move.size + (move.srcOffset - memRange.offset), nonCoherentAtomSize), + pSrcBlock->m_pMetadata->GetSize() - memRange.offset); + (*m_hAllocator->GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hAllocator->m_hDevice, 1, &memRange); + } + + // THE PLACE WHERE ACTUAL DATA COPY HAPPENS. + memmove( + reinterpret_cast(dstBlockInfo.pMappedData) + move.dstOffset, + reinterpret_cast(srcBlockInfo.pMappedData) + move.srcOffset, + static_cast(move.size)); + + if(IsCorruptionDetectionEnabled()) + { + VmaWriteMagicValue(dstBlockInfo.pMappedData, move.dstOffset - VMA_DEBUG_MARGIN); + VmaWriteMagicValue(dstBlockInfo.pMappedData, move.dstOffset + move.size); + } + + // Flush destination. + if(isNonCoherent) + { + VmaDeviceMemoryBlock* const pDstBlock = m_Blocks[move.dstBlockIndex]; + memRange.memory = pDstBlock->GetDeviceMemory(); + memRange.offset = VmaAlignDown(move.dstOffset, nonCoherentAtomSize); + memRange.size = VMA_MIN( + VmaAlignUp(move.size + (move.dstOffset - memRange.offset), nonCoherentAtomSize), + pDstBlock->m_pMetadata->GetSize() - memRange.offset); + (*m_hAllocator->GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hAllocator->m_hDevice, 1, &memRange); + } + } + } + + // Go over all blocks in reverse order. Unmap those that were mapped just for defragmentation. + // Regardless of pCtx->res == VK_SUCCESS. + for(size_t blockIndex = blockCount; blockIndex--; ) + { + const BlockInfo& currBlockInfo = blockInfo[blockIndex]; + if((currBlockInfo.flags & BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION) != 0) + { + VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; + pBlock->Unmap(m_hAllocator, 1); + } + } +} + +void VmaBlockVector::ApplyDefragmentationMovesGpu( + class VmaBlockVectorDefragmentationContext* pDefragCtx, + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, + VkCommandBuffer commandBuffer) +{ + const size_t blockCount = m_Blocks.size(); + + pDefragCtx->blockContexts.resize(blockCount); + memset(pDefragCtx->blockContexts.data(), 0, blockCount * sizeof(VmaBlockDefragmentationContext)); + + // Go over all moves. Mark blocks that are used with BLOCK_FLAG_USED. + const size_t moveCount = moves.size(); + for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) + { + const VmaDefragmentationMove& move = moves[moveIndex]; + + //if(move.type == VMA_ALLOCATION_TYPE_UNKNOWN) + { + // Old school move still require us to map the whole block + pDefragCtx->blockContexts[move.srcBlockIndex].flags |= VmaBlockDefragmentationContext::BLOCK_FLAG_USED; + pDefragCtx->blockContexts[move.dstBlockIndex].flags |= VmaBlockDefragmentationContext::BLOCK_FLAG_USED; + } + } + + VMA_ASSERT(pDefragCtx->res == VK_SUCCESS); + + // Go over all blocks. Create and bind buffer for whole block if necessary. + { + VkBufferCreateInfo bufCreateInfo; + VmaFillGpuDefragmentationBufferCreateInfo(bufCreateInfo); + + for(size_t blockIndex = 0; pDefragCtx->res == VK_SUCCESS && blockIndex < blockCount; ++blockIndex) + { + VmaBlockDefragmentationContext& currBlockCtx = pDefragCtx->blockContexts[blockIndex]; + VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; + if((currBlockCtx.flags & VmaBlockDefragmentationContext::BLOCK_FLAG_USED) != 0) + { + bufCreateInfo.size = pBlock->m_pMetadata->GetSize(); + pDefragCtx->res = (*m_hAllocator->GetVulkanFunctions().vkCreateBuffer)( + m_hAllocator->m_hDevice, &bufCreateInfo, m_hAllocator->GetAllocationCallbacks(), &currBlockCtx.hBuffer); + if(pDefragCtx->res == VK_SUCCESS) + { + pDefragCtx->res = (*m_hAllocator->GetVulkanFunctions().vkBindBufferMemory)( + m_hAllocator->m_hDevice, currBlockCtx.hBuffer, pBlock->GetDeviceMemory(), 0); + } + } + } + } + + // Go over all moves. Post data transfer commands to command buffer. + if(pDefragCtx->res == VK_SUCCESS) + { + for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) + { + const VmaDefragmentationMove& move = moves[moveIndex]; + + const VmaBlockDefragmentationContext& srcBlockCtx = pDefragCtx->blockContexts[move.srcBlockIndex]; + const VmaBlockDefragmentationContext& dstBlockCtx = pDefragCtx->blockContexts[move.dstBlockIndex]; + + VMA_ASSERT(srcBlockCtx.hBuffer && dstBlockCtx.hBuffer); + + VkBufferCopy region = { + move.srcOffset, + move.dstOffset, + move.size }; + (*m_hAllocator->GetVulkanFunctions().vkCmdCopyBuffer)( + commandBuffer, srcBlockCtx.hBuffer, dstBlockCtx.hBuffer, 1, ®ion); + } + } + + // Save buffers to defrag context for later destruction. + if(pDefragCtx->res == VK_SUCCESS && moveCount > 0) + { + pDefragCtx->res = VK_NOT_READY; + } +} + +void VmaBlockVector::FreeEmptyBlocks(VmaDefragmentationStats* pDefragmentationStats) +{ + for(size_t blockIndex = m_Blocks.size(); blockIndex--; ) + { + VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; + if(pBlock->m_pMetadata->IsEmpty()) + { + if(m_Blocks.size() > m_MinBlockCount) + { + if(pDefragmentationStats != VMA_NULL) + { + ++pDefragmentationStats->deviceMemoryBlocksFreed; + pDefragmentationStats->bytesFreed += pBlock->m_pMetadata->GetSize(); + } + + VmaVectorRemove(m_Blocks, blockIndex); + pBlock->Destroy(m_hAllocator); + vma_delete(m_hAllocator, pBlock); + } + else + { + break; + } + } + } + UpdateHasEmptyBlock(); +} + +void VmaBlockVector::UpdateHasEmptyBlock() +{ + m_HasEmptyBlock = false; + for(size_t index = 0, count = m_Blocks.size(); index < count; ++index) + { + VmaDeviceMemoryBlock* const pBlock = m_Blocks[index]; + if(pBlock->m_pMetadata->IsEmpty()) + { + m_HasEmptyBlock = true; + break; + } + } +} + #if VMA_STATS_STRING_ENABLED void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json) { - VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex); + VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); json.BeginObject(); - if(m_IsCustomPool) + if(IsCustomPool()) { + const char* poolName = m_hParentPool->GetName(); + if(poolName != VMA_NULL && poolName[0] != '\0') + { + json.WriteString("Name"); + json.WriteString(poolName); + } + json.WriteString("MemoryTypeIndex"); json.WriteNumber(m_MemoryTypeIndex); @@ -6949,6 +12136,12 @@ void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json) json.WriteString("FrameInUseCount"); json.WriteNumber(m_FrameInUseCount); } + + if(m_Algorithm != 0) + { + json.WriteString("Algorithm"); + json.WriteString(VmaAlgorithmToStr(m_Algorithm)); + } } else { @@ -6957,110 +12150,254 @@ void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json) } json.WriteString("Blocks"); - json.BeginArray(); + json.BeginObject(); for(size_t i = 0; i < m_Blocks.size(); ++i) { - m_Blocks[i]->m_Metadata.PrintDetailedMap(json); + json.BeginString(); + json.ContinueString(m_Blocks[i]->GetId()); + json.EndString(); + + m_Blocks[i]->m_pMetadata->PrintDetailedMap(json); } - json.EndArray(); + json.EndObject(); json.EndObject(); } #endif // #if VMA_STATS_STRING_ENABLED -VmaDefragmentator* VmaBlockVector::EnsureDefragmentator( - VmaAllocator hAllocator, - uint32_t currentFrameIndex) +void VmaBlockVector::Defragment( + class VmaBlockVectorDefragmentationContext* pCtx, + VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags, + VkDeviceSize& maxCpuBytesToMove, uint32_t& maxCpuAllocationsToMove, + VkDeviceSize& maxGpuBytesToMove, uint32_t& maxGpuAllocationsToMove, + VkCommandBuffer commandBuffer) { - if(m_pDefragmentator == VMA_NULL) + pCtx->res = VK_SUCCESS; + + const VkMemoryPropertyFlags memPropFlags = + m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags; + const bool isHostVisible = (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0; + + const bool canDefragmentOnCpu = maxCpuBytesToMove > 0 && maxCpuAllocationsToMove > 0 && + isHostVisible; + const bool canDefragmentOnGpu = maxGpuBytesToMove > 0 && maxGpuAllocationsToMove > 0 && + !IsCorruptionDetectionEnabled() && + ((1u << m_MemoryTypeIndex) & m_hAllocator->GetGpuDefragmentationMemoryTypeBits()) != 0; + + // There are options to defragment this memory type. + if(canDefragmentOnCpu || canDefragmentOnGpu) { - m_pDefragmentator = vma_new(m_hAllocator, VmaDefragmentator)( - hAllocator, - this, - currentFrameIndex); - } - - return m_pDefragmentator; -} - -VkResult VmaBlockVector::Defragment( - VmaDefragmentationStats* pDefragmentationStats, - VkDeviceSize& maxBytesToMove, - uint32_t& maxAllocationsToMove) -{ - if(m_pDefragmentator == VMA_NULL) - { - return VK_SUCCESS; - } - - VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex); - - // Defragment. - VkResult result = m_pDefragmentator->Defragment(maxBytesToMove, maxAllocationsToMove); - - // Accumulate statistics. - if(pDefragmentationStats != VMA_NULL) - { - const VkDeviceSize bytesMoved = m_pDefragmentator->GetBytesMoved(); - const uint32_t allocationsMoved = m_pDefragmentator->GetAllocationsMoved(); - pDefragmentationStats->bytesMoved += bytesMoved; - pDefragmentationStats->allocationsMoved += allocationsMoved; - VMA_ASSERT(bytesMoved <= maxBytesToMove); - VMA_ASSERT(allocationsMoved <= maxAllocationsToMove); - maxBytesToMove -= bytesMoved; - maxAllocationsToMove -= allocationsMoved; - } - - // Free empty blocks. - m_HasEmptyBlock = false; - for(size_t blockIndex = m_Blocks.size(); blockIndex--; ) - { - VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; - if(pBlock->m_Metadata.IsEmpty()) + bool defragmentOnGpu; + // There is only one option to defragment this memory type. + if(canDefragmentOnGpu != canDefragmentOnCpu) { - if(m_Blocks.size() > m_MinBlockCount) - { - if(pDefragmentationStats != VMA_NULL) - { - ++pDefragmentationStats->deviceMemoryBlocksFreed; - pDefragmentationStats->bytesFreed += pBlock->m_Metadata.GetSize(); - } + defragmentOnGpu = canDefragmentOnGpu; + } + // Both options are available: Heuristics to choose the best one. + else + { + defragmentOnGpu = (memPropFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 || + m_hAllocator->IsIntegratedGpu(); + } - VmaVectorRemove(m_Blocks, blockIndex); - pBlock->Destroy(m_hAllocator); - vma_delete(m_hAllocator, pBlock); + bool overlappingMoveSupported = !defragmentOnGpu; + + if(m_hAllocator->m_UseMutex) + { + if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL) + { + if(!m_Mutex.TryLockWrite()) + { + pCtx->res = VK_ERROR_INITIALIZATION_FAILED; + return; + } } else { - m_HasEmptyBlock = true; + m_Mutex.LockWrite(); + pCtx->mutexLocked = true; + } + } + + pCtx->Begin(overlappingMoveSupported, flags); + + // Defragment. + + const VkDeviceSize maxBytesToMove = defragmentOnGpu ? maxGpuBytesToMove : maxCpuBytesToMove; + const uint32_t maxAllocationsToMove = defragmentOnGpu ? maxGpuAllocationsToMove : maxCpuAllocationsToMove; + pCtx->res = pCtx->GetAlgorithm()->Defragment(pCtx->defragmentationMoves, maxBytesToMove, maxAllocationsToMove, flags); + + // Accumulate statistics. + if(pStats != VMA_NULL) + { + const VkDeviceSize bytesMoved = pCtx->GetAlgorithm()->GetBytesMoved(); + const uint32_t allocationsMoved = pCtx->GetAlgorithm()->GetAllocationsMoved(); + pStats->bytesMoved += bytesMoved; + pStats->allocationsMoved += allocationsMoved; + VMA_ASSERT(bytesMoved <= maxBytesToMove); + VMA_ASSERT(allocationsMoved <= maxAllocationsToMove); + if(defragmentOnGpu) + { + maxGpuBytesToMove -= bytesMoved; + maxGpuAllocationsToMove -= allocationsMoved; + } + else + { + maxCpuBytesToMove -= bytesMoved; + maxCpuAllocationsToMove -= allocationsMoved; + } + } + + if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL) + { + if(m_hAllocator->m_UseMutex) + m_Mutex.UnlockWrite(); + + if(pCtx->res >= VK_SUCCESS && !pCtx->defragmentationMoves.empty()) + pCtx->res = VK_NOT_READY; + + return; + } + + if(pCtx->res >= VK_SUCCESS) + { + if(defragmentOnGpu) + { + ApplyDefragmentationMovesGpu(pCtx, pCtx->defragmentationMoves, commandBuffer); + } + else + { + ApplyDefragmentationMovesCpu(pCtx, pCtx->defragmentationMoves); } } } +} +void VmaBlockVector::DefragmentationEnd( + class VmaBlockVectorDefragmentationContext* pCtx, + uint32_t flags, + VmaDefragmentationStats* pStats) +{ + if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL && m_hAllocator->m_UseMutex) + { + VMA_ASSERT(pCtx->mutexLocked == false); + + // Incremental defragmentation doesn't hold the lock, so when we enter here we don't actually have any + // lock protecting us. Since we mutate state here, we have to take the lock out now + m_Mutex.LockWrite(); + pCtx->mutexLocked = true; + } + + // If the mutex isn't locked we didn't do any work and there is nothing to delete. + if(pCtx->mutexLocked || !m_hAllocator->m_UseMutex) + { + // Destroy buffers. + for(size_t blockIndex = pCtx->blockContexts.size(); blockIndex--;) + { + VmaBlockDefragmentationContext &blockCtx = pCtx->blockContexts[blockIndex]; + if(blockCtx.hBuffer) + { + (*m_hAllocator->GetVulkanFunctions().vkDestroyBuffer)(m_hAllocator->m_hDevice, blockCtx.hBuffer, m_hAllocator->GetAllocationCallbacks()); + } + } + + if(pCtx->res >= VK_SUCCESS) + { + FreeEmptyBlocks(pStats); + } + } + + if(pCtx->mutexLocked) + { + VMA_ASSERT(m_hAllocator->m_UseMutex); + m_Mutex.UnlockWrite(); + } +} + +uint32_t VmaBlockVector::ProcessDefragmentations( + class VmaBlockVectorDefragmentationContext *pCtx, + VmaDefragmentationPassMoveInfo* pMove, uint32_t maxMoves) +{ + VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); + + const uint32_t moveCount = VMA_MIN(uint32_t(pCtx->defragmentationMoves.size()) - pCtx->defragmentationMovesProcessed, maxMoves); + + for(uint32_t i = 0; i < moveCount; ++ i) + { + VmaDefragmentationMove& move = pCtx->defragmentationMoves[pCtx->defragmentationMovesProcessed + i]; + + pMove->allocation = move.hAllocation; + pMove->memory = move.pDstBlock->GetDeviceMemory(); + pMove->offset = move.dstOffset; + + ++ pMove; + } + + pCtx->defragmentationMovesProcessed += moveCount; + + return moveCount; +} + +void VmaBlockVector::CommitDefragmentations( + class VmaBlockVectorDefragmentationContext *pCtx, + VmaDefragmentationStats* pStats) +{ + VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); + + for(uint32_t i = pCtx->defragmentationMovesCommitted; i < pCtx->defragmentationMovesProcessed; ++ i) + { + const VmaDefragmentationMove &move = pCtx->defragmentationMoves[i]; + + move.pSrcBlock->m_pMetadata->FreeAtOffset(move.srcOffset); + move.hAllocation->ChangeBlockAllocation(m_hAllocator, move.pDstBlock, move.dstOffset); + } + + pCtx->defragmentationMovesCommitted = pCtx->defragmentationMovesProcessed; + FreeEmptyBlocks(pStats); +} + +size_t VmaBlockVector::CalcAllocationCount() const +{ + size_t result = 0; + for(size_t i = 0; i < m_Blocks.size(); ++i) + { + result += m_Blocks[i]->m_pMetadata->GetAllocationCount(); + } return result; } -void VmaBlockVector::DestroyDefragmentator() +bool VmaBlockVector::IsBufferImageGranularityConflictPossible() const { - if(m_pDefragmentator != VMA_NULL) + if(m_BufferImageGranularity == 1) { - vma_delete(m_hAllocator, m_pDefragmentator); - m_pDefragmentator = VMA_NULL; + return false; } + VmaSuballocationType lastSuballocType = VMA_SUBALLOCATION_TYPE_FREE; + for(size_t i = 0, count = m_Blocks.size(); i < count; ++i) + { + VmaDeviceMemoryBlock* const pBlock = m_Blocks[i]; + VMA_ASSERT(m_Algorithm == 0); + VmaBlockMetadata_Generic* const pMetadata = (VmaBlockMetadata_Generic*)pBlock->m_pMetadata; + if(pMetadata->IsBufferImageGranularityConflictPossible(m_BufferImageGranularity, lastSuballocType)) + { + return true; + } + } + return false; } void VmaBlockVector::MakePoolAllocationsLost( uint32_t currentFrameIndex, size_t* pLostAllocationCount) { - VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex); + VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); size_t lostAllocationCount = 0; for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) { VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; VMA_ASSERT(pBlock); - lostAllocationCount += pBlock->m_Metadata.MakeAllocationsLost(currentFrameIndex, m_FrameInUseCount); + lostAllocationCount += pBlock->m_pMetadata->MakeAllocationsLost(currentFrameIndex, m_FrameInUseCount); } if(pLostAllocationCount != VMA_NULL) { @@ -7068,12 +12405,33 @@ void VmaBlockVector::MakePoolAllocationsLost( } } +VkResult VmaBlockVector::CheckCorruption() +{ + if(!IsCorruptionDetectionEnabled()) + { + return VK_ERROR_FEATURE_NOT_PRESENT; + } + + VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); + for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) + { + VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pBlock); + VkResult res = pBlock->CheckCorruption(m_hAllocator); + if(res != VK_SUCCESS) + { + return res; + } + } + return VK_SUCCESS; +} + void VmaBlockVector::AddStats(VmaStats* pStats) { const uint32_t memTypeIndex = m_MemoryTypeIndex; const uint32_t memHeapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(memTypeIndex); - VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex); + VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) { @@ -7081,7 +12439,7 @@ void VmaBlockVector::AddStats(VmaStats* pStats) VMA_ASSERT(pBlock); VMA_HEAVY_ASSERT(pBlock->Validate()); VmaStatInfo allocationStatInfo; - pBlock->m_Metadata.CalcAllocationStatInfo(allocationStatInfo); + pBlock->m_pMetadata->CalcAllocationStatInfo(allocationStatInfo); VmaAddStatInfo(pStats->total, allocationStatInfo); VmaAddStatInfo(pStats->memoryType[memTypeIndex], allocationStatInfo); VmaAddStatInfo(pStats->memoryHeap[memHeapIndex], allocationStatInfo); @@ -7089,23 +12447,35 @@ void VmaBlockVector::AddStats(VmaStats* pStats) } //////////////////////////////////////////////////////////////////////////////// -// VmaDefragmentator members definition +// VmaDefragmentationAlgorithm_Generic members definition -VmaDefragmentator::VmaDefragmentator( +VmaDefragmentationAlgorithm_Generic::VmaDefragmentationAlgorithm_Generic( VmaAllocator hAllocator, VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex) : - m_hAllocator(hAllocator), - m_pBlockVector(pBlockVector), - m_CurrentFrameIndex(currentFrameIndex), + uint32_t currentFrameIndex, + bool overlappingMoveSupported) : + VmaDefragmentationAlgorithm(hAllocator, pBlockVector, currentFrameIndex), + m_AllocationCount(0), + m_AllAllocations(false), m_BytesMoved(0), m_AllocationsMoved(0), - m_Allocations(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), m_Blocks(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) { + // Create block info for each block. + const size_t blockCount = m_pBlockVector->m_Blocks.size(); + for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) + { + BlockInfo* pBlockInfo = vma_new(m_hAllocator, BlockInfo)(m_hAllocator->GetAllocationCallbacks()); + pBlockInfo->m_OriginalBlockIndex = blockIndex; + pBlockInfo->m_pBlock = m_pBlockVector->m_Blocks[blockIndex]; + m_Blocks.push_back(pBlockInfo); + } + + // Sort them by m_pBlock pointer value. + VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockPointerLess()); } -VmaDefragmentator::~VmaDefragmentator() +VmaDefragmentationAlgorithm_Generic::~VmaDefragmentationAlgorithm_Generic() { for(size_t i = m_Blocks.size(); i--; ) { @@ -7113,66 +12483,72 @@ VmaDefragmentator::~VmaDefragmentator() } } -void VmaDefragmentator::AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) +void VmaDefragmentationAlgorithm_Generic::AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) { - AllocationInfo allocInfo; - allocInfo.m_hAllocation = hAlloc; - allocInfo.m_pChanged = pChanged; - m_Allocations.push_back(allocInfo); -} + // Now as we are inside VmaBlockVector::m_Mutex, we can make final check if this allocation was not lost. + if(hAlloc->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST) + { + VmaDeviceMemoryBlock* pBlock = hAlloc->GetBlock(); + BlockInfoVector::iterator it = VmaBinaryFindFirstNotLess(m_Blocks.begin(), m_Blocks.end(), pBlock, BlockPointerLess()); + if(it != m_Blocks.end() && (*it)->m_pBlock == pBlock) + { + AllocationInfo allocInfo = AllocationInfo(hAlloc, pChanged); + (*it)->m_Allocations.push_back(allocInfo); + } + else + { + VMA_ASSERT(0); + } -VkResult VmaDefragmentator::BlockInfo::EnsureMapping(VmaAllocator hAllocator, void** ppMappedData) -{ - // It has already been mapped for defragmentation. - if(m_pMappedDataForDefragmentation) - { - *ppMappedData = m_pMappedDataForDefragmentation; - return VK_SUCCESS; - } - - // It is originally mapped. - if(m_pBlock->GetMappedData()) - { - *ppMappedData = m_pBlock->GetMappedData(); - return VK_SUCCESS; - } - - // Map on first usage. - VkResult res = m_pBlock->Map(hAllocator, 1, &m_pMappedDataForDefragmentation); - *ppMappedData = m_pMappedDataForDefragmentation; - return res; -} - -void VmaDefragmentator::BlockInfo::Unmap(VmaAllocator hAllocator) -{ - if(m_pMappedDataForDefragmentation != VMA_NULL) - { - m_pBlock->Unmap(hAllocator, 1); + ++m_AllocationCount; } } -VkResult VmaDefragmentator::DefragmentRound( +VkResult VmaDefragmentationAlgorithm_Generic::DefragmentRound( + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove) + uint32_t maxAllocationsToMove, + bool freeOldAllocations) { if(m_Blocks.empty()) { return VK_SUCCESS; } + // This is a choice based on research. + // Option 1: + uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT; + // Option 2: + //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT; + // Option 3: + //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT; + + size_t srcBlockMinIndex = 0; + // When FAST_ALGORITHM, move allocations from only last out of blocks that contain non-movable allocations. + /* + if(m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) + { + const size_t blocksWithNonMovableCount = CalcBlocksWithNonMovableCount(); + if(blocksWithNonMovableCount > 0) + { + srcBlockMinIndex = blocksWithNonMovableCount - 1; + } + } + */ + size_t srcBlockIndex = m_Blocks.size() - 1; size_t srcAllocIndex = SIZE_MAX; for(;;) { // 1. Find next allocation to move. // 1.1. Start from last to first m_Blocks - they are sorted from most "destination" to most "source". - // 1.2. Then start from last to first m_Allocations - they are sorted from largest to smallest. + // 1.2. Then start from last to first m_Allocations. while(srcAllocIndex >= m_Blocks[srcBlockIndex]->m_Allocations.size()) { if(m_Blocks[srcBlockIndex]->m_Allocations.empty()) { // Finished: no more allocations to process. - if(srcBlockIndex == 0) + if(srcBlockIndex == srcBlockMinIndex) { return VK_SUCCESS; } @@ -7187,7 +12563,7 @@ VkResult VmaDefragmentator::DefragmentRound( srcAllocIndex = m_Blocks[srcBlockIndex]->m_Allocations.size() - 1; } } - + BlockInfo* pSrcBlockInfo = m_Blocks[srcBlockIndex]; AllocationInfo& allocInfo = pSrcBlockInfo->m_Allocations[srcAllocIndex]; @@ -7201,14 +12577,16 @@ VkResult VmaDefragmentator::DefragmentRound( { BlockInfo* pDstBlockInfo = m_Blocks[dstBlockIndex]; VmaAllocationRequest dstAllocRequest; - if(pDstBlockInfo->m_pBlock->m_Metadata.CreateAllocationRequest( + if(pDstBlockInfo->m_pBlock->m_pMetadata->CreateAllocationRequest( m_CurrentFrameIndex, m_pBlockVector->GetFrameInUseCount(), m_pBlockVector->GetBufferImageGranularity(), size, alignment, + false, // upperAddress suballocType, false, // canMakeOtherLost + strategy, &dstAllocRequest) && MoveMakesSense( dstBlockIndex, dstAllocRequest.offset, srcBlockIndex, srcOffset)) @@ -7219,33 +12597,32 @@ VkResult VmaDefragmentator::DefragmentRound( if((m_AllocationsMoved + 1 > maxAllocationsToMove) || (m_BytesMoved + size > maxBytesToMove)) { - return VK_INCOMPLETE; + return VK_SUCCESS; } - void* pDstMappedData = VMA_NULL; - VkResult res = pDstBlockInfo->EnsureMapping(m_hAllocator, &pDstMappedData); - if(res != VK_SUCCESS) - { - return res; - } + VmaDefragmentationMove move = {}; + move.srcBlockIndex = pSrcBlockInfo->m_OriginalBlockIndex; + move.dstBlockIndex = pDstBlockInfo->m_OriginalBlockIndex; + move.srcOffset = srcOffset; + move.dstOffset = dstAllocRequest.offset; + move.size = size; + move.hAllocation = allocInfo.m_hAllocation; + move.pSrcBlock = pSrcBlockInfo->m_pBlock; + move.pDstBlock = pDstBlockInfo->m_pBlock; - void* pSrcMappedData = VMA_NULL; - res = pSrcBlockInfo->EnsureMapping(m_hAllocator, &pSrcMappedData); - if(res != VK_SUCCESS) + moves.push_back(move); + + pDstBlockInfo->m_pBlock->m_pMetadata->Alloc( + dstAllocRequest, + suballocType, + size, + allocInfo.m_hAllocation); + + if(freeOldAllocations) { - return res; + pSrcBlockInfo->m_pBlock->m_pMetadata->FreeAtOffset(srcOffset); + allocInfo.m_hAllocation->ChangeBlockAllocation(m_hAllocator, pDstBlockInfo->m_pBlock, dstAllocRequest.offset); } - - // THE PLACE WHERE ACTUAL DATA COPY HAPPENS. - memcpy( - reinterpret_cast(pDstMappedData) + dstAllocRequest.offset, - reinterpret_cast(pSrcMappedData) + srcOffset, - static_cast(size)); - - pDstBlockInfo->m_pBlock->m_Metadata.Alloc(dstAllocRequest, suballocType, size, allocInfo.m_hAllocation); - pSrcBlockInfo->m_pBlock->m_Metadata.FreeAtOffset(srcOffset); - - allocInfo.m_hAllocation->ChangeBlockAllocation(m_hAllocator, pDstBlockInfo->m_pBlock, dstAllocRequest.offset); if(allocInfo.m_pChanged != VMA_NULL) { @@ -7282,75 +12659,76 @@ VkResult VmaDefragmentator::DefragmentRound( } } -VkResult VmaDefragmentator::Defragment( - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove) +size_t VmaDefragmentationAlgorithm_Generic::CalcBlocksWithNonMovableCount() const { - if(m_Allocations.empty()) + size_t result = 0; + for(size_t i = 0; i < m_Blocks.size(); ++i) + { + if(m_Blocks[i]->m_HasNonMovableAllocations) + { + ++result; + } + } + return result; +} + +VkResult VmaDefragmentationAlgorithm_Generic::Defragment( + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, + VkDeviceSize maxBytesToMove, + uint32_t maxAllocationsToMove, + VmaDefragmentationFlags flags) +{ + if(!m_AllAllocations && m_AllocationCount == 0) { return VK_SUCCESS; } - // Create block info for each block. - const size_t blockCount = m_pBlockVector->m_Blocks.size(); - for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) - { - BlockInfo* pBlockInfo = vma_new(m_hAllocator, BlockInfo)(m_hAllocator->GetAllocationCallbacks()); - pBlockInfo->m_pBlock = m_pBlockVector->m_Blocks[blockIndex]; - m_Blocks.push_back(pBlockInfo); - } - - // Sort them by m_pBlock pointer value. - VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockPointerLess()); - - // Move allocation infos from m_Allocations to appropriate m_Blocks[memTypeIndex].m_Allocations. - for(size_t blockIndex = 0, allocCount = m_Allocations.size(); blockIndex < allocCount; ++blockIndex) - { - AllocationInfo& allocInfo = m_Allocations[blockIndex]; - // Now as we are inside VmaBlockVector::m_Mutex, we can make final check if this allocation was not lost. - if(allocInfo.m_hAllocation->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST) - { - VmaDeviceMemoryBlock* pBlock = allocInfo.m_hAllocation->GetBlock(); - BlockInfoVector::iterator it = VmaBinaryFindFirstNotLess(m_Blocks.begin(), m_Blocks.end(), pBlock, BlockPointerLess()); - if(it != m_Blocks.end() && (*it)->m_pBlock == pBlock) - { - (*it)->m_Allocations.push_back(allocInfo); - } - else - { - VMA_ASSERT(0); - } - } - } - m_Allocations.clear(); - + const size_t blockCount = m_Blocks.size(); for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) { BlockInfo* pBlockInfo = m_Blocks[blockIndex]; + + if(m_AllAllocations) + { + VmaBlockMetadata_Generic* pMetadata = (VmaBlockMetadata_Generic*)pBlockInfo->m_pBlock->m_pMetadata; + for(VmaSuballocationList::const_iterator it = pMetadata->m_Suballocations.begin(); + it != pMetadata->m_Suballocations.end(); + ++it) + { + if(it->type != VMA_SUBALLOCATION_TYPE_FREE) + { + AllocationInfo allocInfo = AllocationInfo(it->hAllocation, VMA_NULL); + pBlockInfo->m_Allocations.push_back(allocInfo); + } + } + } + pBlockInfo->CalcHasNonMovableAllocations(); - pBlockInfo->SortAllocationsBySizeDescecnding(); + + // This is a choice based on research. + // Option 1: + pBlockInfo->SortAllocationsByOffsetDescending(); + // Option 2: + //pBlockInfo->SortAllocationsBySizeDescending(); } // Sort m_Blocks this time by the main criterium, from most "destination" to most "source" blocks. VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockInfoCompareMoveDestination()); + // This is a choice based on research. + const uint32_t roundCount = 2; + // Execute defragmentation rounds (the main part). VkResult result = VK_SUCCESS; - for(size_t round = 0; (round < 2) && (result == VK_SUCCESS); ++round) + for(uint32_t round = 0; (round < roundCount) && (result == VK_SUCCESS); ++round) { - result = DefragmentRound(maxBytesToMove, maxAllocationsToMove); - } - - // Unmap blocks that were mapped for defragmentation. - for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) - { - m_Blocks[blockIndex]->Unmap(m_hAllocator); + result = DefragmentRound(moves, maxBytesToMove, maxAllocationsToMove, !(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL)); } return result; } -bool VmaDefragmentator::MoveMakesSense( +bool VmaDefragmentationAlgorithm_Generic::MoveMakesSense( size_t dstBlockIndex, VkDeviceSize dstOffset, size_t srcBlockIndex, VkDeviceSize srcOffset) { @@ -7369,37 +12747,1535 @@ bool VmaDefragmentator::MoveMakesSense( return false; } +//////////////////////////////////////////////////////////////////////////////// +// VmaDefragmentationAlgorithm_Fast + +VmaDefragmentationAlgorithm_Fast::VmaDefragmentationAlgorithm_Fast( + VmaAllocator hAllocator, + VmaBlockVector* pBlockVector, + uint32_t currentFrameIndex, + bool overlappingMoveSupported) : + VmaDefragmentationAlgorithm(hAllocator, pBlockVector, currentFrameIndex), + m_OverlappingMoveSupported(overlappingMoveSupported), + m_AllocationCount(0), + m_AllAllocations(false), + m_BytesMoved(0), + m_AllocationsMoved(0), + m_BlockInfos(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) +{ + VMA_ASSERT(VMA_DEBUG_MARGIN == 0); + +} + +VmaDefragmentationAlgorithm_Fast::~VmaDefragmentationAlgorithm_Fast() +{ +} + +VkResult VmaDefragmentationAlgorithm_Fast::Defragment( + VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, + VkDeviceSize maxBytesToMove, + uint32_t maxAllocationsToMove, + VmaDefragmentationFlags flags) +{ + VMA_ASSERT(m_AllAllocations || m_pBlockVector->CalcAllocationCount() == m_AllocationCount); + + const size_t blockCount = m_pBlockVector->GetBlockCount(); + if(blockCount == 0 || maxBytesToMove == 0 || maxAllocationsToMove == 0) + { + return VK_SUCCESS; + } + + PreprocessMetadata(); + + // Sort blocks in order from most destination. + + m_BlockInfos.resize(blockCount); + for(size_t i = 0; i < blockCount; ++i) + { + m_BlockInfos[i].origBlockIndex = i; + } + + VMA_SORT(m_BlockInfos.begin(), m_BlockInfos.end(), [this](const BlockInfo& lhs, const BlockInfo& rhs) -> bool { + return m_pBlockVector->GetBlock(lhs.origBlockIndex)->m_pMetadata->GetSumFreeSize() < + m_pBlockVector->GetBlock(rhs.origBlockIndex)->m_pMetadata->GetSumFreeSize(); + }); + + // THE MAIN ALGORITHM + + FreeSpaceDatabase freeSpaceDb; + + size_t dstBlockInfoIndex = 0; + size_t dstOrigBlockIndex = m_BlockInfos[dstBlockInfoIndex].origBlockIndex; + VmaDeviceMemoryBlock* pDstBlock = m_pBlockVector->GetBlock(dstOrigBlockIndex); + VmaBlockMetadata_Generic* pDstMetadata = (VmaBlockMetadata_Generic*)pDstBlock->m_pMetadata; + VkDeviceSize dstBlockSize = pDstMetadata->GetSize(); + VkDeviceSize dstOffset = 0; + + bool end = false; + for(size_t srcBlockInfoIndex = 0; !end && srcBlockInfoIndex < blockCount; ++srcBlockInfoIndex) + { + const size_t srcOrigBlockIndex = m_BlockInfos[srcBlockInfoIndex].origBlockIndex; + VmaDeviceMemoryBlock* const pSrcBlock = m_pBlockVector->GetBlock(srcOrigBlockIndex); + VmaBlockMetadata_Generic* const pSrcMetadata = (VmaBlockMetadata_Generic*)pSrcBlock->m_pMetadata; + for(VmaSuballocationList::iterator srcSuballocIt = pSrcMetadata->m_Suballocations.begin(); + !end && srcSuballocIt != pSrcMetadata->m_Suballocations.end(); ) + { + VmaAllocation_T* const pAlloc = srcSuballocIt->hAllocation; + const VkDeviceSize srcAllocAlignment = pAlloc->GetAlignment(); + const VkDeviceSize srcAllocSize = srcSuballocIt->size; + if(m_AllocationsMoved == maxAllocationsToMove || + m_BytesMoved + srcAllocSize > maxBytesToMove) + { + end = true; + break; + } + const VkDeviceSize srcAllocOffset = srcSuballocIt->offset; + + VmaDefragmentationMove move = {}; + // Try to place it in one of free spaces from the database. + size_t freeSpaceInfoIndex; + VkDeviceSize dstAllocOffset; + if(freeSpaceDb.Fetch(srcAllocAlignment, srcAllocSize, + freeSpaceInfoIndex, dstAllocOffset)) + { + size_t freeSpaceOrigBlockIndex = m_BlockInfos[freeSpaceInfoIndex].origBlockIndex; + VmaDeviceMemoryBlock* pFreeSpaceBlock = m_pBlockVector->GetBlock(freeSpaceOrigBlockIndex); + VmaBlockMetadata_Generic* pFreeSpaceMetadata = (VmaBlockMetadata_Generic*)pFreeSpaceBlock->m_pMetadata; + + // Same block + if(freeSpaceInfoIndex == srcBlockInfoIndex) + { + VMA_ASSERT(dstAllocOffset <= srcAllocOffset); + + // MOVE OPTION 1: Move the allocation inside the same block by decreasing offset. + + VmaSuballocation suballoc = *srcSuballocIt; + suballoc.offset = dstAllocOffset; + suballoc.hAllocation->ChangeOffset(dstAllocOffset); + m_BytesMoved += srcAllocSize; + ++m_AllocationsMoved; + + VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt; + ++nextSuballocIt; + pSrcMetadata->m_Suballocations.erase(srcSuballocIt); + srcSuballocIt = nextSuballocIt; + + InsertSuballoc(pFreeSpaceMetadata, suballoc); + + move.srcBlockIndex = srcOrigBlockIndex; + move.dstBlockIndex = freeSpaceOrigBlockIndex; + move.srcOffset = srcAllocOffset; + move.dstOffset = dstAllocOffset; + move.size = srcAllocSize; + + moves.push_back(move); + } + // Different block + else + { + // MOVE OPTION 2: Move the allocation to a different block. + + VMA_ASSERT(freeSpaceInfoIndex < srcBlockInfoIndex); + + VmaSuballocation suballoc = *srcSuballocIt; + suballoc.offset = dstAllocOffset; + suballoc.hAllocation->ChangeBlockAllocation(m_hAllocator, pFreeSpaceBlock, dstAllocOffset); + m_BytesMoved += srcAllocSize; + ++m_AllocationsMoved; + + VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt; + ++nextSuballocIt; + pSrcMetadata->m_Suballocations.erase(srcSuballocIt); + srcSuballocIt = nextSuballocIt; + + InsertSuballoc(pFreeSpaceMetadata, suballoc); + + move.srcBlockIndex = srcOrigBlockIndex; + move.dstBlockIndex = freeSpaceOrigBlockIndex; + move.srcOffset = srcAllocOffset; + move.dstOffset = dstAllocOffset; + move.size = srcAllocSize; + + moves.push_back(move); + } + } + else + { + dstAllocOffset = VmaAlignUp(dstOffset, srcAllocAlignment); + + // If the allocation doesn't fit before the end of dstBlock, forward to next block. + while(dstBlockInfoIndex < srcBlockInfoIndex && + dstAllocOffset + srcAllocSize > dstBlockSize) + { + // But before that, register remaining free space at the end of dst block. + freeSpaceDb.Register(dstBlockInfoIndex, dstOffset, dstBlockSize - dstOffset); + + ++dstBlockInfoIndex; + dstOrigBlockIndex = m_BlockInfos[dstBlockInfoIndex].origBlockIndex; + pDstBlock = m_pBlockVector->GetBlock(dstOrigBlockIndex); + pDstMetadata = (VmaBlockMetadata_Generic*)pDstBlock->m_pMetadata; + dstBlockSize = pDstMetadata->GetSize(); + dstOffset = 0; + dstAllocOffset = 0; + } + + // Same block + if(dstBlockInfoIndex == srcBlockInfoIndex) + { + VMA_ASSERT(dstAllocOffset <= srcAllocOffset); + + const bool overlap = dstAllocOffset + srcAllocSize > srcAllocOffset; + + bool skipOver = overlap; + if(overlap && m_OverlappingMoveSupported && dstAllocOffset < srcAllocOffset) + { + // If destination and source place overlap, skip if it would move it + // by only < 1/64 of its size. + skipOver = (srcAllocOffset - dstAllocOffset) * 64 < srcAllocSize; + } + + if(skipOver) + { + freeSpaceDb.Register(dstBlockInfoIndex, dstOffset, srcAllocOffset - dstOffset); + + dstOffset = srcAllocOffset + srcAllocSize; + ++srcSuballocIt; + } + // MOVE OPTION 1: Move the allocation inside the same block by decreasing offset. + else + { + srcSuballocIt->offset = dstAllocOffset; + srcSuballocIt->hAllocation->ChangeOffset(dstAllocOffset); + dstOffset = dstAllocOffset + srcAllocSize; + m_BytesMoved += srcAllocSize; + ++m_AllocationsMoved; + ++srcSuballocIt; + + move.srcBlockIndex = srcOrigBlockIndex; + move.dstBlockIndex = dstOrigBlockIndex; + move.srcOffset = srcAllocOffset; + move.dstOffset = dstAllocOffset; + move.size = srcAllocSize; + + moves.push_back(move); + } + } + // Different block + else + { + // MOVE OPTION 2: Move the allocation to a different block. + + VMA_ASSERT(dstBlockInfoIndex < srcBlockInfoIndex); + VMA_ASSERT(dstAllocOffset + srcAllocSize <= dstBlockSize); + + VmaSuballocation suballoc = *srcSuballocIt; + suballoc.offset = dstAllocOffset; + suballoc.hAllocation->ChangeBlockAllocation(m_hAllocator, pDstBlock, dstAllocOffset); + dstOffset = dstAllocOffset + srcAllocSize; + m_BytesMoved += srcAllocSize; + ++m_AllocationsMoved; + + VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt; + ++nextSuballocIt; + pSrcMetadata->m_Suballocations.erase(srcSuballocIt); + srcSuballocIt = nextSuballocIt; + + pDstMetadata->m_Suballocations.push_back(suballoc); + + move.srcBlockIndex = srcOrigBlockIndex; + move.dstBlockIndex = dstOrigBlockIndex; + move.srcOffset = srcAllocOffset; + move.dstOffset = dstAllocOffset; + move.size = srcAllocSize; + + moves.push_back(move); + } + } + } + } + + m_BlockInfos.clear(); + + PostprocessMetadata(); + + return VK_SUCCESS; +} + +void VmaDefragmentationAlgorithm_Fast::PreprocessMetadata() +{ + const size_t blockCount = m_pBlockVector->GetBlockCount(); + for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) + { + VmaBlockMetadata_Generic* const pMetadata = + (VmaBlockMetadata_Generic*)m_pBlockVector->GetBlock(blockIndex)->m_pMetadata; + pMetadata->m_FreeCount = 0; + pMetadata->m_SumFreeSize = pMetadata->GetSize(); + pMetadata->m_FreeSuballocationsBySize.clear(); + for(VmaSuballocationList::iterator it = pMetadata->m_Suballocations.begin(); + it != pMetadata->m_Suballocations.end(); ) + { + if(it->type == VMA_SUBALLOCATION_TYPE_FREE) + { + VmaSuballocationList::iterator nextIt = it; + ++nextIt; + pMetadata->m_Suballocations.erase(it); + it = nextIt; + } + else + { + ++it; + } + } + } +} + +void VmaDefragmentationAlgorithm_Fast::PostprocessMetadata() +{ + const size_t blockCount = m_pBlockVector->GetBlockCount(); + for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) + { + VmaBlockMetadata_Generic* const pMetadata = + (VmaBlockMetadata_Generic*)m_pBlockVector->GetBlock(blockIndex)->m_pMetadata; + const VkDeviceSize blockSize = pMetadata->GetSize(); + + // No allocations in this block - entire area is free. + if(pMetadata->m_Suballocations.empty()) + { + pMetadata->m_FreeCount = 1; + //pMetadata->m_SumFreeSize is already set to blockSize. + VmaSuballocation suballoc = { + 0, // offset + blockSize, // size + VMA_NULL, // hAllocation + VMA_SUBALLOCATION_TYPE_FREE }; + pMetadata->m_Suballocations.push_back(suballoc); + pMetadata->RegisterFreeSuballocation(pMetadata->m_Suballocations.begin()); + } + // There are some allocations in this block. + else + { + VkDeviceSize offset = 0; + VmaSuballocationList::iterator it; + for(it = pMetadata->m_Suballocations.begin(); + it != pMetadata->m_Suballocations.end(); + ++it) + { + VMA_ASSERT(it->type != VMA_SUBALLOCATION_TYPE_FREE); + VMA_ASSERT(it->offset >= offset); + + // Need to insert preceding free space. + if(it->offset > offset) + { + ++pMetadata->m_FreeCount; + const VkDeviceSize freeSize = it->offset - offset; + VmaSuballocation suballoc = { + offset, // offset + freeSize, // size + VMA_NULL, // hAllocation + VMA_SUBALLOCATION_TYPE_FREE }; + VmaSuballocationList::iterator precedingFreeIt = pMetadata->m_Suballocations.insert(it, suballoc); + if(freeSize >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) + { + pMetadata->m_FreeSuballocationsBySize.push_back(precedingFreeIt); + } + } + + pMetadata->m_SumFreeSize -= it->size; + offset = it->offset + it->size; + } + + // Need to insert trailing free space. + if(offset < blockSize) + { + ++pMetadata->m_FreeCount; + const VkDeviceSize freeSize = blockSize - offset; + VmaSuballocation suballoc = { + offset, // offset + freeSize, // size + VMA_NULL, // hAllocation + VMA_SUBALLOCATION_TYPE_FREE }; + VMA_ASSERT(it == pMetadata->m_Suballocations.end()); + VmaSuballocationList::iterator trailingFreeIt = pMetadata->m_Suballocations.insert(it, suballoc); + if(freeSize > VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) + { + pMetadata->m_FreeSuballocationsBySize.push_back(trailingFreeIt); + } + } + + VMA_SORT( + pMetadata->m_FreeSuballocationsBySize.begin(), + pMetadata->m_FreeSuballocationsBySize.end(), + VmaSuballocationItemSizeLess()); + } + + VMA_HEAVY_ASSERT(pMetadata->Validate()); + } +} + +void VmaDefragmentationAlgorithm_Fast::InsertSuballoc(VmaBlockMetadata_Generic* pMetadata, const VmaSuballocation& suballoc) +{ + // TODO: Optimize somehow. Remember iterator instead of searching for it linearly. + VmaSuballocationList::iterator it = pMetadata->m_Suballocations.begin(); + while(it != pMetadata->m_Suballocations.end()) + { + if(it->offset < suballoc.offset) + { + ++it; + } + } + pMetadata->m_Suballocations.insert(it, suballoc); +} + +//////////////////////////////////////////////////////////////////////////////// +// VmaBlockVectorDefragmentationContext + +VmaBlockVectorDefragmentationContext::VmaBlockVectorDefragmentationContext( + VmaAllocator hAllocator, + VmaPool hCustomPool, + VmaBlockVector* pBlockVector, + uint32_t currFrameIndex) : + res(VK_SUCCESS), + mutexLocked(false), + blockContexts(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), + defragmentationMoves(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), + defragmentationMovesProcessed(0), + defragmentationMovesCommitted(0), + hasDefragmentationPlan(0), + m_hAllocator(hAllocator), + m_hCustomPool(hCustomPool), + m_pBlockVector(pBlockVector), + m_CurrFrameIndex(currFrameIndex), + m_pAlgorithm(VMA_NULL), + m_Allocations(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), + m_AllAllocations(false) +{ +} + +VmaBlockVectorDefragmentationContext::~VmaBlockVectorDefragmentationContext() +{ + vma_delete(m_hAllocator, m_pAlgorithm); +} + +void VmaBlockVectorDefragmentationContext::AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) +{ + AllocInfo info = { hAlloc, pChanged }; + m_Allocations.push_back(info); +} + +void VmaBlockVectorDefragmentationContext::Begin(bool overlappingMoveSupported, VmaDefragmentationFlags flags) +{ + const bool allAllocations = m_AllAllocations || + m_Allocations.size() == m_pBlockVector->CalcAllocationCount(); + + /******************************** + HERE IS THE CHOICE OF DEFRAGMENTATION ALGORITHM. + ********************************/ + + /* + Fast algorithm is supported only when certain criteria are met: + - VMA_DEBUG_MARGIN is 0. + - All allocations in this block vector are moveable. + - There is no possibility of image/buffer granularity conflict. + - The defragmentation is not incremental + */ + if(VMA_DEBUG_MARGIN == 0 && + allAllocations && + !m_pBlockVector->IsBufferImageGranularityConflictPossible() && + !(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL)) + { + m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm_Fast)( + m_hAllocator, m_pBlockVector, m_CurrFrameIndex, overlappingMoveSupported); + } + else + { + m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm_Generic)( + m_hAllocator, m_pBlockVector, m_CurrFrameIndex, overlappingMoveSupported); + } + + if(allAllocations) + { + m_pAlgorithm->AddAll(); + } + else + { + for(size_t i = 0, count = m_Allocations.size(); i < count; ++i) + { + m_pAlgorithm->AddAllocation(m_Allocations[i].hAlloc, m_Allocations[i].pChanged); + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// VmaDefragmentationContext + +VmaDefragmentationContext_T::VmaDefragmentationContext_T( + VmaAllocator hAllocator, + uint32_t currFrameIndex, + uint32_t flags, + VmaDefragmentationStats* pStats) : + m_hAllocator(hAllocator), + m_CurrFrameIndex(currFrameIndex), + m_Flags(flags), + m_pStats(pStats), + m_CustomPoolContexts(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) +{ + memset(m_DefaultPoolContexts, 0, sizeof(m_DefaultPoolContexts)); +} + +VmaDefragmentationContext_T::~VmaDefragmentationContext_T() +{ + for(size_t i = m_CustomPoolContexts.size(); i--; ) + { + VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[i]; + pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_Flags, m_pStats); + vma_delete(m_hAllocator, pBlockVectorCtx); + } + for(size_t i = m_hAllocator->m_MemProps.memoryTypeCount; i--; ) + { + VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[i]; + if(pBlockVectorCtx) + { + pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_Flags, m_pStats); + vma_delete(m_hAllocator, pBlockVectorCtx); + } + } +} + +void VmaDefragmentationContext_T::AddPools(uint32_t poolCount, const VmaPool* pPools) +{ + for(uint32_t poolIndex = 0; poolIndex < poolCount; ++poolIndex) + { + VmaPool pool = pPools[poolIndex]; + VMA_ASSERT(pool); + // Pools with algorithm other than default are not defragmented. + if(pool->m_BlockVector.GetAlgorithm() == 0) + { + VmaBlockVectorDefragmentationContext* pBlockVectorDefragCtx = VMA_NULL; + + for(size_t i = m_CustomPoolContexts.size(); i--; ) + { + if(m_CustomPoolContexts[i]->GetCustomPool() == pool) + { + pBlockVectorDefragCtx = m_CustomPoolContexts[i]; + break; + } + } + + if(!pBlockVectorDefragCtx) + { + pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)( + m_hAllocator, + pool, + &pool->m_BlockVector, + m_CurrFrameIndex); + m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); + } + + pBlockVectorDefragCtx->AddAll(); + } + } +} + +void VmaDefragmentationContext_T::AddAllocations( + uint32_t allocationCount, + const VmaAllocation* pAllocations, + VkBool32* pAllocationsChanged) +{ + // Dispatch pAllocations among defragmentators. Create them when necessary. + for(uint32_t allocIndex = 0; allocIndex < allocationCount; ++allocIndex) + { + const VmaAllocation hAlloc = pAllocations[allocIndex]; + VMA_ASSERT(hAlloc); + // DedicatedAlloc cannot be defragmented. + if((hAlloc->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK) && + // Lost allocation cannot be defragmented. + (hAlloc->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)) + { + VmaBlockVectorDefragmentationContext* pBlockVectorDefragCtx = VMA_NULL; + + const VmaPool hAllocPool = hAlloc->GetBlock()->GetParentPool(); + // This allocation belongs to custom pool. + if(hAllocPool != VK_NULL_HANDLE) + { + // Pools with algorithm other than default are not defragmented. + if(hAllocPool->m_BlockVector.GetAlgorithm() == 0) + { + for(size_t i = m_CustomPoolContexts.size(); i--; ) + { + if(m_CustomPoolContexts[i]->GetCustomPool() == hAllocPool) + { + pBlockVectorDefragCtx = m_CustomPoolContexts[i]; + break; + } + } + if(!pBlockVectorDefragCtx) + { + pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)( + m_hAllocator, + hAllocPool, + &hAllocPool->m_BlockVector, + m_CurrFrameIndex); + m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); + } + } + } + // This allocation belongs to default pool. + else + { + const uint32_t memTypeIndex = hAlloc->GetMemoryTypeIndex(); + pBlockVectorDefragCtx = m_DefaultPoolContexts[memTypeIndex]; + if(!pBlockVectorDefragCtx) + { + pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)( + m_hAllocator, + VMA_NULL, // hCustomPool + m_hAllocator->m_pBlockVectors[memTypeIndex], + m_CurrFrameIndex); + m_DefaultPoolContexts[memTypeIndex] = pBlockVectorDefragCtx; + } + } + + if(pBlockVectorDefragCtx) + { + VkBool32* const pChanged = (pAllocationsChanged != VMA_NULL) ? + &pAllocationsChanged[allocIndex] : VMA_NULL; + pBlockVectorDefragCtx->AddAllocation(hAlloc, pChanged); + } + } + } +} + +VkResult VmaDefragmentationContext_T::Defragment( + VkDeviceSize maxCpuBytesToMove, uint32_t maxCpuAllocationsToMove, + VkDeviceSize maxGpuBytesToMove, uint32_t maxGpuAllocationsToMove, + VkCommandBuffer commandBuffer, VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags) +{ + if(pStats) + { + memset(pStats, 0, sizeof(VmaDefragmentationStats)); + } + + if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL) + { + // For incremental defragmetnations, we just earmark how much we can move + // The real meat is in the defragmentation steps + m_MaxCpuBytesToMove = maxCpuBytesToMove; + m_MaxCpuAllocationsToMove = maxCpuAllocationsToMove; + + m_MaxGpuBytesToMove = maxGpuBytesToMove; + m_MaxGpuAllocationsToMove = maxGpuAllocationsToMove; + + if(m_MaxCpuBytesToMove == 0 && m_MaxCpuAllocationsToMove == 0 && + m_MaxGpuBytesToMove == 0 && m_MaxGpuAllocationsToMove == 0) + return VK_SUCCESS; + + return VK_NOT_READY; + } + + if(commandBuffer == VK_NULL_HANDLE) + { + maxGpuBytesToMove = 0; + maxGpuAllocationsToMove = 0; + } + + VkResult res = VK_SUCCESS; + + // Process default pools. + for(uint32_t memTypeIndex = 0; + memTypeIndex < m_hAllocator->GetMemoryTypeCount() && res >= VK_SUCCESS; + ++memTypeIndex) + { + VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex]; + if(pBlockVectorCtx) + { + VMA_ASSERT(pBlockVectorCtx->GetBlockVector()); + pBlockVectorCtx->GetBlockVector()->Defragment( + pBlockVectorCtx, + pStats, flags, + maxCpuBytesToMove, maxCpuAllocationsToMove, + maxGpuBytesToMove, maxGpuAllocationsToMove, + commandBuffer); + if(pBlockVectorCtx->res != VK_SUCCESS) + { + res = pBlockVectorCtx->res; + } + } + } + + // Process custom pools. + for(size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size(); + customCtxIndex < customCtxCount && res >= VK_SUCCESS; + ++customCtxIndex) + { + VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex]; + VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector()); + pBlockVectorCtx->GetBlockVector()->Defragment( + pBlockVectorCtx, + pStats, flags, + maxCpuBytesToMove, maxCpuAllocationsToMove, + maxGpuBytesToMove, maxGpuAllocationsToMove, + commandBuffer); + if(pBlockVectorCtx->res != VK_SUCCESS) + { + res = pBlockVectorCtx->res; + } + } + + return res; +} + +VkResult VmaDefragmentationContext_T::DefragmentPassBegin(VmaDefragmentationPassInfo* pInfo) +{ + VmaDefragmentationPassMoveInfo* pCurrentMove = pInfo->pMoves; + uint32_t movesLeft = pInfo->moveCount; + + // Process default pools. + for(uint32_t memTypeIndex = 0; + memTypeIndex < m_hAllocator->GetMemoryTypeCount(); + ++memTypeIndex) + { + VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex]; + if(pBlockVectorCtx) + { + VMA_ASSERT(pBlockVectorCtx->GetBlockVector()); + + if(!pBlockVectorCtx->hasDefragmentationPlan) + { + pBlockVectorCtx->GetBlockVector()->Defragment( + pBlockVectorCtx, + m_pStats, m_Flags, + m_MaxCpuBytesToMove, m_MaxCpuAllocationsToMove, + m_MaxGpuBytesToMove, m_MaxGpuAllocationsToMove, + VK_NULL_HANDLE); + + if(pBlockVectorCtx->res < VK_SUCCESS) + continue; + + pBlockVectorCtx->hasDefragmentationPlan = true; + } + + const uint32_t processed = pBlockVectorCtx->GetBlockVector()->ProcessDefragmentations( + pBlockVectorCtx, + pCurrentMove, movesLeft); + + movesLeft -= processed; + pCurrentMove += processed; + } + } + + // Process custom pools. + for(size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size(); + customCtxIndex < customCtxCount; + ++customCtxIndex) + { + VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex]; + VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector()); + + if(!pBlockVectorCtx->hasDefragmentationPlan) + { + pBlockVectorCtx->GetBlockVector()->Defragment( + pBlockVectorCtx, + m_pStats, m_Flags, + m_MaxCpuBytesToMove, m_MaxCpuAllocationsToMove, + m_MaxGpuBytesToMove, m_MaxGpuAllocationsToMove, + VK_NULL_HANDLE); + + if(pBlockVectorCtx->res < VK_SUCCESS) + continue; + + pBlockVectorCtx->hasDefragmentationPlan = true; + } + + const uint32_t processed = pBlockVectorCtx->GetBlockVector()->ProcessDefragmentations( + pBlockVectorCtx, + pCurrentMove, movesLeft); + + movesLeft -= processed; + pCurrentMove += processed; + } + + pInfo->moveCount = pInfo->moveCount - movesLeft; + + return VK_SUCCESS; +} +VkResult VmaDefragmentationContext_T::DefragmentPassEnd() +{ + VkResult res = VK_SUCCESS; + + // Process default pools. + for(uint32_t memTypeIndex = 0; + memTypeIndex < m_hAllocator->GetMemoryTypeCount(); + ++memTypeIndex) + { + VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex]; + if(pBlockVectorCtx) + { + VMA_ASSERT(pBlockVectorCtx->GetBlockVector()); + + if(!pBlockVectorCtx->hasDefragmentationPlan) + { + res = VK_NOT_READY; + continue; + } + + pBlockVectorCtx->GetBlockVector()->CommitDefragmentations( + pBlockVectorCtx, m_pStats); + + if(pBlockVectorCtx->defragmentationMoves.size() != pBlockVectorCtx->defragmentationMovesCommitted) + res = VK_NOT_READY; + } + } + + // Process custom pools. + for(size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size(); + customCtxIndex < customCtxCount; + ++customCtxIndex) + { + VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex]; + VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector()); + + if(!pBlockVectorCtx->hasDefragmentationPlan) + { + res = VK_NOT_READY; + continue; + } + + pBlockVectorCtx->GetBlockVector()->CommitDefragmentations( + pBlockVectorCtx, m_pStats); + + if(pBlockVectorCtx->defragmentationMoves.size() != pBlockVectorCtx->defragmentationMovesCommitted) + res = VK_NOT_READY; + } + + return res; +} + +//////////////////////////////////////////////////////////////////////////////// +// VmaRecorder + +#if VMA_RECORDING_ENABLED + +VmaRecorder::VmaRecorder() : + m_UseMutex(true), + m_Flags(0), + m_File(VMA_NULL), + m_RecordingStartTime(std::chrono::high_resolution_clock::now()) +{ +} + +VkResult VmaRecorder::Init(const VmaRecordSettings& settings, bool useMutex) +{ + m_UseMutex = useMutex; + m_Flags = settings.flags; + +#if defined(_WIN32) + // Open file for writing. + errno_t err = fopen_s(&m_File, settings.pFilePath, "wb"); + + if(err != 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } +#else + // Open file for writing. + m_File = fopen(settings.pFilePath, "wb"); + + if(m_File == 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } +#endif + + // Write header. + fprintf(m_File, "%s\n", "Vulkan Memory Allocator,Calls recording"); + fprintf(m_File, "%s\n", "1,8"); + + return VK_SUCCESS; +} + +VmaRecorder::~VmaRecorder() +{ + if(m_File != VMA_NULL) + { + fclose(m_File); + } +} + +void VmaRecorder::RecordCreateAllocator(uint32_t frameIndex) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaCreateAllocator\n", callParams.threadId, callParams.time, frameIndex); + Flush(); +} + +void VmaRecorder::RecordDestroyAllocator(uint32_t frameIndex) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaDestroyAllocator\n", callParams.threadId, callParams.time, frameIndex); + Flush(); +} + +void VmaRecorder::RecordCreatePool(uint32_t frameIndex, const VmaPoolCreateInfo& createInfo, VmaPool pool) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaCreatePool,%u,%u,%llu,%llu,%llu,%u,%p\n", callParams.threadId, callParams.time, frameIndex, + createInfo.memoryTypeIndex, + createInfo.flags, + createInfo.blockSize, + (uint64_t)createInfo.minBlockCount, + (uint64_t)createInfo.maxBlockCount, + createInfo.frameInUseCount, + pool); + Flush(); +} + +void VmaRecorder::RecordDestroyPool(uint32_t frameIndex, VmaPool pool) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaDestroyPool,%p\n", callParams.threadId, callParams.time, frameIndex, + pool); + Flush(); +} + +void VmaRecorder::RecordAllocateMemory(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + const VmaAllocationCreateInfo& createInfo, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr(createInfo.flags, createInfo.pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemory,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, + vkMemReq.size, + vkMemReq.alignment, + vkMemReq.memoryTypeBits, + createInfo.flags, + createInfo.usage, + createInfo.requiredFlags, + createInfo.preferredFlags, + createInfo.memoryTypeBits, + createInfo.pool, + allocation, + userDataStr.GetString()); + Flush(); +} + +void VmaRecorder::RecordAllocateMemoryPages(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + const VmaAllocationCreateInfo& createInfo, + uint64_t allocationCount, + const VmaAllocation* pAllocations) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr(createInfo.flags, createInfo.pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryPages,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,", callParams.threadId, callParams.time, frameIndex, + vkMemReq.size, + vkMemReq.alignment, + vkMemReq.memoryTypeBits, + createInfo.flags, + createInfo.usage, + createInfo.requiredFlags, + createInfo.preferredFlags, + createInfo.memoryTypeBits, + createInfo.pool); + PrintPointerList(allocationCount, pAllocations); + fprintf(m_File, ",%s\n", userDataStr.GetString()); + Flush(); +} + +void VmaRecorder::RecordAllocateMemoryForBuffer(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + bool requiresDedicatedAllocation, + bool prefersDedicatedAllocation, + const VmaAllocationCreateInfo& createInfo, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr(createInfo.flags, createInfo.pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryForBuffer,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, + vkMemReq.size, + vkMemReq.alignment, + vkMemReq.memoryTypeBits, + requiresDedicatedAllocation ? 1 : 0, + prefersDedicatedAllocation ? 1 : 0, + createInfo.flags, + createInfo.usage, + createInfo.requiredFlags, + createInfo.preferredFlags, + createInfo.memoryTypeBits, + createInfo.pool, + allocation, + userDataStr.GetString()); + Flush(); +} + +void VmaRecorder::RecordAllocateMemoryForImage(uint32_t frameIndex, + const VkMemoryRequirements& vkMemReq, + bool requiresDedicatedAllocation, + bool prefersDedicatedAllocation, + const VmaAllocationCreateInfo& createInfo, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr(createInfo.flags, createInfo.pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryForImage,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, + vkMemReq.size, + vkMemReq.alignment, + vkMemReq.memoryTypeBits, + requiresDedicatedAllocation ? 1 : 0, + prefersDedicatedAllocation ? 1 : 0, + createInfo.flags, + createInfo.usage, + createInfo.requiredFlags, + createInfo.preferredFlags, + createInfo.memoryTypeBits, + createInfo.pool, + allocation, + userDataStr.GetString()); + Flush(); +} + +void VmaRecorder::RecordFreeMemory(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaFreeMemory,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordFreeMemoryPages(uint32_t frameIndex, + uint64_t allocationCount, + const VmaAllocation* pAllocations) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaFreeMemoryPages,", callParams.threadId, callParams.time, frameIndex); + PrintPointerList(allocationCount, pAllocations); + fprintf(m_File, "\n"); + Flush(); +} + +void VmaRecorder::RecordSetAllocationUserData(uint32_t frameIndex, + VmaAllocation allocation, + const void* pUserData) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr( + allocation->IsUserDataString() ? VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT : 0, + pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaSetAllocationUserData,%p,%s\n", callParams.threadId, callParams.time, frameIndex, + allocation, + userDataStr.GetString()); + Flush(); +} + +void VmaRecorder::RecordCreateLostAllocation(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaCreateLostAllocation,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordMapMemory(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaMapMemory,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordUnmapMemory(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaUnmapMemory,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordFlushAllocation(uint32_t frameIndex, + VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaFlushAllocation,%p,%llu,%llu\n", callParams.threadId, callParams.time, frameIndex, + allocation, + offset, + size); + Flush(); +} + +void VmaRecorder::RecordInvalidateAllocation(uint32_t frameIndex, + VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaInvalidateAllocation,%p,%llu,%llu\n", callParams.threadId, callParams.time, frameIndex, + allocation, + offset, + size); + Flush(); +} + +void VmaRecorder::RecordCreateBuffer(uint32_t frameIndex, + const VkBufferCreateInfo& bufCreateInfo, + const VmaAllocationCreateInfo& allocCreateInfo, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr(allocCreateInfo.flags, allocCreateInfo.pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaCreateBuffer,%u,%llu,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, + bufCreateInfo.flags, + bufCreateInfo.size, + bufCreateInfo.usage, + bufCreateInfo.sharingMode, + allocCreateInfo.flags, + allocCreateInfo.usage, + allocCreateInfo.requiredFlags, + allocCreateInfo.preferredFlags, + allocCreateInfo.memoryTypeBits, + allocCreateInfo.pool, + allocation, + userDataStr.GetString()); + Flush(); +} + +void VmaRecorder::RecordCreateImage(uint32_t frameIndex, + const VkImageCreateInfo& imageCreateInfo, + const VmaAllocationCreateInfo& allocCreateInfo, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + UserDataString userDataStr(allocCreateInfo.flags, allocCreateInfo.pUserData); + fprintf(m_File, "%u,%.3f,%u,vmaCreateImage,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, + imageCreateInfo.flags, + imageCreateInfo.imageType, + imageCreateInfo.format, + imageCreateInfo.extent.width, + imageCreateInfo.extent.height, + imageCreateInfo.extent.depth, + imageCreateInfo.mipLevels, + imageCreateInfo.arrayLayers, + imageCreateInfo.samples, + imageCreateInfo.tiling, + imageCreateInfo.usage, + imageCreateInfo.sharingMode, + imageCreateInfo.initialLayout, + allocCreateInfo.flags, + allocCreateInfo.usage, + allocCreateInfo.requiredFlags, + allocCreateInfo.preferredFlags, + allocCreateInfo.memoryTypeBits, + allocCreateInfo.pool, + allocation, + userDataStr.GetString()); + Flush(); +} + +void VmaRecorder::RecordDestroyBuffer(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaDestroyBuffer,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordDestroyImage(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaDestroyImage,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordTouchAllocation(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaTouchAllocation,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordGetAllocationInfo(uint32_t frameIndex, + VmaAllocation allocation) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaGetAllocationInfo,%p\n", callParams.threadId, callParams.time, frameIndex, + allocation); + Flush(); +} + +void VmaRecorder::RecordMakePoolAllocationsLost(uint32_t frameIndex, + VmaPool pool) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaMakePoolAllocationsLost,%p\n", callParams.threadId, callParams.time, frameIndex, + pool); + Flush(); +} + +void VmaRecorder::RecordDefragmentationBegin(uint32_t frameIndex, + const VmaDefragmentationInfo2& info, + VmaDefragmentationContext ctx) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaDefragmentationBegin,%u,", callParams.threadId, callParams.time, frameIndex, + info.flags); + PrintPointerList(info.allocationCount, info.pAllocations); + fprintf(m_File, ","); + PrintPointerList(info.poolCount, info.pPools); + fprintf(m_File, ",%llu,%u,%llu,%u,%p,%p\n", + info.maxCpuBytesToMove, + info.maxCpuAllocationsToMove, + info.maxGpuBytesToMove, + info.maxGpuAllocationsToMove, + info.commandBuffer, + ctx); + Flush(); +} + +void VmaRecorder::RecordDefragmentationEnd(uint32_t frameIndex, + VmaDefragmentationContext ctx) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaDefragmentationEnd,%p\n", callParams.threadId, callParams.time, frameIndex, + ctx); + Flush(); +} + +void VmaRecorder::RecordSetPoolName(uint32_t frameIndex, + VmaPool pool, + const char* name) +{ + CallParams callParams; + GetBasicParams(callParams); + + VmaMutexLock lock(m_FileMutex, m_UseMutex); + fprintf(m_File, "%u,%.3f,%u,vmaSetPoolName,%p,%s\n", callParams.threadId, callParams.time, frameIndex, + pool, name != VMA_NULL ? name : ""); + Flush(); +} + +VmaRecorder::UserDataString::UserDataString(VmaAllocationCreateFlags allocFlags, const void* pUserData) +{ + if(pUserData != VMA_NULL) + { + if((allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0) + { + m_Str = (const char*)pUserData; + } + else + { + // If VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT is not specified, convert the string's memory address to a string and store it. + snprintf(m_PtrStr, 17, "%p", pUserData); + m_Str = m_PtrStr; + } + } + else + { + m_Str = ""; + } +} + +void VmaRecorder::WriteConfiguration( + const VkPhysicalDeviceProperties& devProps, + const VkPhysicalDeviceMemoryProperties& memProps, + uint32_t vulkanApiVersion, + bool dedicatedAllocationExtensionEnabled, + bool bindMemory2ExtensionEnabled, + bool memoryBudgetExtensionEnabled, + bool deviceCoherentMemoryExtensionEnabled) +{ + fprintf(m_File, "Config,Begin\n"); + + fprintf(m_File, "VulkanApiVersion,%u,%u\n", VK_VERSION_MAJOR(vulkanApiVersion), VK_VERSION_MINOR(vulkanApiVersion)); + + fprintf(m_File, "PhysicalDevice,apiVersion,%u\n", devProps.apiVersion); + fprintf(m_File, "PhysicalDevice,driverVersion,%u\n", devProps.driverVersion); + fprintf(m_File, "PhysicalDevice,vendorID,%u\n", devProps.vendorID); + fprintf(m_File, "PhysicalDevice,deviceID,%u\n", devProps.deviceID); + fprintf(m_File, "PhysicalDevice,deviceType,%u\n", devProps.deviceType); + fprintf(m_File, "PhysicalDevice,deviceName,%s\n", devProps.deviceName); + + fprintf(m_File, "PhysicalDeviceLimits,maxMemoryAllocationCount,%u\n", devProps.limits.maxMemoryAllocationCount); + fprintf(m_File, "PhysicalDeviceLimits,bufferImageGranularity,%llu\n", devProps.limits.bufferImageGranularity); + fprintf(m_File, "PhysicalDeviceLimits,nonCoherentAtomSize,%llu\n", devProps.limits.nonCoherentAtomSize); + + fprintf(m_File, "PhysicalDeviceMemory,HeapCount,%u\n", memProps.memoryHeapCount); + for(uint32_t i = 0; i < memProps.memoryHeapCount; ++i) + { + fprintf(m_File, "PhysicalDeviceMemory,Heap,%u,size,%llu\n", i, memProps.memoryHeaps[i].size); + fprintf(m_File, "PhysicalDeviceMemory,Heap,%u,flags,%u\n", i, memProps.memoryHeaps[i].flags); + } + fprintf(m_File, "PhysicalDeviceMemory,TypeCount,%u\n", memProps.memoryTypeCount); + for(uint32_t i = 0; i < memProps.memoryTypeCount; ++i) + { + fprintf(m_File, "PhysicalDeviceMemory,Type,%u,heapIndex,%u\n", i, memProps.memoryTypes[i].heapIndex); + fprintf(m_File, "PhysicalDeviceMemory,Type,%u,propertyFlags,%u\n", i, memProps.memoryTypes[i].propertyFlags); + } + + fprintf(m_File, "Extension,VK_KHR_dedicated_allocation,%u\n", dedicatedAllocationExtensionEnabled ? 1 : 0); + fprintf(m_File, "Extension,VK_KHR_bind_memory2,%u\n", bindMemory2ExtensionEnabled ? 1 : 0); + fprintf(m_File, "Extension,VK_EXT_memory_budget,%u\n", memoryBudgetExtensionEnabled ? 1 : 0); + fprintf(m_File, "Extension,VK_AMD_device_coherent_memory,%u\n", deviceCoherentMemoryExtensionEnabled ? 1 : 0); + + fprintf(m_File, "Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,%u\n", VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ? 1 : 0); + fprintf(m_File, "Macro,VMA_MIN_ALIGNMENT,%llu\n", (VkDeviceSize)VMA_MIN_ALIGNMENT); + fprintf(m_File, "Macro,VMA_DEBUG_MARGIN,%llu\n", (VkDeviceSize)VMA_DEBUG_MARGIN); + fprintf(m_File, "Macro,VMA_DEBUG_INITIALIZE_ALLOCATIONS,%u\n", VMA_DEBUG_INITIALIZE_ALLOCATIONS ? 1 : 0); + fprintf(m_File, "Macro,VMA_DEBUG_DETECT_CORRUPTION,%u\n", VMA_DEBUG_DETECT_CORRUPTION ? 1 : 0); + fprintf(m_File, "Macro,VMA_DEBUG_GLOBAL_MUTEX,%u\n", VMA_DEBUG_GLOBAL_MUTEX ? 1 : 0); + fprintf(m_File, "Macro,VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,%llu\n", (VkDeviceSize)VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY); + fprintf(m_File, "Macro,VMA_SMALL_HEAP_MAX_SIZE,%llu\n", (VkDeviceSize)VMA_SMALL_HEAP_MAX_SIZE); + fprintf(m_File, "Macro,VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,%llu\n", (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE); + + fprintf(m_File, "Config,End\n"); +} + +void VmaRecorder::GetBasicParams(CallParams& outParams) +{ + #if defined(_WIN32) + outParams.threadId = GetCurrentThreadId(); + #else + // Use C++11 features to get thread id and convert it to uint32_t. + // There is room for optimization since sstream is quite slow. + // Is there a better way to convert std::this_thread::get_id() to uint32_t? + std::thread::id thread_id = std::this_thread::get_id(); + std::stringstream thread_id_to_string_converter; + thread_id_to_string_converter << thread_id; + std::string thread_id_as_string = thread_id_to_string_converter.str(); + outParams.threadId = static_cast(std::stoi(thread_id_as_string.c_str())); + #endif + + auto current_time = std::chrono::high_resolution_clock::now(); + + outParams.time = std::chrono::duration(current_time - m_RecordingStartTime).count(); +} + +void VmaRecorder::PrintPointerList(uint64_t count, const VmaAllocation* pItems) +{ + if(count) + { + fprintf(m_File, "%p", pItems[0]); + for(uint64_t i = 1; i < count; ++i) + { + fprintf(m_File, " %p", pItems[i]); + } + } +} + +void VmaRecorder::Flush() +{ + if((m_Flags & VMA_RECORD_FLUSH_AFTER_CALL_BIT) != 0) + { + fflush(m_File); + } +} + +#endif // #if VMA_RECORDING_ENABLED + +//////////////////////////////////////////////////////////////////////////////// +// VmaAllocationObjectAllocator + +VmaAllocationObjectAllocator::VmaAllocationObjectAllocator(const VkAllocationCallbacks* pAllocationCallbacks) : + m_Allocator(pAllocationCallbacks, 1024) +{ +} + +template VmaAllocation VmaAllocationObjectAllocator::Allocate(Types&&... args) +{ + VmaMutexLock mutexLock(m_Mutex); + return m_Allocator.Alloc(std::forward(args)...); +} + +void VmaAllocationObjectAllocator::Free(VmaAllocation hAlloc) +{ + VmaMutexLock mutexLock(m_Mutex); + m_Allocator.Free(hAlloc); +} + //////////////////////////////////////////////////////////////////////////////// // VmaAllocator_T VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : m_UseMutex((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT) == 0), + m_VulkanApiVersion(pCreateInfo->vulkanApiVersion != 0 ? pCreateInfo->vulkanApiVersion : VK_API_VERSION_1_0), m_UseKhrDedicatedAllocation((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT) != 0), + m_UseKhrBindMemory2((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT) != 0), + m_UseExtMemoryBudget((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT) != 0), + m_UseAmdDeviceCoherentMemory((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT) != 0), + m_UseKhrBufferDeviceAddress((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT) != 0), + m_UseExtMemoryPriority((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT) != 0), m_hDevice(pCreateInfo->device), + m_hInstance(pCreateInfo->instance), m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL), m_AllocationCallbacks(pCreateInfo->pAllocationCallbacks ? *pCreateInfo->pAllocationCallbacks : VmaEmptyAllocationCallbacks), + m_AllocationObjectAllocator(&m_AllocationCallbacks), + m_HeapSizeLimitMask(0), + m_DeviceMemoryCount(0), m_PreferredLargeHeapBlockSize(0), m_PhysicalDevice(pCreateInfo->physicalDevice), m_CurrentFrameIndex(0), - m_Pools(VmaStlAllocator(GetAllocationCallbacks())) + m_GpuDefragmentationMemoryTypeBits(UINT32_MAX), + m_NextPoolId(0), + m_GlobalMemoryTypeBits(UINT32_MAX) +#if VMA_RECORDING_ENABLED + ,m_pRecorder(VMA_NULL) +#endif { - VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device); + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) + { + m_UseKhrDedicatedAllocation = false; + m_UseKhrBindMemory2 = false; + } + + if(VMA_DEBUG_DETECT_CORRUPTION) + { + // Needs to be multiply of uint32_t size because we are going to write VMA_CORRUPTION_DETECTION_MAGIC_VALUE to it. + VMA_ASSERT(VMA_DEBUG_MARGIN % sizeof(uint32_t) == 0); + } + + VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device && pCreateInfo->instance); + + if(m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0)) + { +#if !(VMA_DEDICATED_ALLOCATION) + if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT) != 0) + { + VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT set but required extensions are disabled by preprocessor macros."); + } +#endif +#if !(VMA_BIND_MEMORY2) + if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT) != 0) + { + VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT set but required extension is disabled by preprocessor macros."); + } +#endif + } +#if !(VMA_MEMORY_BUDGET) + if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT) != 0) + { + VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT set but required extension is disabled by preprocessor macros."); + } +#endif +#if !(VMA_BUFFER_DEVICE_ADDRESS) + if(m_UseKhrBufferDeviceAddress) + { + VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT is set but required extension or Vulkan 1.2 is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro."); + } +#endif +#if VMA_VULKAN_VERSION < 1002000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 2, 0)) + { + VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_2 but required Vulkan version is disabled by preprocessor macros."); + } +#endif +#if VMA_VULKAN_VERSION < 1001000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) + { + VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_1 but required Vulkan version is disabled by preprocessor macros."); + } +#endif +#if !(VMA_MEMORY_PRIORITY) + if(m_UseExtMemoryPriority) + { + VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro."); + } +#endif memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks)); - memset(&m_MemProps, 0, sizeof(m_MemProps)); memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties)); - - memset(&m_pBlockVectors, 0, sizeof(m_pBlockVectors)); - memset(&m_pDedicatedAllocations, 0, sizeof(m_pDedicatedAllocations)); + memset(&m_MemProps, 0, sizeof(m_MemProps)); - for(uint32_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i) - { - m_HeapSizeLimit[i] = VK_WHOLE_SIZE; - } + memset(&m_pBlockVectors, 0, sizeof(m_pBlockVectors)); + memset(&m_VulkanFunctions, 0, sizeof(m_VulkanFunctions)); + +#if VMA_EXTERNAL_MEMORY + memset(&m_TypeExternalMemoryHandleTypes, 0, sizeof(m_TypeExternalMemoryHandleTypes)); +#endif // #if VMA_EXTERNAL_MEMORY if(pCreateInfo->pDeviceMemoryCallbacks != VMA_NULL) { + m_DeviceMemoryCallbacks.pUserData = pCreateInfo->pDeviceMemoryCallbacks->pUserData; m_DeviceMemoryCallbacks.pfnAllocate = pCreateInfo->pDeviceMemoryCallbacks->pfnAllocate; m_DeviceMemoryCallbacks.pfnFree = pCreateInfo->pDeviceMemoryCallbacks->pfnFree; } @@ -7409,9 +14285,24 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : (*m_VulkanFunctions.vkGetPhysicalDeviceProperties)(m_PhysicalDevice, &m_PhysicalDeviceProperties); (*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &m_MemProps); + VMA_ASSERT(VmaIsPow2(VMA_MIN_ALIGNMENT)); + VMA_ASSERT(VmaIsPow2(VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY)); + VMA_ASSERT(VmaIsPow2(m_PhysicalDeviceProperties.limits.bufferImageGranularity)); + VMA_ASSERT(VmaIsPow2(m_PhysicalDeviceProperties.limits.nonCoherentAtomSize)); + m_PreferredLargeHeapBlockSize = (pCreateInfo->preferredLargeHeapBlockSize != 0) ? pCreateInfo->preferredLargeHeapBlockSize : static_cast(VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE); + m_GlobalMemoryTypeBits = CalculateGlobalMemoryTypeBits(); + +#if VMA_EXTERNAL_MEMORY + if(pCreateInfo->pTypeExternalMemoryHandleTypes != VMA_NULL) + { + memcpy(m_TypeExternalMemoryHandleTypes, pCreateInfo->pTypeExternalMemoryHandleTypes, + sizeof(VkExternalMemoryHandleTypeFlagsKHR) * GetMemoryTypeCount()); + } +#endif // #if VMA_EXTERNAL_MEMORY + if(pCreateInfo->pHeapSizeLimit != VMA_NULL) { for(uint32_t heapIndex = 0; heapIndex < GetMemoryHeapCount(); ++heapIndex) @@ -7419,7 +14310,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : const VkDeviceSize limit = pCreateInfo->pHeapSizeLimit[heapIndex]; if(limit != VK_WHOLE_SIZE) { - m_HeapSizeLimit[heapIndex] = limit; + m_HeapSizeLimitMask |= 1u << heapIndex; if(limit < m_MemProps.memoryHeaps[heapIndex].size) { m_MemProps.memoryHeaps[heapIndex].size = limit; @@ -7434,89 +14325,264 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : m_pBlockVectors[memTypeIndex] = vma_new(this, VmaBlockVector)( this, + VK_NULL_HANDLE, // hParentPool memTypeIndex, preferredBlockSize, 0, SIZE_MAX, GetBufferImageGranularity(), pCreateInfo->frameInUseCount, - false); // isCustomPool + false, // explicitBlockSize + false, // linearAlgorithm + 0.5f, // priority (0.5 is the default per Vulkan spec) + GetMemoryTypeMinAlignment(memTypeIndex), // minAllocationAlignment + VMA_NULL); // // pMemoryAllocateNext // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here, // becase minBlockCount is 0. - m_pDedicatedAllocations[memTypeIndex] = vma_new(this, AllocationVectorType)(VmaStlAllocator(GetAllocationCallbacks())); } } +VkResult VmaAllocator_T::Init(const VmaAllocatorCreateInfo* pCreateInfo) +{ + VkResult res = VK_SUCCESS; + + if(pCreateInfo->pRecordSettings != VMA_NULL && + !VmaStrIsEmpty(pCreateInfo->pRecordSettings->pFilePath)) + { +#if VMA_RECORDING_ENABLED + m_pRecorder = vma_new(this, VmaRecorder)(); + res = m_pRecorder->Init(*pCreateInfo->pRecordSettings, m_UseMutex); + if(res != VK_SUCCESS) + { + return res; + } + m_pRecorder->WriteConfiguration( + m_PhysicalDeviceProperties, + m_MemProps, + m_VulkanApiVersion, + m_UseKhrDedicatedAllocation, + m_UseKhrBindMemory2, + m_UseExtMemoryBudget, + m_UseAmdDeviceCoherentMemory); + m_pRecorder->RecordCreateAllocator(GetCurrentFrameIndex()); +#else + VMA_ASSERT(0 && "VmaAllocatorCreateInfo::pRecordSettings used, but not supported due to VMA_RECORDING_ENABLED not defined to 1."); + return VK_ERROR_FEATURE_NOT_PRESENT; +#endif + } + +#if VMA_MEMORY_BUDGET + if(m_UseExtMemoryBudget) + { + UpdateVulkanBudget(); + } +#endif // #if VMA_MEMORY_BUDGET + + return res; +} + VmaAllocator_T::~VmaAllocator_T() { - VMA_ASSERT(m_Pools.empty()); - - for(size_t i = GetMemoryTypeCount(); i--; ) +#if VMA_RECORDING_ENABLED + if(m_pRecorder != VMA_NULL) { - vma_delete(this, m_pDedicatedAllocations[i]); - vma_delete(this, m_pBlockVectors[i]); + m_pRecorder->RecordDestroyAllocator(GetCurrentFrameIndex()); + vma_delete(this, m_pRecorder); + } +#endif + + VMA_ASSERT(m_Pools.IsEmpty()); + + for(size_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; ) + { + if(!m_DedicatedAllocations[memTypeIndex].IsEmpty()) + { + VMA_ASSERT(0 && "Unfreed dedicated allocations found."); + } + + vma_delete(this, m_pBlockVectors[memTypeIndex]); } } void VmaAllocator_T::ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunctions) { #if VMA_STATIC_VULKAN_FUNCTIONS == 1 - m_VulkanFunctions.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties; - m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties; - m_VulkanFunctions.vkAllocateMemory = vkAllocateMemory; - m_VulkanFunctions.vkFreeMemory = vkFreeMemory; - m_VulkanFunctions.vkMapMemory = vkMapMemory; - m_VulkanFunctions.vkUnmapMemory = vkUnmapMemory; - m_VulkanFunctions.vkBindBufferMemory = vkBindBufferMemory; - m_VulkanFunctions.vkBindImageMemory = vkBindImageMemory; - m_VulkanFunctions.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements; - m_VulkanFunctions.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements; - m_VulkanFunctions.vkCreateBuffer = vkCreateBuffer; - m_VulkanFunctions.vkDestroyBuffer = vkDestroyBuffer; - m_VulkanFunctions.vkCreateImage = vkCreateImage; - m_VulkanFunctions.vkDestroyImage = vkDestroyImage; - if(m_UseKhrDedicatedAllocation) + ImportVulkanFunctions_Static(); +#endif + + if(pVulkanFunctions != VMA_NULL) { - m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR = - (PFN_vkGetBufferMemoryRequirements2KHR)vkGetDeviceProcAddr(m_hDevice, "vkGetBufferMemoryRequirements2KHR"); - m_VulkanFunctions.vkGetImageMemoryRequirements2KHR = - (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(m_hDevice, "vkGetImageMemoryRequirements2KHR"); + ImportVulkanFunctions_Custom(pVulkanFunctions); } + +#if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1 + ImportVulkanFunctions_Dynamic(); +#endif + + ValidateVulkanFunctions(); +} + +#if VMA_STATIC_VULKAN_FUNCTIONS == 1 + +void VmaAllocator_T::ImportVulkanFunctions_Static() +{ + // Vulkan 1.0 + m_VulkanFunctions.vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)vkGetPhysicalDeviceProperties; + m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)vkGetPhysicalDeviceMemoryProperties; + m_VulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkAllocateMemory; + m_VulkanFunctions.vkFreeMemory = (PFN_vkFreeMemory)vkFreeMemory; + m_VulkanFunctions.vkMapMemory = (PFN_vkMapMemory)vkMapMemory; + m_VulkanFunctions.vkUnmapMemory = (PFN_vkUnmapMemory)vkUnmapMemory; + m_VulkanFunctions.vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)vkFlushMappedMemoryRanges; + m_VulkanFunctions.vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)vkInvalidateMappedMemoryRanges; + m_VulkanFunctions.vkBindBufferMemory = (PFN_vkBindBufferMemory)vkBindBufferMemory; + m_VulkanFunctions.vkBindImageMemory = (PFN_vkBindImageMemory)vkBindImageMemory; + m_VulkanFunctions.vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)vkGetBufferMemoryRequirements; + m_VulkanFunctions.vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)vkGetImageMemoryRequirements; + m_VulkanFunctions.vkCreateBuffer = (PFN_vkCreateBuffer)vkCreateBuffer; + m_VulkanFunctions.vkDestroyBuffer = (PFN_vkDestroyBuffer)vkDestroyBuffer; + m_VulkanFunctions.vkCreateImage = (PFN_vkCreateImage)vkCreateImage; + m_VulkanFunctions.vkDestroyImage = (PFN_vkDestroyImage)vkDestroyImage; + m_VulkanFunctions.vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer)vkCmdCopyBuffer; + + // Vulkan 1.1 +#if VMA_VULKAN_VERSION >= 1001000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) + { + m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2)vkGetBufferMemoryRequirements2; + m_VulkanFunctions.vkGetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2)vkGetImageMemoryRequirements2; + m_VulkanFunctions.vkBindBufferMemory2KHR = (PFN_vkBindBufferMemory2)vkBindBufferMemory2; + m_VulkanFunctions.vkBindImageMemory2KHR = (PFN_vkBindImageMemory2)vkBindImageMemory2; + m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2)vkGetPhysicalDeviceMemoryProperties2; + } +#endif +} + #endif // #if VMA_STATIC_VULKAN_FUNCTIONS == 1 +void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVulkanFunctions) +{ + VMA_ASSERT(pVulkanFunctions != VMA_NULL); + #define VMA_COPY_IF_NOT_NULL(funcName) \ if(pVulkanFunctions->funcName != VMA_NULL) m_VulkanFunctions.funcName = pVulkanFunctions->funcName; - if(pVulkanFunctions != VMA_NULL) - { - VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties); - VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties); - VMA_COPY_IF_NOT_NULL(vkAllocateMemory); - VMA_COPY_IF_NOT_NULL(vkFreeMemory); - VMA_COPY_IF_NOT_NULL(vkMapMemory); - VMA_COPY_IF_NOT_NULL(vkUnmapMemory); - VMA_COPY_IF_NOT_NULL(vkBindBufferMemory); - VMA_COPY_IF_NOT_NULL(vkBindImageMemory); - VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements); - VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements); - VMA_COPY_IF_NOT_NULL(vkCreateBuffer); - VMA_COPY_IF_NOT_NULL(vkDestroyBuffer); - VMA_COPY_IF_NOT_NULL(vkCreateImage); - VMA_COPY_IF_NOT_NULL(vkDestroyImage); - VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements2KHR); - VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements2KHR); - } + VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties); + VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties); + VMA_COPY_IF_NOT_NULL(vkAllocateMemory); + VMA_COPY_IF_NOT_NULL(vkFreeMemory); + VMA_COPY_IF_NOT_NULL(vkMapMemory); + VMA_COPY_IF_NOT_NULL(vkUnmapMemory); + VMA_COPY_IF_NOT_NULL(vkFlushMappedMemoryRanges); + VMA_COPY_IF_NOT_NULL(vkInvalidateMappedMemoryRanges); + VMA_COPY_IF_NOT_NULL(vkBindBufferMemory); + VMA_COPY_IF_NOT_NULL(vkBindImageMemory); + VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements); + VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements); + VMA_COPY_IF_NOT_NULL(vkCreateBuffer); + VMA_COPY_IF_NOT_NULL(vkDestroyBuffer); + VMA_COPY_IF_NOT_NULL(vkCreateImage); + VMA_COPY_IF_NOT_NULL(vkDestroyImage); + VMA_COPY_IF_NOT_NULL(vkCmdCopyBuffer); + +#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements2KHR); + VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements2KHR); +#endif + +#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000 + VMA_COPY_IF_NOT_NULL(vkBindBufferMemory2KHR); + VMA_COPY_IF_NOT_NULL(vkBindImageMemory2KHR); +#endif + +#if VMA_MEMORY_BUDGET + VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties2KHR); +#endif #undef VMA_COPY_IF_NOT_NULL +} - // If these asserts are hit, you must either #define VMA_STATIC_VULKAN_FUNCTIONS 1 - // or pass valid pointers as VmaAllocatorCreateInfo::pVulkanFunctions. +#if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1 + +void VmaAllocator_T::ImportVulkanFunctions_Dynamic() +{ +#define VMA_FETCH_INSTANCE_FUNC(memberName, functionPointerType, functionNameString) \ + if(m_VulkanFunctions.memberName == VMA_NULL) \ + m_VulkanFunctions.memberName = \ + (functionPointerType)vkGetInstanceProcAddr(m_hInstance, functionNameString); +#define VMA_FETCH_DEVICE_FUNC(memberName, functionPointerType, functionNameString) \ + if(m_VulkanFunctions.memberName == VMA_NULL) \ + m_VulkanFunctions.memberName = \ + (functionPointerType)vkGetDeviceProcAddr(m_hDevice, functionNameString); + + VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceProperties, PFN_vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties"); + VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties, PFN_vkGetPhysicalDeviceMemoryProperties, "vkGetPhysicalDeviceMemoryProperties"); + VMA_FETCH_DEVICE_FUNC(vkAllocateMemory, PFN_vkAllocateMemory, "vkAllocateMemory"); + VMA_FETCH_DEVICE_FUNC(vkFreeMemory, PFN_vkFreeMemory, "vkFreeMemory"); + VMA_FETCH_DEVICE_FUNC(vkMapMemory, PFN_vkMapMemory, "vkMapMemory"); + VMA_FETCH_DEVICE_FUNC(vkUnmapMemory, PFN_vkUnmapMemory, "vkUnmapMemory"); + VMA_FETCH_DEVICE_FUNC(vkFlushMappedMemoryRanges, PFN_vkFlushMappedMemoryRanges, "vkFlushMappedMemoryRanges"); + VMA_FETCH_DEVICE_FUNC(vkInvalidateMappedMemoryRanges, PFN_vkInvalidateMappedMemoryRanges, "vkInvalidateMappedMemoryRanges"); + VMA_FETCH_DEVICE_FUNC(vkBindBufferMemory, PFN_vkBindBufferMemory, "vkBindBufferMemory"); + VMA_FETCH_DEVICE_FUNC(vkBindImageMemory, PFN_vkBindImageMemory, "vkBindImageMemory"); + VMA_FETCH_DEVICE_FUNC(vkGetBufferMemoryRequirements, PFN_vkGetBufferMemoryRequirements, "vkGetBufferMemoryRequirements"); + VMA_FETCH_DEVICE_FUNC(vkGetImageMemoryRequirements, PFN_vkGetImageMemoryRequirements, "vkGetImageMemoryRequirements"); + VMA_FETCH_DEVICE_FUNC(vkCreateBuffer, PFN_vkCreateBuffer, "vkCreateBuffer"); + VMA_FETCH_DEVICE_FUNC(vkDestroyBuffer, PFN_vkDestroyBuffer, "vkDestroyBuffer"); + VMA_FETCH_DEVICE_FUNC(vkCreateImage, PFN_vkCreateImage, "vkCreateImage"); + VMA_FETCH_DEVICE_FUNC(vkDestroyImage, PFN_vkDestroyImage, "vkDestroyImage"); + VMA_FETCH_DEVICE_FUNC(vkCmdCopyBuffer, PFN_vkCmdCopyBuffer, "vkCmdCopyBuffer"); + +#if VMA_VULKAN_VERSION >= 1001000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) + { + VMA_FETCH_DEVICE_FUNC(vkGetBufferMemoryRequirements2KHR, PFN_vkGetBufferMemoryRequirements2, "vkGetBufferMemoryRequirements2"); + VMA_FETCH_DEVICE_FUNC(vkGetImageMemoryRequirements2KHR, PFN_vkGetImageMemoryRequirements2, "vkGetImageMemoryRequirements2"); + VMA_FETCH_DEVICE_FUNC(vkBindBufferMemory2KHR, PFN_vkBindBufferMemory2, "vkBindBufferMemory2"); + VMA_FETCH_DEVICE_FUNC(vkBindImageMemory2KHR, PFN_vkBindImageMemory2, "vkBindImageMemory2"); + VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2, "vkGetPhysicalDeviceMemoryProperties2"); + } +#endif + +#if VMA_DEDICATED_ALLOCATION + if(m_UseKhrDedicatedAllocation) + { + VMA_FETCH_DEVICE_FUNC(vkGetBufferMemoryRequirements2KHR, PFN_vkGetBufferMemoryRequirements2KHR, "vkGetBufferMemoryRequirements2KHR"); + VMA_FETCH_DEVICE_FUNC(vkGetImageMemoryRequirements2KHR, PFN_vkGetImageMemoryRequirements2KHR, "vkGetImageMemoryRequirements2KHR"); + } +#endif + +#if VMA_BIND_MEMORY2 + if(m_UseKhrBindMemory2) + { + VMA_FETCH_DEVICE_FUNC(vkBindBufferMemory2KHR, PFN_vkBindBufferMemory2KHR, "vkBindBufferMemory2KHR"); + VMA_FETCH_DEVICE_FUNC(vkBindImageMemory2KHR, PFN_vkBindImageMemory2KHR, "vkBindImageMemory2KHR"); + } +#endif // #if VMA_BIND_MEMORY2 + +#if VMA_MEMORY_BUDGET + if(m_UseExtMemoryBudget) + { + VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR"); + } +#endif // #if VMA_MEMORY_BUDGET + +#undef VMA_FETCH_DEVICE_FUNC +#undef VMA_FETCH_INSTANCE_FUNC +} + +#endif // #if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1 + +void VmaAllocator_T::ValidateVulkanFunctions() +{ VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceProperties != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkAllocateMemory != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkFreeMemory != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkMapMemory != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkUnmapMemory != VMA_NULL); + VMA_ASSERT(m_VulkanFunctions.vkFlushMappedMemoryRanges != VMA_NULL); + VMA_ASSERT(m_VulkanFunctions.vkInvalidateMappedMemoryRanges != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkBindBufferMemory != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkBindImageMemory != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements != VMA_NULL); @@ -7525,11 +14591,30 @@ void VmaAllocator_T::ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunc VMA_ASSERT(m_VulkanFunctions.vkDestroyBuffer != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkCreateImage != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkDestroyImage != VMA_NULL); - if(m_UseKhrDedicatedAllocation) + VMA_ASSERT(m_VulkanFunctions.vkCmdCopyBuffer != VMA_NULL); + +#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0) || m_UseKhrDedicatedAllocation) { VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR != VMA_NULL); VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements2KHR != VMA_NULL); } +#endif + +#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0) || m_UseKhrBindMemory2) + { + VMA_ASSERT(m_VulkanFunctions.vkBindBufferMemory2KHR != VMA_NULL); + VMA_ASSERT(m_VulkanFunctions.vkBindImageMemory2KHR != VMA_NULL); + } +#endif + +#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000 + if(m_UseExtMemoryBudget || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) + { + VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL); + } +#endif } VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex) @@ -7537,21 +14622,24 @@ VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex) const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex); const VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size; const bool isSmallHeap = heapSize <= VMA_SMALL_HEAP_MAX_SIZE; - return isSmallHeap ? (heapSize / 8) : m_PreferredLargeHeapBlockSize; + return VmaAlignUp(isSmallHeap ? (heapSize / 8) : m_PreferredLargeHeapBlockSize, (VkDeviceSize)32); } VkResult VmaAllocator_T::AllocateMemoryOfType( - const VkMemoryRequirements& vkMemReq, + VkDeviceSize size, + VkDeviceSize alignment, bool dedicatedAllocation, VkBuffer dedicatedBuffer, + VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, const VmaAllocationCreateInfo& createInfo, uint32_t memTypeIndex, VmaSuballocationType suballocType, - VmaAllocation* pAllocation) + size_t allocationCount, + VmaAllocation* pAllocations) { - VMA_ASSERT(pAllocation != VMA_NULL); - VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, Size=%llu", memTypeIndex, vkMemReq.size); + VMA_ASSERT(pAllocations != VMA_NULL); + VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, AllocationCount=%zu, Size=%llu", memTypeIndex, allocationCount, size); VmaAllocationCreateInfo finalCreateInfo = createInfo; @@ -7561,6 +14649,11 @@ VkResult VmaAllocator_T::AllocateMemoryOfType( { finalCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT; } + // If memory is lazily allocated, it should be always dedicated. + if(finalCreateInfo.usage == VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED) + { + finalCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + } VmaBlockVector* const blockVector = m_pBlockVectors[memTypeIndex]; VMA_ASSERT(blockVector); @@ -7570,7 +14663,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType( VMA_DEBUG_ALWAYS_DEDICATED_MEMORY || dedicatedAllocation || // Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size. - vkMemReq.size > preferredBlockSize / 2; + size > preferredBlockSize / 2; if(preferDedicatedMemory && (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0 && @@ -7588,26 +14681,31 @@ VkResult VmaAllocator_T::AllocateMemoryOfType( else { return AllocateDedicatedMemory( - vkMemReq.size, + size, suballocType, memTypeIndex, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT) != 0, (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, finalCreateInfo.pUserData, + finalCreateInfo.priority, dedicatedBuffer, + dedicatedBufferUsage, dedicatedImage, - pAllocation); + allocationCount, + pAllocations); } } else { VkResult res = blockVector->Allocate( - VK_NULL_HANDLE, // hCurrentPool m_CurrentFrameIndex.load(), - vkMemReq, + size, + alignment, finalCreateInfo, suballocType, - pAllocation); + allocationCount, + pAllocations); if(res == VK_SUCCESS) { return res; @@ -7618,30 +14716,40 @@ VkResult VmaAllocator_T::AllocateMemoryOfType( { return VK_ERROR_OUT_OF_DEVICE_MEMORY; } + + // Protection against creating each allocation as dedicated when we reach or exceed heap size/budget, + // which can quickly deplete maxMemoryAllocationCount: Don't try dedicated allocations when above + // 3/4 of the maximum allocation count. + if(m_DeviceMemoryCount.load() > m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount * 3 / 4) + { + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + + res = AllocateDedicatedMemory( + size, + suballocType, + memTypeIndex, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, + finalCreateInfo.pUserData, + finalCreateInfo.priority, + dedicatedBuffer, + dedicatedBufferUsage, + dedicatedImage, + allocationCount, + pAllocations); + if(res == VK_SUCCESS) + { + // Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here. + VMA_DEBUG_LOG(" Allocated as DedicatedMemory"); + return VK_SUCCESS; + } else { - res = AllocateDedicatedMemory( - vkMemReq.size, - suballocType, - memTypeIndex, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, - finalCreateInfo.pUserData, - dedicatedBuffer, - dedicatedImage, - pAllocation); - if(res == VK_SUCCESS) - { - // Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here. - VMA_DEBUG_LOG(" Allocated as DedicatedMemory"); - return VK_SUCCESS; - } - else - { - // Everything failed: Return error code. - VMA_DEBUG_LOG(" vkAllocateMemory FAILED"); - return res; - } + // Everything failed: Return error code. + VMA_DEBUG_LOG(" vkAllocateMemory FAILED"); + return res; } } } @@ -7650,36 +14758,166 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( VkDeviceSize size, VmaSuballocationType suballocType, uint32_t memTypeIndex, + bool withinBudget, bool map, bool isUserDataString, void* pUserData, + float priority, VkBuffer dedicatedBuffer, + VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, - VmaAllocation* pAllocation) + size_t allocationCount, + VmaAllocation* pAllocations) { - VMA_ASSERT(pAllocation); + VMA_ASSERT(allocationCount > 0 && pAllocations); + + if(withinBudget) + { + const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex); + VmaBudget heapBudget = {}; + GetBudget(&heapBudget, heapIndex, 1); + if(heapBudget.usage + size * allocationCount > heapBudget.budget) + { + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + } VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; allocInfo.memoryTypeIndex = memTypeIndex; allocInfo.allocationSize = size; +#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 VkMemoryDedicatedAllocateInfoKHR dedicatedAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR }; - if(m_UseKhrDedicatedAllocation) + if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) { if(dedicatedBuffer != VK_NULL_HANDLE) { VMA_ASSERT(dedicatedImage == VK_NULL_HANDLE); dedicatedAllocInfo.buffer = dedicatedBuffer; - allocInfo.pNext = &dedicatedAllocInfo; + VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo); } else if(dedicatedImage != VK_NULL_HANDLE) { dedicatedAllocInfo.image = dedicatedImage; - allocInfo.pNext = &dedicatedAllocInfo; + VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo); + } + } +#endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + +#if VMA_BUFFER_DEVICE_ADDRESS + VkMemoryAllocateFlagsInfoKHR allocFlagsInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR }; + if(m_UseKhrBufferDeviceAddress) + { + bool canContainBufferWithDeviceAddress = true; + if(dedicatedBuffer != VK_NULL_HANDLE) + { + canContainBufferWithDeviceAddress = dedicatedBufferUsage == UINT32_MAX || // Usage flags unknown + (dedicatedBufferUsage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT) != 0; + } + else if(dedicatedImage != VK_NULL_HANDLE) + { + canContainBufferWithDeviceAddress = false; + } + if(canContainBufferWithDeviceAddress) + { + allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR; + VmaPnextChainPushFront(&allocInfo, &allocFlagsInfo); + } + } +#endif // #if VMA_BUFFER_DEVICE_ADDRESS + +#if VMA_MEMORY_PRIORITY + VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT }; + if(m_UseExtMemoryPriority) + { + priorityInfo.priority = priority; + VmaPnextChainPushFront(&allocInfo, &priorityInfo); + } +#endif // #if VMA_MEMORY_PRIORITY + +#if VMA_EXTERNAL_MEMORY + // Attach VkExportMemoryAllocateInfoKHR if necessary. + VkExportMemoryAllocateInfoKHR exportMemoryAllocInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR }; + exportMemoryAllocInfo.handleTypes = GetExternalMemoryHandleTypeFlags(memTypeIndex); + if(exportMemoryAllocInfo.handleTypes != 0) + { + VmaPnextChainPushFront(&allocInfo, &exportMemoryAllocInfo); + } +#endif // #if VMA_EXTERNAL_MEMORY + + size_t allocIndex; + VkResult res = VK_SUCCESS; + for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex) + { + res = AllocateDedicatedMemoryPage( + size, + suballocType, + memTypeIndex, + allocInfo, + map, + isUserDataString, + pUserData, + pAllocations + allocIndex); + if(res != VK_SUCCESS) + { + break; } } - // Allocate VkDeviceMemory. + if(res == VK_SUCCESS) + { + // Register them in m_DedicatedAllocations. + { + VmaMutexLockWrite lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); + DedicatedAllocationLinkedList& dedicatedAllocations = m_DedicatedAllocations[memTypeIndex]; + for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex) + { + dedicatedAllocations.PushBack(pAllocations[allocIndex]); + } + } + + VMA_DEBUG_LOG(" Allocated DedicatedMemory Count=%zu, MemoryTypeIndex=#%u", allocationCount, memTypeIndex); + } + else + { + // Free all already created allocations. + while(allocIndex--) + { + VmaAllocation currAlloc = pAllocations[allocIndex]; + VkDeviceMemory hMemory = currAlloc->GetMemory(); + + /* + There is no need to call this, because Vulkan spec allows to skip vkUnmapMemory + before vkFreeMemory. + + if(currAlloc->GetMappedData() != VMA_NULL) + { + (*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory); + } + */ + + FreeVulkanMemory(memTypeIndex, currAlloc->GetSize(), hMemory); + m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(memTypeIndex), currAlloc->GetSize()); + currAlloc->SetUserData(this, VMA_NULL); + m_AllocationObjectAllocator.Free(currAlloc); + } + + memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount); + } + + return res; +} + +VkResult VmaAllocator_T::AllocateDedicatedMemoryPage( + VkDeviceSize size, + VmaSuballocationType suballocType, + uint32_t memTypeIndex, + const VkMemoryAllocateInfo& allocInfo, + bool map, + bool isUserDataString, + void* pUserData, + VmaAllocation* pAllocation) +{ VkDeviceMemory hMemory = VK_NULL_HANDLE; VkResult res = AllocateVulkanMemory(&allocInfo, &hMemory); if(res < 0) @@ -7706,20 +14944,15 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( } } - *pAllocation = vma_new(this, VmaAllocation_T)(m_CurrentFrameIndex.load(), isUserDataString); + *pAllocation = m_AllocationObjectAllocator.Allocate(m_CurrentFrameIndex.load(), isUserDataString); (*pAllocation)->InitDedicatedAllocation(memTypeIndex, hMemory, suballocType, pMappedData, size); (*pAllocation)->SetUserData(this, pUserData); - - // Register it in m_pDedicatedAllocations. + m_Budget.AddAllocation(MemoryTypeIndexToHeapIndex(memTypeIndex), size); + if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) { - VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex]; - VMA_ASSERT(pDedicatedAllocations); - VmaVectorInsertSorted(*pDedicatedAllocations, *pAllocation); + FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED); } - VMA_DEBUG_LOG(" Allocated DedicatedMemory MemoryTypeIndex=#%u", memTypeIndex); - return VK_SUCCESS; } @@ -7729,7 +14962,8 @@ void VmaAllocator_T::GetBufferMemoryRequirements( bool& requiresDedicatedAllocation, bool& prefersDedicatedAllocation) const { - if(m_UseKhrDedicatedAllocation) +#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) { VkBufferMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR }; memReqInfo.buffer = hBuffer; @@ -7737,7 +14971,7 @@ void VmaAllocator_T::GetBufferMemoryRequirements( VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR }; VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR }; - memReq2.pNext = &memDedicatedReq; + VmaPnextChainPushFront(&memReq2, &memDedicatedReq); (*m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR)(m_hDevice, &memReqInfo, &memReq2); @@ -7746,6 +14980,7 @@ void VmaAllocator_T::GetBufferMemoryRequirements( prefersDedicatedAllocation = (memDedicatedReq.prefersDedicatedAllocation != VK_FALSE); } else +#endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 { (*m_VulkanFunctions.vkGetBufferMemoryRequirements)(m_hDevice, hBuffer, &memReq); requiresDedicatedAllocation = false; @@ -7759,7 +14994,8 @@ void VmaAllocator_T::GetImageMemoryRequirements( bool& requiresDedicatedAllocation, bool& prefersDedicatedAllocation) const { - if(m_UseKhrDedicatedAllocation) +#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) { VkImageMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR }; memReqInfo.image = hImage; @@ -7767,7 +15003,7 @@ void VmaAllocator_T::GetImageMemoryRequirements( VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR }; VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR }; - memReq2.pNext = &memDedicatedReq; + VmaPnextChainPushFront(&memReq2, &memDedicatedReq); (*m_VulkanFunctions.vkGetImageMemoryRequirements2KHR)(m_hDevice, &memReqInfo, &memReq2); @@ -7776,6 +15012,7 @@ void VmaAllocator_T::GetImageMemoryRequirements( prefersDedicatedAllocation = (memDedicatedReq.prefersDedicatedAllocation != VK_FALSE); } else +#endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 { (*m_VulkanFunctions.vkGetImageMemoryRequirements)(m_hDevice, hImage, &memReq); requiresDedicatedAllocation = false; @@ -7788,11 +15025,21 @@ VkResult VmaAllocator_T::AllocateMemory( bool requiresDedicatedAllocation, bool prefersDedicatedAllocation, VkBuffer dedicatedBuffer, + VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, const VmaAllocationCreateInfo& createInfo, VmaSuballocationType suballocType, - VmaAllocation* pAllocation) + size_t allocationCount, + VmaAllocation* pAllocations) { + memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount); + + VMA_ASSERT(VmaIsPow2(vkMemReq.alignment)); + + if(vkMemReq.size == 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } if((createInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 && (createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0) { @@ -7827,13 +15074,22 @@ VkResult VmaAllocator_T::AllocateMemory( if(createInfo.pool != VK_NULL_HANDLE) { + VmaAllocationCreateInfo createInfoForPool = createInfo; + // If memory type is not HOST_VISIBLE, disable MAPPED. + if((createInfoForPool.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0 && + (m_MemProps.memoryTypes[createInfo.pool->m_BlockVector.GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) + { + createInfoForPool.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT; + } + return createInfo.pool->m_BlockVector.Allocate( - createInfo.pool, m_CurrentFrameIndex.load(), - vkMemReq, - createInfo, + vkMemReq.size, + vkMemReq.alignment, + createInfoForPool, suballocType, - pAllocation); + allocationCount, + pAllocations); } else { @@ -7844,14 +15100,17 @@ VkResult VmaAllocator_T::AllocateMemory( if(res == VK_SUCCESS) { res = AllocateMemoryOfType( - vkMemReq, + vkMemReq.size, + vkMemReq.alignment, requiresDedicatedAllocation || prefersDedicatedAllocation, dedicatedBuffer, + dedicatedBufferUsage, dedicatedImage, createInfo, memTypeIndex, suballocType, - pAllocation); + allocationCount, + pAllocations); // Succeeded on first try. if(res == VK_SUCCESS) { @@ -7869,14 +15128,17 @@ VkResult VmaAllocator_T::AllocateMemory( if(res == VK_SUCCESS) { res = AllocateMemoryOfType( - vkMemReq, + vkMemReq.size, + vkMemReq.alignment, requiresDedicatedAllocation || prefersDedicatedAllocation, dedicatedBuffer, + dedicatedBufferUsage, dedicatedImage, createInfo, memTypeIndex, suballocType, - pAllocation); + allocationCount, + pAllocations); // Allocation from this alternative memory type succeeded. if(res == VK_SUCCESS) { @@ -7899,41 +15161,57 @@ VkResult VmaAllocator_T::AllocateMemory( } } -void VmaAllocator_T::FreeMemory(const VmaAllocation allocation) +void VmaAllocator_T::FreeMemory( + size_t allocationCount, + const VmaAllocation* pAllocations) { - VMA_ASSERT(allocation); + VMA_ASSERT(pAllocations); - if(allocation->CanBecomeLost() == false || - allocation->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST) + for(size_t allocIndex = allocationCount; allocIndex--; ) { - switch(allocation->GetType()) + VmaAllocation allocation = pAllocations[allocIndex]; + + if(allocation != VK_NULL_HANDLE) { - case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: + if(TouchAllocation(allocation)) { - VmaBlockVector* pBlockVector = VMA_NULL; - VmaPool hPool = allocation->GetPool(); - if(hPool != VK_NULL_HANDLE) + if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) { - pBlockVector = &hPool->m_BlockVector; + FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED); } - else + + switch(allocation->GetType()) { - const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); - pBlockVector = m_pBlockVectors[memTypeIndex]; + case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: + { + VmaBlockVector* pBlockVector = VMA_NULL; + VmaPool hPool = allocation->GetBlock()->GetParentPool(); + if(hPool != VK_NULL_HANDLE) + { + pBlockVector = &hPool->m_BlockVector; + } + else + { + const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); + pBlockVector = m_pBlockVectors[memTypeIndex]; + } + pBlockVector->Free(allocation); + } + break; + case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED: + FreeDedicatedMemory(allocation); + break; + default: + VMA_ASSERT(0); } - pBlockVector->Free(allocation); } - break; - case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED: - FreeDedicatedMemory(allocation); - break; - default: - VMA_ASSERT(0); + + // Do this regardless of whether the allocation is lost. Lost allocations still account to Budget.AllocationBytes. + m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize()); + allocation->SetUserData(this, VMA_NULL); + m_AllocationObjectAllocator.Free(allocation); } } - - allocation->SetUserData(this, VMA_NULL); - vma_delete(this, allocation); } void VmaAllocator_T::CalculateStats(VmaStats* pStats) @@ -7944,7 +15222,7 @@ void VmaAllocator_T::CalculateStats(VmaStats* pStats) InitStatInfo(pStats->memoryType[i]); for(size_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i) InitStatInfo(pStats->memoryHeap[i]); - + // Process default pools. for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { @@ -7955,10 +15233,10 @@ void VmaAllocator_T::CalculateStats(VmaStats* pStats) // Process custom pools. { - VmaMutexLock lock(m_PoolsMutex, m_UseMutex); - for(size_t poolIndex = 0, poolCount = m_Pools.size(); poolIndex < poolCount; ++poolIndex) + VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex); + for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool)) { - m_Pools[poolIndex]->GetBlockVector().AddStats(pStats); + pool->m_BlockVector.AddStats(pStats); } } @@ -7966,13 +15244,13 @@ void VmaAllocator_T::CalculateStats(VmaStats* pStats) for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { const uint32_t memHeapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex); - VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - AllocationVectorType* const pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex]; - VMA_ASSERT(pDedicatedAllocVector); - for(size_t allocIndex = 0, allocCount = pDedicatedAllocVector->size(); allocIndex < allocCount; ++allocIndex) + VmaMutexLockRead dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); + DedicatedAllocationLinkedList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex]; + for(VmaAllocation alloc = dedicatedAllocList.Front(); + alloc != VMA_NULL; alloc = dedicatedAllocList.GetNext(alloc)) { VmaStatInfo allocationStatInfo; - (*pDedicatedAllocVector)[allocIndex]->DedicatedAllocCalcStatsInfo(allocationStatInfo); + alloc->DedicatedAllocCalcStatsInfo(allocationStatInfo); VmaAddStatInfo(pStats->total, allocationStatInfo); VmaAddStatInfo(pStats->memoryType[memTypeIndex], allocationStatInfo); VmaAddStatInfo(pStats->memoryHeap[memHeapIndex], allocationStatInfo); @@ -7987,119 +15265,109 @@ void VmaAllocator_T::CalculateStats(VmaStats* pStats) VmaPostprocessCalcStatInfo(pStats->memoryHeap[i]); } +void VmaAllocator_T::GetBudget(VmaBudget* outBudget, uint32_t firstHeap, uint32_t heapCount) +{ +#if VMA_MEMORY_BUDGET + if(m_UseExtMemoryBudget) + { + if(m_Budget.m_OperationsSinceBudgetFetch < 30) + { + VmaMutexLockRead lockRead(m_Budget.m_BudgetMutex, m_UseMutex); + for(uint32_t i = 0; i < heapCount; ++i, ++outBudget) + { + const uint32_t heapIndex = firstHeap + i; + + outBudget->blockBytes = m_Budget.m_BlockBytes[heapIndex]; + outBudget->allocationBytes = m_Budget.m_AllocationBytes[heapIndex]; + + if(m_Budget.m_VulkanUsage[heapIndex] + outBudget->blockBytes > m_Budget.m_BlockBytesAtBudgetFetch[heapIndex]) + { + outBudget->usage = m_Budget.m_VulkanUsage[heapIndex] + + outBudget->blockBytes - m_Budget.m_BlockBytesAtBudgetFetch[heapIndex]; + } + else + { + outBudget->usage = 0; + } + + // Have to take MIN with heap size because explicit HeapSizeLimit is included in it. + outBudget->budget = VMA_MIN( + m_Budget.m_VulkanBudget[heapIndex], m_MemProps.memoryHeaps[heapIndex].size); + } + } + else + { + UpdateVulkanBudget(); // Outside of mutex lock + GetBudget(outBudget, firstHeap, heapCount); // Recursion + } + } + else +#endif + { + for(uint32_t i = 0; i < heapCount; ++i, ++outBudget) + { + const uint32_t heapIndex = firstHeap + i; + + outBudget->blockBytes = m_Budget.m_BlockBytes[heapIndex]; + outBudget->allocationBytes = m_Budget.m_AllocationBytes[heapIndex]; + + outBudget->usage = outBudget->blockBytes; + outBudget->budget = m_MemProps.memoryHeaps[heapIndex].size * 8 / 10; // 80% heuristics. + } + } +} + static const uint32_t VMA_VENDOR_ID_AMD = 4098; -VkResult VmaAllocator_T::Defragment( - VmaAllocation* pAllocations, - size_t allocationCount, - VkBool32* pAllocationsChanged, - const VmaDefragmentationInfo* pDefragmentationInfo, - VmaDefragmentationStats* pDefragmentationStats) +VkResult VmaAllocator_T::DefragmentationBegin( + const VmaDefragmentationInfo2& info, + VmaDefragmentationStats* pStats, + VmaDefragmentationContext* pContext) { - if(pAllocationsChanged != VMA_NULL) + if(info.pAllocationsChanged != VMA_NULL) { - memset(pAllocationsChanged, 0, sizeof(*pAllocationsChanged)); - } - if(pDefragmentationStats != VMA_NULL) - { - memset(pDefragmentationStats, 0, sizeof(*pDefragmentationStats)); + memset(info.pAllocationsChanged, 0, info.allocationCount * sizeof(VkBool32)); } - const uint32_t currentFrameIndex = m_CurrentFrameIndex.load(); + *pContext = vma_new(this, VmaDefragmentationContext_T)( + this, m_CurrentFrameIndex.load(), info.flags, pStats); - VmaMutexLock poolsLock(m_PoolsMutex, m_UseMutex); + (*pContext)->AddPools(info.poolCount, info.pPools); + (*pContext)->AddAllocations( + info.allocationCount, info.pAllocations, info.pAllocationsChanged); - const size_t poolCount = m_Pools.size(); + VkResult res = (*pContext)->Defragment( + info.maxCpuBytesToMove, info.maxCpuAllocationsToMove, + info.maxGpuBytesToMove, info.maxGpuAllocationsToMove, + info.commandBuffer, pStats, info.flags); - // Dispatch pAllocations among defragmentators. Create them in BlockVectors when necessary. - for(size_t allocIndex = 0; allocIndex < allocationCount; ++allocIndex) + if(res != VK_NOT_READY) { - VmaAllocation hAlloc = pAllocations[allocIndex]; - VMA_ASSERT(hAlloc); - const uint32_t memTypeIndex = hAlloc->GetMemoryTypeIndex(); - // DedicatedAlloc cannot be defragmented. - if((hAlloc->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK) && - // Only HOST_VISIBLE memory types can be defragmented. - ((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) && - // Lost allocation cannot be defragmented. - (hAlloc->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)) - { - VmaBlockVector* pAllocBlockVector = VMA_NULL; - - const VmaPool hAllocPool = hAlloc->GetPool(); - // This allocation belongs to custom pool. - if(hAllocPool != VK_NULL_HANDLE) - { - pAllocBlockVector = &hAllocPool->GetBlockVector(); - } - // This allocation belongs to general pool. - else - { - pAllocBlockVector = m_pBlockVectors[memTypeIndex]; - } - - VmaDefragmentator* const pDefragmentator = pAllocBlockVector->EnsureDefragmentator(this, currentFrameIndex); - - VkBool32* const pChanged = (pAllocationsChanged != VMA_NULL) ? - &pAllocationsChanged[allocIndex] : VMA_NULL; - pDefragmentator->AddAllocation(hAlloc, pChanged); - } + vma_delete(this, *pContext); + *pContext = VMA_NULL; } - VkResult result = VK_SUCCESS; + return res; +} - // ======== Main processing. +VkResult VmaAllocator_T::DefragmentationEnd( + VmaDefragmentationContext context) +{ + vma_delete(this, context); + return VK_SUCCESS; +} - VkDeviceSize maxBytesToMove = SIZE_MAX; - uint32_t maxAllocationsToMove = UINT32_MAX; - if(pDefragmentationInfo != VMA_NULL) - { - maxBytesToMove = pDefragmentationInfo->maxBytesToMove; - maxAllocationsToMove = pDefragmentationInfo->maxAllocationsToMove; - } +VkResult VmaAllocator_T::DefragmentationPassBegin( + VmaDefragmentationPassInfo* pInfo, + VmaDefragmentationContext context) +{ + return context->DefragmentPassBegin(pInfo); +} +VkResult VmaAllocator_T::DefragmentationPassEnd( + VmaDefragmentationContext context) +{ + return context->DefragmentPassEnd(); - // Process standard memory. - for(uint32_t memTypeIndex = 0; - (memTypeIndex < GetMemoryTypeCount()) && (result == VK_SUCCESS); - ++memTypeIndex) - { - // Only HOST_VISIBLE memory types can be defragmented. - if((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) - { - result = m_pBlockVectors[memTypeIndex]->Defragment( - pDefragmentationStats, - maxBytesToMove, - maxAllocationsToMove); - } - } - - // Process custom pools. - for(size_t poolIndex = 0; (poolIndex < poolCount) && (result == VK_SUCCESS); ++poolIndex) - { - result = m_Pools[poolIndex]->GetBlockVector().Defragment( - pDefragmentationStats, - maxBytesToMove, - maxAllocationsToMove); - } - - // ======== Destroy defragmentators. - - // Process custom pools. - for(size_t poolIndex = poolCount; poolIndex--; ) - { - m_Pools[poolIndex]->GetBlockVector().DestroyDefragmentator(); - } - - // Process standard memory. - for(uint32_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; ) - { - if((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) - { - m_pBlockVectors[memTypeIndex]->DestroyDefragmentator(); - } - } - - return result; } void VmaAllocator_T::GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo) @@ -8108,9 +15376,9 @@ void VmaAllocator_T::GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationI { /* Warning: This is a carefully designed algorithm. - Do not modify unless you really know what you're doing :) + Do not modify unless you really know what you are doing :) */ - uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); + const uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex(); for(;;) { @@ -8145,6 +15413,26 @@ void VmaAllocator_T::GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationI } else { +#if VMA_STATS_STRING_ENABLED + uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); + uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex(); + for(;;) + { + VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST); + if(localLastUseFrameIndex == localCurrFrameIndex) + { + break; + } + else // Last use time earlier than current time. + { + if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex)) + { + localLastUseFrameIndex = localCurrFrameIndex; + } + } + } +#endif + pAllocationInfo->memoryType = hAllocation->GetMemoryTypeIndex(); pAllocationInfo->deviceMemory = hAllocation->GetMemory(); pAllocationInfo->offset = hAllocation->GetOffset(); @@ -8182,26 +15470,64 @@ bool VmaAllocator_T::TouchAllocation(VmaAllocation hAllocation) } else { +#if VMA_STATS_STRING_ENABLED + uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); + uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex(); + for(;;) + { + VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST); + if(localLastUseFrameIndex == localCurrFrameIndex) + { + break; + } + else // Last use time earlier than current time. + { + if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex)) + { + localLastUseFrameIndex = localCurrFrameIndex; + } + } + } +#endif + return true; } } VkResult VmaAllocator_T::CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool) { - VMA_DEBUG_LOG(" CreatePool: MemoryTypeIndex=%u", pCreateInfo->memoryTypeIndex); + VMA_DEBUG_LOG(" CreatePool: MemoryTypeIndex=%u, flags=%u", pCreateInfo->memoryTypeIndex, pCreateInfo->flags); VmaPoolCreateInfo newCreateInfo = *pCreateInfo; + // Protection against uninitialized new structure member. If garbage data are left there, this pointer dereference would crash. + if(pCreateInfo->pMemoryAllocateNext) + { + VMA_ASSERT(((const VkBaseInStructure*)pCreateInfo->pMemoryAllocateNext)->sType != 0); + } + if(newCreateInfo.maxBlockCount == 0) { newCreateInfo.maxBlockCount = SIZE_MAX; } - if(newCreateInfo.blockSize == 0) + if(newCreateInfo.minBlockCount > newCreateInfo.maxBlockCount) { - newCreateInfo.blockSize = CalcPreferredBlockSize(newCreateInfo.memoryTypeIndex); + return VK_ERROR_INITIALIZATION_FAILED; + } + // Memory type index out of range or forbidden. + if(pCreateInfo->memoryTypeIndex >= GetMemoryTypeCount() || + ((1u << pCreateInfo->memoryTypeIndex) & m_GlobalMemoryTypeBits) == 0) + { + return VK_ERROR_FEATURE_NOT_PRESENT; + } + if(newCreateInfo.minAllocationAlignment > 0) + { + VMA_ASSERT(VmaIsPow2(newCreateInfo.minAllocationAlignment)); } - *pPool = vma_new(this, VmaPool_T)(this, newCreateInfo); + const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(newCreateInfo.memoryTypeIndex); + + *pPool = vma_new(this, VmaPool_T)(this, newCreateInfo, preferredBlockSize); VkResult res = (*pPool)->m_BlockVector.CreateMinBlocks(); if(res != VK_SUCCESS) @@ -8213,8 +15539,9 @@ VkResult VmaAllocator_T::CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPoo // Add to m_Pools. { - VmaMutexLock lock(m_PoolsMutex, m_UseMutex); - VmaVectorInsertSorted(m_Pools, *pPool); + VmaMutexLockWrite lock(m_PoolsMutex, m_UseMutex); + (*pPool)->SetId(m_NextPoolId++); + m_Pools.PushBack(*pPool); } return VK_SUCCESS; @@ -8224,9 +15551,8 @@ void VmaAllocator_T::DestroyPool(VmaPool pool) { // Remove from m_Pools. { - VmaMutexLock lock(m_PoolsMutex, m_UseMutex); - bool success = VmaVectorRemoveSorted(m_Pools, pool); - VMA_ASSERT(success && "Pool not found in Allocator."); + VmaMutexLockWrite lock(m_PoolsMutex, m_UseMutex); + m_Pools.Remove(pool); } vma_delete(this, pool); @@ -8240,6 +15566,13 @@ void VmaAllocator_T::GetPoolStats(VmaPool pool, VmaPoolStats* pPoolStats) void VmaAllocator_T::SetCurrentFrameIndex(uint32_t frameIndex) { m_CurrentFrameIndex.store(frameIndex); + +#if VMA_MEMORY_BUDGET + if(m_UseExtMemoryBudget) + { + UpdateVulkanBudget(); + } +#endif // #if VMA_MEMORY_BUDGET } void VmaAllocator_T::MakePoolAllocationsLost( @@ -8251,41 +15584,148 @@ void VmaAllocator_T::MakePoolAllocationsLost( pLostAllocationCount); } +VkResult VmaAllocator_T::CheckPoolCorruption(VmaPool hPool) +{ + return hPool->m_BlockVector.CheckCorruption(); +} + +VkResult VmaAllocator_T::CheckCorruption(uint32_t memoryTypeBits) +{ + VkResult finalRes = VK_ERROR_FEATURE_NOT_PRESENT; + + // Process default pools. + for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) + { + if(((1u << memTypeIndex) & memoryTypeBits) != 0) + { + VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex]; + VMA_ASSERT(pBlockVector); + VkResult localRes = pBlockVector->CheckCorruption(); + switch(localRes) + { + case VK_ERROR_FEATURE_NOT_PRESENT: + break; + case VK_SUCCESS: + finalRes = VK_SUCCESS; + break; + default: + return localRes; + } + } + } + + // Process custom pools. + { + VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex); + for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool)) + { + if(((1u << pool->m_BlockVector.GetMemoryTypeIndex()) & memoryTypeBits) != 0) + { + VkResult localRes = pool->m_BlockVector.CheckCorruption(); + switch(localRes) + { + case VK_ERROR_FEATURE_NOT_PRESENT: + break; + case VK_SUCCESS: + finalRes = VK_SUCCESS; + break; + default: + return localRes; + } + } + } + } + + return finalRes; +} + void VmaAllocator_T::CreateLostAllocation(VmaAllocation* pAllocation) { - *pAllocation = vma_new(this, VmaAllocation_T)(VMA_FRAME_INDEX_LOST, false); + *pAllocation = m_AllocationObjectAllocator.Allocate(VMA_FRAME_INDEX_LOST, false); (*pAllocation)->InitLost(); } +// An object that increments given atomic but decrements it back in the destructor unless Commit() is called. +template +struct AtomicTransactionalIncrement +{ +public: + typedef std::atomic AtomicT; + ~AtomicTransactionalIncrement() + { + if(m_Atomic) + --(*m_Atomic); + } + T Increment(AtomicT* atomic) + { + m_Atomic = atomic; + return m_Atomic->fetch_add(1); + } + void Commit() + { + m_Atomic = nullptr; + } + +private: + AtomicT* m_Atomic = nullptr; +}; + VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory) { + AtomicTransactionalIncrement deviceMemoryCountIncrement; + const uint64_t prevDeviceMemoryCount = deviceMemoryCountIncrement.Increment(&m_DeviceMemoryCount); +#if VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT + if(prevDeviceMemoryCount >= m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount) + { + return VK_ERROR_TOO_MANY_OBJECTS; + } +#endif + const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(pAllocateInfo->memoryTypeIndex); - VkResult res; - if(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE) + // HeapSizeLimit is in effect for this heap. + if((m_HeapSizeLimitMask & (1u << heapIndex)) != 0) { - VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex); - if(m_HeapSizeLimit[heapIndex] >= pAllocateInfo->allocationSize) + const VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size; + VkDeviceSize blockBytes = m_Budget.m_BlockBytes[heapIndex]; + for(;;) { - res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory); - if(res == VK_SUCCESS) + const VkDeviceSize blockBytesAfterAllocation = blockBytes + pAllocateInfo->allocationSize; + if(blockBytesAfterAllocation > heapSize) { - m_HeapSizeLimit[heapIndex] -= pAllocateInfo->allocationSize; + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + if(m_Budget.m_BlockBytes[heapIndex].compare_exchange_strong(blockBytes, blockBytesAfterAllocation)) + { + break; } - } - else - { - res = VK_ERROR_OUT_OF_DEVICE_MEMORY; } } else { - res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory); + m_Budget.m_BlockBytes[heapIndex] += pAllocateInfo->allocationSize; } - if(res == VK_SUCCESS && m_DeviceMemoryCallbacks.pfnAllocate != VMA_NULL) + // VULKAN CALL vkAllocateMemory. + VkResult res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory); + + if(res == VK_SUCCESS) { - (*m_DeviceMemoryCallbacks.pfnAllocate)(this, pAllocateInfo->memoryTypeIndex, *pMemory, pAllocateInfo->allocationSize); +#if VMA_MEMORY_BUDGET + ++m_Budget.m_OperationsSinceBudgetFetch; +#endif + + // Informative callback. + if(m_DeviceMemoryCallbacks.pfnAllocate != VMA_NULL) + { + (*m_DeviceMemoryCallbacks.pfnAllocate)(this, pAllocateInfo->memoryTypeIndex, *pMemory, pAllocateInfo->allocationSize, m_DeviceMemoryCallbacks.pUserData); + } + + deviceMemoryCountIncrement.Commit(); + } + else + { + m_Budget.m_BlockBytes[heapIndex] -= pAllocateInfo->allocationSize; } return res; @@ -8293,18 +15733,79 @@ VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAlloc void VmaAllocator_T::FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory) { + // Informative callback. if(m_DeviceMemoryCallbacks.pfnFree != VMA_NULL) { - (*m_DeviceMemoryCallbacks.pfnFree)(this, memoryType, hMemory, size); + (*m_DeviceMemoryCallbacks.pfnFree)(this, memoryType, hMemory, size, m_DeviceMemoryCallbacks.pUserData); } + // VULKAN CALL vkFreeMemory. (*m_VulkanFunctions.vkFreeMemory)(m_hDevice, hMemory, GetAllocationCallbacks()); - const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memoryType); - if(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE) + m_Budget.m_BlockBytes[MemoryTypeIndexToHeapIndex(memoryType)] -= size; + + --m_DeviceMemoryCount; +} + +VkResult VmaAllocator_T::BindVulkanBuffer( + VkDeviceMemory memory, + VkDeviceSize memoryOffset, + VkBuffer buffer, + const void* pNext) +{ + if(pNext != VMA_NULL) { - VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex); - m_HeapSizeLimit[heapIndex] += size; +#if VMA_VULKAN_VERSION >= 1001000 || VMA_BIND_MEMORY2 + if((m_UseKhrBindMemory2 || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) && + m_VulkanFunctions.vkBindBufferMemory2KHR != VMA_NULL) + { + VkBindBufferMemoryInfoKHR bindBufferMemoryInfo = { VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR }; + bindBufferMemoryInfo.pNext = pNext; + bindBufferMemoryInfo.buffer = buffer; + bindBufferMemoryInfo.memory = memory; + bindBufferMemoryInfo.memoryOffset = memoryOffset; + return (*m_VulkanFunctions.vkBindBufferMemory2KHR)(m_hDevice, 1, &bindBufferMemoryInfo); + } + else +#endif // #if VMA_VULKAN_VERSION >= 1001000 || VMA_BIND_MEMORY2 + { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + } + else + { + return (*m_VulkanFunctions.vkBindBufferMemory)(m_hDevice, buffer, memory, memoryOffset); + } +} + +VkResult VmaAllocator_T::BindVulkanImage( + VkDeviceMemory memory, + VkDeviceSize memoryOffset, + VkImage image, + const void* pNext) +{ + if(pNext != VMA_NULL) + { +#if VMA_VULKAN_VERSION >= 1001000 || VMA_BIND_MEMORY2 + if((m_UseKhrBindMemory2 || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) && + m_VulkanFunctions.vkBindImageMemory2KHR != VMA_NULL) + { + VkBindImageMemoryInfoKHR bindBufferMemoryInfo = { VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR }; + bindBufferMemoryInfo.pNext = pNext; + bindBufferMemoryInfo.image = image; + bindBufferMemoryInfo.memory = memory; + bindBufferMemoryInfo.memoryOffset = memoryOffset; + return (*m_VulkanFunctions.vkBindImageMemory2KHR)(m_hDevice, 1, &bindBufferMemoryInfo); + } + else +#endif // #if VMA_BIND_MEMORY2 + { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + } + else + { + return (*m_VulkanFunctions.vkBindImageMemory)(m_hDevice, image, memory, memoryOffset); } } @@ -8356,23 +15857,23 @@ void VmaAllocator_T::Unmap(VmaAllocation hAllocation) } } -VkResult VmaAllocator_T::BindBufferMemory(VmaAllocation hAllocation, VkBuffer hBuffer) +VkResult VmaAllocator_T::BindBufferMemory( + VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkBuffer hBuffer, + const void* pNext) { VkResult res = VK_SUCCESS; switch(hAllocation->GetType()) { case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED: - res = GetVulkanFunctions().vkBindBufferMemory( - m_hDevice, - hBuffer, - hAllocation->GetMemory(), - 0); //memoryOffset + res = BindVulkanBuffer(hAllocation->GetMemory(), allocationLocalOffset, hBuffer, pNext); break; case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: { - VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock(); + VmaDeviceMemoryBlock* const pBlock = hAllocation->GetBlock(); VMA_ASSERT(pBlock && "Binding buffer to allocation that doesn't belong to any block. Is the allocation lost?"); - res = pBlock->BindBufferMemory(this, hAllocation, hBuffer); + res = pBlock->BindBufferMemory(this, hAllocation, allocationLocalOffset, hBuffer, pNext); break; } default: @@ -8381,23 +15882,23 @@ VkResult VmaAllocator_T::BindBufferMemory(VmaAllocation hAllocation, VkBuffer hB return res; } -VkResult VmaAllocator_T::BindImageMemory(VmaAllocation hAllocation, VkImage hImage) +VkResult VmaAllocator_T::BindImageMemory( + VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkImage hImage, + const void* pNext) { VkResult res = VK_SUCCESS; switch(hAllocation->GetType()) { case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED: - res = GetVulkanFunctions().vkBindImageMemory( - m_hDevice, - hImage, - hAllocation->GetMemory(), - 0); //memoryOffset + res = BindVulkanImage(hAllocation->GetMemory(), allocationLocalOffset, hImage, pNext); break; case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: { VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock(); VMA_ASSERT(pBlock && "Binding image to allocation that doesn't belong to any block. Is the allocation lost?"); - res = pBlock->BindImageMemory(this, hAllocation, hImage); + res = pBlock->BindImageMemory(this, hAllocation, allocationLocalOffset, hImage, pNext); break; } default: @@ -8406,31 +15907,285 @@ VkResult VmaAllocator_T::BindImageMemory(VmaAllocation hAllocation, VkImage hIma return res; } -void VmaAllocator_T::FreeDedicatedMemory(VmaAllocation allocation) +VkResult VmaAllocator_T::FlushOrInvalidateAllocation( + VmaAllocation hAllocation, + VkDeviceSize offset, VkDeviceSize size, + VMA_CACHE_OPERATION op) +{ + VkResult res = VK_SUCCESS; + + VkMappedMemoryRange memRange = {}; + if(GetFlushOrInvalidateRange(hAllocation, offset, size, memRange)) + { + switch(op) + { + case VMA_CACHE_FLUSH: + res = (*GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hDevice, 1, &memRange); + break; + case VMA_CACHE_INVALIDATE: + res = (*GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hDevice, 1, &memRange); + break; + default: + VMA_ASSERT(0); + } + } + // else: Just ignore this call. + return res; +} + +VkResult VmaAllocator_T::FlushOrInvalidateAllocations( + uint32_t allocationCount, + const VmaAllocation* allocations, + const VkDeviceSize* offsets, const VkDeviceSize* sizes, + VMA_CACHE_OPERATION op) +{ + typedef VmaStlAllocator RangeAllocator; + typedef VmaSmallVector RangeVector; + RangeVector ranges = RangeVector(RangeAllocator(GetAllocationCallbacks())); + + for(uint32_t allocIndex = 0; allocIndex < allocationCount; ++allocIndex) + { + const VmaAllocation alloc = allocations[allocIndex]; + const VkDeviceSize offset = offsets != VMA_NULL ? offsets[allocIndex] : 0; + const VkDeviceSize size = sizes != VMA_NULL ? sizes[allocIndex] : VK_WHOLE_SIZE; + VkMappedMemoryRange newRange; + if(GetFlushOrInvalidateRange(alloc, offset, size, newRange)) + { + ranges.push_back(newRange); + } + } + + VkResult res = VK_SUCCESS; + if(!ranges.empty()) + { + switch(op) + { + case VMA_CACHE_FLUSH: + res = (*GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hDevice, (uint32_t)ranges.size(), ranges.data()); + break; + case VMA_CACHE_INVALIDATE: + res = (*GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hDevice, (uint32_t)ranges.size(), ranges.data()); + break; + default: + VMA_ASSERT(0); + } + } + // else: Just ignore this call. + return res; +} + +void VmaAllocator_T::FreeDedicatedMemory(const VmaAllocation allocation) { VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); { - VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - AllocationVectorType* const pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex]; - VMA_ASSERT(pDedicatedAllocations); - bool success = VmaVectorRemoveSorted(*pDedicatedAllocations, allocation); - VMA_ASSERT(success); + VmaMutexLockWrite lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); + DedicatedAllocationLinkedList& dedicatedAllocations = m_DedicatedAllocations[memTypeIndex]; + dedicatedAllocations.Remove(allocation); } VkDeviceMemory hMemory = allocation->GetMemory(); - + + /* + There is no need to call this, because Vulkan spec allows to skip vkUnmapMemory + before vkFreeMemory. + if(allocation->GetMappedData() != VMA_NULL) { (*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory); } - + */ + FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory); VMA_DEBUG_LOG(" Freed DedicatedMemory MemoryTypeIndex=%u", memTypeIndex); } +uint32_t VmaAllocator_T::CalculateGpuDefragmentationMemoryTypeBits() const +{ + VkBufferCreateInfo dummyBufCreateInfo; + VmaFillGpuDefragmentationBufferCreateInfo(dummyBufCreateInfo); + + uint32_t memoryTypeBits = 0; + + // Create buffer. + VkBuffer buf = VK_NULL_HANDLE; + VkResult res = (*GetVulkanFunctions().vkCreateBuffer)( + m_hDevice, &dummyBufCreateInfo, GetAllocationCallbacks(), &buf); + if(res == VK_SUCCESS) + { + // Query for supported memory types. + VkMemoryRequirements memReq; + (*GetVulkanFunctions().vkGetBufferMemoryRequirements)(m_hDevice, buf, &memReq); + memoryTypeBits = memReq.memoryTypeBits; + + // Destroy buffer. + (*GetVulkanFunctions().vkDestroyBuffer)(m_hDevice, buf, GetAllocationCallbacks()); + } + + return memoryTypeBits; +} + +uint32_t VmaAllocator_T::CalculateGlobalMemoryTypeBits() const +{ + // Make sure memory information is already fetched. + VMA_ASSERT(GetMemoryTypeCount() > 0); + + uint32_t memoryTypeBits = UINT32_MAX; + + if(!m_UseAmdDeviceCoherentMemory) + { + // Exclude memory types that have VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD. + for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) + { + if((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY) != 0) + { + memoryTypeBits &= ~(1u << memTypeIndex); + } + } + } + + return memoryTypeBits; +} + +bool VmaAllocator_T::GetFlushOrInvalidateRange( + VmaAllocation allocation, + VkDeviceSize offset, VkDeviceSize size, + VkMappedMemoryRange& outRange) const +{ + const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); + if(size > 0 && IsMemoryTypeNonCoherent(memTypeIndex)) + { + const VkDeviceSize nonCoherentAtomSize = m_PhysicalDeviceProperties.limits.nonCoherentAtomSize; + const VkDeviceSize allocationSize = allocation->GetSize(); + VMA_ASSERT(offset <= allocationSize); + + outRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + outRange.pNext = VMA_NULL; + outRange.memory = allocation->GetMemory(); + + switch(allocation->GetType()) + { + case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED: + outRange.offset = VmaAlignDown(offset, nonCoherentAtomSize); + if(size == VK_WHOLE_SIZE) + { + outRange.size = allocationSize - outRange.offset; + } + else + { + VMA_ASSERT(offset + size <= allocationSize); + outRange.size = VMA_MIN( + VmaAlignUp(size + (offset - outRange.offset), nonCoherentAtomSize), + allocationSize - outRange.offset); + } + break; + case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: + { + // 1. Still within this allocation. + outRange.offset = VmaAlignDown(offset, nonCoherentAtomSize); + if(size == VK_WHOLE_SIZE) + { + size = allocationSize - offset; + } + else + { + VMA_ASSERT(offset + size <= allocationSize); + } + outRange.size = VmaAlignUp(size + (offset - outRange.offset), nonCoherentAtomSize); + + // 2. Adjust to whole block. + const VkDeviceSize allocationOffset = allocation->GetOffset(); + VMA_ASSERT(allocationOffset % nonCoherentAtomSize == 0); + const VkDeviceSize blockSize = allocation->GetBlock()->m_pMetadata->GetSize(); + outRange.offset += allocationOffset; + outRange.size = VMA_MIN(outRange.size, blockSize - outRange.offset); + + break; + } + default: + VMA_ASSERT(0); + } + return true; + } + return false; +} + +#if VMA_MEMORY_BUDGET + +void VmaAllocator_T::UpdateVulkanBudget() +{ + VMA_ASSERT(m_UseExtMemoryBudget); + + VkPhysicalDeviceMemoryProperties2KHR memProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR }; + + VkPhysicalDeviceMemoryBudgetPropertiesEXT budgetProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT }; + VmaPnextChainPushFront(&memProps, &budgetProps); + + GetVulkanFunctions().vkGetPhysicalDeviceMemoryProperties2KHR(m_PhysicalDevice, &memProps); + + { + VmaMutexLockWrite lockWrite(m_Budget.m_BudgetMutex, m_UseMutex); + + for(uint32_t heapIndex = 0; heapIndex < GetMemoryHeapCount(); ++heapIndex) + { + m_Budget.m_VulkanUsage[heapIndex] = budgetProps.heapUsage[heapIndex]; + m_Budget.m_VulkanBudget[heapIndex] = budgetProps.heapBudget[heapIndex]; + m_Budget.m_BlockBytesAtBudgetFetch[heapIndex] = m_Budget.m_BlockBytes[heapIndex].load(); + + // Some bugged drivers return the budget incorrectly, e.g. 0 or much bigger than heap size. + if(m_Budget.m_VulkanBudget[heapIndex] == 0) + { + m_Budget.m_VulkanBudget[heapIndex] = m_MemProps.memoryHeaps[heapIndex].size * 8 / 10; // 80% heuristics. + } + else if(m_Budget.m_VulkanBudget[heapIndex] > m_MemProps.memoryHeaps[heapIndex].size) + { + m_Budget.m_VulkanBudget[heapIndex] = m_MemProps.memoryHeaps[heapIndex].size; + } + if(m_Budget.m_VulkanUsage[heapIndex] == 0 && m_Budget.m_BlockBytesAtBudgetFetch[heapIndex] > 0) + { + m_Budget.m_VulkanUsage[heapIndex] = m_Budget.m_BlockBytesAtBudgetFetch[heapIndex]; + } + } + m_Budget.m_OperationsSinceBudgetFetch = 0; + } +} + +#endif // #if VMA_MEMORY_BUDGET + +void VmaAllocator_T::FillAllocation(const VmaAllocation hAllocation, uint8_t pattern) +{ + if(VMA_DEBUG_INITIALIZE_ALLOCATIONS && + !hAllocation->CanBecomeLost() && + (m_MemProps.memoryTypes[hAllocation->GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) + { + void* pData = VMA_NULL; + VkResult res = Map(hAllocation, &pData); + if(res == VK_SUCCESS) + { + memset(pData, (int)pattern, (size_t)hAllocation->GetSize()); + FlushOrInvalidateAllocation(hAllocation, 0, VK_WHOLE_SIZE, VMA_CACHE_FLUSH); + Unmap(hAllocation); + } + else + { + VMA_ASSERT(0 && "VMA_DEBUG_INITIALIZE_ALLOCATIONS is enabled, but couldn't map memory to fill allocation."); + } + } +} + +uint32_t VmaAllocator_T::GetGpuDefragmentationMemoryTypeBits() +{ + uint32_t memoryTypeBits = m_GpuDefragmentationMemoryTypeBits.load(); + if(memoryTypeBits == UINT32_MAX) + { + memoryTypeBits = CalculateGpuDefragmentationMemoryTypeBits(); + m_GpuDefragmentationMemoryTypeBits.store(memoryTypeBits); + } + return memoryTypeBits; +} + #if VMA_STATS_STRING_ENABLED void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json) @@ -8438,10 +16193,9 @@ void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json) bool dedicatedAllocationsStarted = false; for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { - VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - AllocationVectorType* const pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex]; - VMA_ASSERT(pDedicatedAllocVector); - if(pDedicatedAllocVector->empty() == false) + VmaMutexLockRead dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); + DedicatedAllocationLinkedList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex]; + if(!dedicatedAllocList.IsEmpty()) { if(dedicatedAllocationsStarted == false) { @@ -8453,36 +16207,14 @@ void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json) json.BeginString("Type "); json.ContinueString(memTypeIndex); json.EndString(); - + json.BeginArray(); - for(size_t i = 0; i < pDedicatedAllocVector->size(); ++i) + for(VmaAllocation alloc = dedicatedAllocList.Front(); + alloc != VMA_NULL; alloc = dedicatedAllocList.GetNext(alloc)) { - const VmaAllocation hAlloc = (*pDedicatedAllocVector)[i]; json.BeginObject(true); - - json.WriteString("Type"); - json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[hAlloc->GetSuballocationType()]); - - json.WriteString("Size"); - json.WriteNumber(hAlloc->GetSize()); - - const void* pUserData = hAlloc->GetUserData(); - if(pUserData != VMA_NULL) - { - json.WriteString("UserData"); - if(hAlloc->IsUserDataString()) - { - json.WriteString((const char*)pUserData); - } - else - { - json.BeginString(); - json.ContinueString_Pointer(pUserData); - json.EndString(); - } - } - + alloc->PrintParameters(json); json.EndObject(); } @@ -8520,64 +16252,44 @@ void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json) } } + // Custom pools { - VmaMutexLock lock(m_PoolsMutex, m_UseMutex); - const size_t poolCount = m_Pools.size(); - if(poolCount > 0) + VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex); + if(!m_Pools.IsEmpty()) { json.WriteString("Pools"); - json.BeginArray(); - for(size_t poolIndex = 0; poolIndex < poolCount; ++poolIndex) + json.BeginObject(); + for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool)) { - m_Pools[poolIndex]->m_BlockVector.PrintDetailedMap(json); + json.BeginString(); + json.ContinueString(pool->GetId()); + json.EndString(); + + pool->m_BlockVector.PrintDetailedMap(json); } - json.EndArray(); + json.EndObject(); } } } #endif // #if VMA_STATS_STRING_ENABLED -static VkResult AllocateMemoryForImage( - VmaAllocator allocator, - VkImage image, - const VmaAllocationCreateInfo* pAllocationCreateInfo, - VmaSuballocationType suballocType, - VmaAllocation* pAllocation) -{ - VMA_ASSERT(allocator && (image != VK_NULL_HANDLE) && pAllocationCreateInfo && pAllocation); - - VkMemoryRequirements vkMemReq = {}; - bool requiresDedicatedAllocation = false; - bool prefersDedicatedAllocation = false; - allocator->GetImageMemoryRequirements(image, vkMemReq, - requiresDedicatedAllocation, prefersDedicatedAllocation); - - return allocator->AllocateMemory( - vkMemReq, - requiresDedicatedAllocation, - prefersDedicatedAllocation, - VK_NULL_HANDLE, // dedicatedBuffer - image, // dedicatedImage - *pAllocationCreateInfo, - suballocType, - pAllocation); -} - //////////////////////////////////////////////////////////////////////////////// // Public interface -VkResult vmaCreateAllocator( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator( const VmaAllocatorCreateInfo* pCreateInfo, VmaAllocator* pAllocator) { VMA_ASSERT(pCreateInfo && pAllocator); + VMA_ASSERT(pCreateInfo->vulkanApiVersion == 0 || + (VK_VERSION_MAJOR(pCreateInfo->vulkanApiVersion) == 1 && VK_VERSION_MINOR(pCreateInfo->vulkanApiVersion) <= 2)); VMA_DEBUG_LOG("vmaCreateAllocator"); *pAllocator = vma_new(pCreateInfo->pAllocationCallbacks, VmaAllocator_T)(pCreateInfo); - return VK_SUCCESS; + return (*pAllocator)->Init(pCreateInfo); } -void vmaDestroyAllocator( +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator( VmaAllocator allocator) { if(allocator != VK_NULL_HANDLE) @@ -8588,7 +16300,15 @@ void vmaDestroyAllocator( } } -void vmaGetPhysicalDeviceProperties( +VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocatorInfo(VmaAllocator allocator, VmaAllocatorInfo* pAllocatorInfo) +{ + VMA_ASSERT(allocator && pAllocatorInfo); + pAllocatorInfo->instance = allocator->m_hInstance; + pAllocatorInfo->physicalDevice = allocator->GetPhysicalDevice(); + pAllocatorInfo->device = allocator->m_hDevice; +} + +VMA_CALL_PRE void VMA_CALL_POST vmaGetPhysicalDeviceProperties( VmaAllocator allocator, const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties) { @@ -8596,7 +16316,7 @@ void vmaGetPhysicalDeviceProperties( *ppPhysicalDeviceProperties = &allocator->m_PhysicalDeviceProperties; } -void vmaGetMemoryProperties( +VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryProperties( VmaAllocator allocator, const VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties) { @@ -8604,7 +16324,7 @@ void vmaGetMemoryProperties( *ppPhysicalDeviceMemoryProperties = &allocator->m_MemProps; } -void vmaGetMemoryTypeProperties( +VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryTypeProperties( VmaAllocator allocator, uint32_t memoryTypeIndex, VkMemoryPropertyFlags* pFlags) @@ -8614,7 +16334,7 @@ void vmaGetMemoryTypeProperties( *pFlags = allocator->m_MemProps.memoryTypes[memoryTypeIndex].propertyFlags; } -void vmaSetCurrentFrameIndex( +VMA_CALL_PRE void VMA_CALL_POST vmaSetCurrentFrameIndex( VmaAllocator allocator, uint32_t frameIndex) { @@ -8626,7 +16346,7 @@ void vmaSetCurrentFrameIndex( allocator->SetCurrentFrameIndex(frameIndex); } -void vmaCalculateStats( +VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStats( VmaAllocator allocator, VmaStats* pStats) { @@ -8635,9 +16355,18 @@ void vmaCalculateStats( allocator->CalculateStats(pStats); } +VMA_CALL_PRE void VMA_CALL_POST vmaGetBudget( + VmaAllocator allocator, + VmaBudget* pBudget) +{ + VMA_ASSERT(allocator && pBudget); + VMA_DEBUG_GLOBAL_MUTEX_LOCK + allocator->GetBudget(pBudget, 0, allocator->GetMemoryHeapCount()); +} + #if VMA_STATS_STRING_ENABLED -void vmaBuildStatsString( +VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString( VmaAllocator allocator, char** ppStatsString, VkBool32 detailedMap) @@ -8650,12 +16379,15 @@ void vmaBuildStatsString( VmaJsonWriter json(allocator->GetAllocationCallbacks(), sb); json.BeginObject(); + VmaBudget budget[VK_MAX_MEMORY_HEAPS]; + allocator->GetBudget(budget, 0, allocator->GetMemoryHeapCount()); + VmaStats stats; allocator->CalculateStats(&stats); json.WriteString("Total"); VmaPrintStatInfo(json, stats.total); - + for(uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex) { json.BeginString("Heap "); @@ -8674,6 +16406,20 @@ void vmaBuildStatsString( } json.EndArray(); + json.WriteString("Budget"); + json.BeginObject(); + { + json.WriteString("BlockBytes"); + json.WriteNumber(budget[heapIndex].blockBytes); + json.WriteString("AllocationBytes"); + json.WriteNumber(budget[heapIndex].allocationBytes); + json.WriteString("Usage"); + json.WriteNumber(budget[heapIndex].usage); + json.WriteString("Budget"); + json.WriteNumber(budget[heapIndex].budget); + } + json.EndObject(); + if(stats.memoryHeap[heapIndex].blockCount > 0) { json.WriteString("Stats"); @@ -8713,6 +16459,22 @@ void vmaBuildStatsString( { json.WriteString("LAZILY_ALLOCATED"); } +#if VMA_VULKAN_VERSION >= 1001000 + if((flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0) + { + json.WriteString("PROTECTED"); + } +#endif // #if VMA_VULKAN_VERSION >= 1001000 +#if VK_AMD_device_coherent_memory + if((flags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY) != 0) + { + json.WriteString("DEVICE_COHERENT"); + } + if((flags & VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY) != 0) + { + json.WriteString("DEVICE_UNCACHED"); + } +#endif // #if VK_AMD_device_coherent_memory json.EndArray(); if(stats.memoryType[typeIndex].blockCount > 0) @@ -8745,7 +16507,7 @@ void vmaBuildStatsString( *ppStatsString = pChars; } -void vmaFreeStatsString( +VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString( VmaAllocator allocator, char* pStatsString) { @@ -8762,7 +16524,7 @@ void vmaFreeStatsString( /* This function is not protected by any mutex because it just reads immutable data. */ -VkResult vmaFindMemoryTypeIndex( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex( VmaAllocator allocator, uint32_t memoryTypeBits, const VmaAllocationCreateInfo* pAllocationCreateInfo, @@ -8772,13 +16534,16 @@ VkResult vmaFindMemoryTypeIndex( VMA_ASSERT(pAllocationCreateInfo != VMA_NULL); VMA_ASSERT(pMemoryTypeIndex != VMA_NULL); + memoryTypeBits &= allocator->GetGlobalMemoryTypeBits(); + if(pAllocationCreateInfo->memoryTypeBits != 0) { memoryTypeBits &= pAllocationCreateInfo->memoryTypeBits; } - + uint32_t requiredFlags = pAllocationCreateInfo->requiredFlags; uint32_t preferredFlags = pAllocationCreateInfo->preferredFlags; + uint32_t notPreferredFlags = 0; // Convert usage to requiredFlags and preferredFlags. switch(pAllocationCreateInfo->usage) @@ -8786,23 +16551,43 @@ VkResult vmaFindMemoryTypeIndex( case VMA_MEMORY_USAGE_UNKNOWN: break; case VMA_MEMORY_USAGE_GPU_ONLY: - preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + if(!allocator->IsIntegratedGpu() || (preferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) + { + preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } break; case VMA_MEMORY_USAGE_CPU_ONLY: requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; break; case VMA_MEMORY_USAGE_CPU_TO_GPU: requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + if(!allocator->IsIntegratedGpu() || (preferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) + { + preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } break; case VMA_MEMORY_USAGE_GPU_TO_CPU: requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - preferredFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + preferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + break; + case VMA_MEMORY_USAGE_CPU_COPY: + notPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + break; + case VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED: + requiredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT; break; default: + VMA_ASSERT(0); break; } + // Avoid DEVICE_COHERENT unless explicitly requested. + if(((pAllocationCreateInfo->requiredFlags | pAllocationCreateInfo->preferredFlags) & + (VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY)) == 0) + { + notPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY; + } + *pMemoryTypeIndex = UINT32_MAX; uint32_t minCost = UINT32_MAX; for(uint32_t memTypeIndex = 0, memTypeBit = 1; @@ -8818,7 +16603,8 @@ VkResult vmaFindMemoryTypeIndex( if((requiredFlags & ~currFlags) == 0) { // Calculate cost as number of bits from preferredFlags not present in this memory type. - uint32_t currCost = VmaCountBitsSet(preferredFlags & ~currFlags); + uint32_t currCost = VmaCountBitsSet(preferredFlags & ~currFlags) + + VmaCountBitsSet(currFlags & notPreferredFlags); // Remember memory type with lowest cost. if(currCost < minCost) { @@ -8835,7 +16621,7 @@ VkResult vmaFindMemoryTypeIndex( return (*pMemoryTypeIndex != UINT32_MAX) ? VK_SUCCESS : VK_ERROR_FEATURE_NOT_PRESENT; } -VkResult vmaFindMemoryTypeIndexForBufferInfo( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo( VmaAllocator allocator, const VkBufferCreateInfo* pBufferCreateInfo, const VmaAllocationCreateInfo* pAllocationCreateInfo, @@ -8868,7 +16654,7 @@ VkResult vmaFindMemoryTypeIndexForBufferInfo( return res; } -VkResult vmaFindMemoryTypeIndexForImageInfo( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo( VmaAllocator allocator, const VkImageCreateInfo* pImageCreateInfo, const VmaAllocationCreateInfo* pAllocationCreateInfo, @@ -8901,10 +16687,10 @@ VkResult vmaFindMemoryTypeIndexForImageInfo( return res; } -VkResult vmaCreatePool( - VmaAllocator allocator, - const VmaPoolCreateInfo* pCreateInfo, - VmaPool* pPool) +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreatePool( + VmaAllocator allocator, + const VmaPoolCreateInfo* pCreateInfo, + VmaPool* pPool) { VMA_ASSERT(allocator && pCreateInfo && pPool); @@ -8912,10 +16698,19 @@ VkResult vmaCreatePool( VMA_DEBUG_GLOBAL_MUTEX_LOCK - return allocator->CreatePool(pCreateInfo, pPool); + VkResult res = allocator->CreatePool(pCreateInfo, pPool); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordCreatePool(allocator->GetCurrentFrameIndex(), *pCreateInfo, *pPool); + } +#endif + + return res; } -void vmaDestroyPool( +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool( VmaAllocator allocator, VmaPool pool) { @@ -8930,10 +16725,17 @@ void vmaDestroyPool( VMA_DEBUG_GLOBAL_MUTEX_LOCK +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordDestroyPool(allocator->GetCurrentFrameIndex(), pool); + } +#endif + allocator->DestroyPool(pool); } -void vmaGetPoolStats( +VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStats( VmaAllocator allocator, VmaPool pool, VmaPoolStats* pPoolStats) @@ -8945,7 +16747,7 @@ void vmaGetPoolStats( allocator->GetPoolStats(pool, pPoolStats); } -void vmaMakePoolAllocationsLost( +VMA_CALL_PRE void VMA_CALL_POST vmaMakePoolAllocationsLost( VmaAllocator allocator, VmaPool pool, size_t* pLostAllocationCount) @@ -8954,10 +16756,63 @@ void vmaMakePoolAllocationsLost( VMA_DEBUG_GLOBAL_MUTEX_LOCK +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordMakePoolAllocationsLost(allocator->GetCurrentFrameIndex(), pool); + } +#endif + allocator->MakePoolAllocationsLost(pool, pLostAllocationCount); } -VkResult vmaAllocateMemory( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool) +{ + VMA_ASSERT(allocator && pool); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + VMA_DEBUG_LOG("vmaCheckPoolCorruption"); + + return allocator->CheckPoolCorruption(pool); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName( + VmaAllocator allocator, + VmaPool pool, + const char** ppName) +{ + VMA_ASSERT(allocator && pool && ppName); + + VMA_DEBUG_LOG("vmaGetPoolName"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + *ppName = pool->GetName(); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName( + VmaAllocator allocator, + VmaPool pool, + const char* pName) +{ + VMA_ASSERT(allocator && pool); + + VMA_DEBUG_LOG("vmaSetPoolName"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + pool->SetName(pName); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordSetPoolName(allocator->GetCurrentFrameIndex(), pool, pName); + } +#endif +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory( VmaAllocator allocator, const VkMemoryRequirements* pVkMemoryRequirements, const VmaAllocationCreateInfo* pCreateInfo, @@ -8970,25 +16825,92 @@ VkResult vmaAllocateMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK - VkResult result = allocator->AllocateMemory( + VkResult result = allocator->AllocateMemory( *pVkMemoryRequirements, false, // requiresDedicatedAllocation false, // prefersDedicatedAllocation VK_NULL_HANDLE, // dedicatedBuffer + UINT32_MAX, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage *pCreateInfo, VMA_SUBALLOCATION_TYPE_UNKNOWN, + 1, // allocationCount pAllocation); - if(pAllocationInfo && result == VK_SUCCESS) +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordAllocateMemory( + allocator->GetCurrentFrameIndex(), + *pVkMemoryRequirements, + *pCreateInfo, + *pAllocation); + } +#endif + + if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); } - return result; + return result; } -VkResult vmaAllocateMemoryForBuffer( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages( + VmaAllocator allocator, + const VkMemoryRequirements* pVkMemoryRequirements, + const VmaAllocationCreateInfo* pCreateInfo, + size_t allocationCount, + VmaAllocation* pAllocations, + VmaAllocationInfo* pAllocationInfo) +{ + if(allocationCount == 0) + { + return VK_SUCCESS; + } + + VMA_ASSERT(allocator && pVkMemoryRequirements && pCreateInfo && pAllocations); + + VMA_DEBUG_LOG("vmaAllocateMemoryPages"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + VkResult result = allocator->AllocateMemory( + *pVkMemoryRequirements, + false, // requiresDedicatedAllocation + false, // prefersDedicatedAllocation + VK_NULL_HANDLE, // dedicatedBuffer + UINT32_MAX, // dedicatedBufferUsage + VK_NULL_HANDLE, // dedicatedImage + *pCreateInfo, + VMA_SUBALLOCATION_TYPE_UNKNOWN, + allocationCount, + pAllocations); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordAllocateMemoryPages( + allocator->GetCurrentFrameIndex(), + *pVkMemoryRequirements, + *pCreateInfo, + (uint64_t)allocationCount, + pAllocations); + } +#endif + + if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS) + { + for(size_t i = 0; i < allocationCount; ++i) + { + allocator->GetAllocationInfo(pAllocations[i], pAllocationInfo + i); + } + } + + return result; +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer( VmaAllocator allocator, VkBuffer buffer, const VmaAllocationCreateInfo* pCreateInfo, @@ -9013,20 +16935,35 @@ VkResult vmaAllocateMemoryForBuffer( requiresDedicatedAllocation, prefersDedicatedAllocation, buffer, // dedicatedBuffer + UINT32_MAX, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage *pCreateInfo, VMA_SUBALLOCATION_TYPE_BUFFER, + 1, // allocationCount pAllocation); +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordAllocateMemoryForBuffer( + allocator->GetCurrentFrameIndex(), + vkMemReq, + requiresDedicatedAllocation, + prefersDedicatedAllocation, + *pCreateInfo, + *pAllocation); + } +#endif + if(pAllocationInfo && result == VK_SUCCESS) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); } - return result; + return result; } -VkResult vmaAllocateMemoryForImage( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage( VmaAllocator allocator, VkImage image, const VmaAllocationCreateInfo* pCreateInfo, @@ -9039,35 +16976,104 @@ VkResult vmaAllocateMemoryForImage( VMA_DEBUG_GLOBAL_MUTEX_LOCK - VkResult result = AllocateMemoryForImage( - allocator, - image, - pCreateInfo, + VkMemoryRequirements vkMemReq = {}; + bool requiresDedicatedAllocation = false; + bool prefersDedicatedAllocation = false; + allocator->GetImageMemoryRequirements(image, vkMemReq, + requiresDedicatedAllocation, prefersDedicatedAllocation); + + VkResult result = allocator->AllocateMemory( + vkMemReq, + requiresDedicatedAllocation, + prefersDedicatedAllocation, + VK_NULL_HANDLE, // dedicatedBuffer + UINT32_MAX, // dedicatedBufferUsage + image, // dedicatedImage + *pCreateInfo, VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN, + 1, // allocationCount pAllocation); +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordAllocateMemoryForImage( + allocator->GetCurrentFrameIndex(), + vkMemReq, + requiresDedicatedAllocation, + prefersDedicatedAllocation, + *pCreateInfo, + *pAllocation); + } +#endif + if(pAllocationInfo && result == VK_SUCCESS) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); } - return result; + return result; } -void vmaFreeMemory( +VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemory( VmaAllocator allocator, VmaAllocation allocation) { - VMA_ASSERT(allocator && allocation); + VMA_ASSERT(allocator); + + if(allocation == VK_NULL_HANDLE) + { + return; + } VMA_DEBUG_LOG("vmaFreeMemory"); VMA_DEBUG_GLOBAL_MUTEX_LOCK - allocator->FreeMemory(allocation); +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordFreeMemory( + allocator->GetCurrentFrameIndex(), + allocation); + } +#endif + + allocator->FreeMemory( + 1, // allocationCount + &allocation); } -void vmaGetAllocationInfo( +VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemoryPages( + VmaAllocator allocator, + size_t allocationCount, + const VmaAllocation* pAllocations) +{ + if(allocationCount == 0) + { + return; + } + + VMA_ASSERT(allocator); + + VMA_DEBUG_LOG("vmaFreeMemoryPages"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordFreeMemoryPages( + allocator->GetCurrentFrameIndex(), + (uint64_t)allocationCount, + pAllocations); + } +#endif + + allocator->FreeMemory(allocationCount, pAllocations); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationInfo( VmaAllocator allocator, VmaAllocation allocation, VmaAllocationInfo* pAllocationInfo) @@ -9076,10 +17082,19 @@ void vmaGetAllocationInfo( VMA_DEBUG_GLOBAL_MUTEX_LOCK +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordGetAllocationInfo( + allocator->GetCurrentFrameIndex(), + allocation); + } +#endif + allocator->GetAllocationInfo(allocation, pAllocationInfo); } -VkBool32 vmaTouchAllocation( +VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaTouchAllocation( VmaAllocator allocator, VmaAllocation allocation) { @@ -9087,10 +17102,19 @@ VkBool32 vmaTouchAllocation( VMA_DEBUG_GLOBAL_MUTEX_LOCK +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordTouchAllocation( + allocator->GetCurrentFrameIndex(), + allocation); + } +#endif + return allocator->TouchAllocation(allocation); } -void vmaSetAllocationUserData( +VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData( VmaAllocator allocator, VmaAllocation allocation, void* pUserData) @@ -9100,9 +17124,19 @@ void vmaSetAllocationUserData( VMA_DEBUG_GLOBAL_MUTEX_LOCK allocation->SetUserData(allocator, pUserData); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordSetAllocationUserData( + allocator->GetCurrentFrameIndex(), + allocation, + pUserData); + } +#endif } -void vmaCreateLostAllocation( +VMA_CALL_PRE void VMA_CALL_POST vmaCreateLostAllocation( VmaAllocator allocator, VmaAllocation* pAllocation) { @@ -9111,9 +17145,18 @@ void vmaCreateLostAllocation( VMA_DEBUG_GLOBAL_MUTEX_LOCK; allocator->CreateLostAllocation(pAllocation); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordCreateLostAllocation( + allocator->GetCurrentFrameIndex(), + *pAllocation); + } +#endif } -VkResult vmaMapMemory( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaMapMemory( VmaAllocator allocator, VmaAllocation allocation, void** ppData) @@ -9122,10 +17165,21 @@ VkResult vmaMapMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK - return allocator->Map(allocation, ppData); + VkResult res = allocator->Map(allocation, ppData); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordMapMemory( + allocator->GetCurrentFrameIndex(), + allocation); + } +#endif + + return res; } -void vmaUnmapMemory( +VMA_CALL_PRE void VMA_CALL_POST vmaUnmapMemory( VmaAllocator allocator, VmaAllocation allocation) { @@ -9133,27 +17187,273 @@ void vmaUnmapMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordUnmapMemory( + allocator->GetCurrentFrameIndex(), + allocation); + } +#endif + allocator->Unmap(allocation); } -VkResult vmaDefragment( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) +{ + VMA_ASSERT(allocator && allocation); + + VMA_DEBUG_LOG("vmaFlushAllocation"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + const VkResult res = allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_FLUSH); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordFlushAllocation( + allocator->GetCurrentFrameIndex(), + allocation, offset, size); + } +#endif + + return res; +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) +{ + VMA_ASSERT(allocator && allocation); + + VMA_DEBUG_LOG("vmaInvalidateAllocation"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + const VkResult res = allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_INVALIDATE); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordInvalidateAllocation( + allocator->GetCurrentFrameIndex(), + allocation, offset, size); + } +#endif + + return res; +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocations( VmaAllocator allocator, - VmaAllocation* pAllocations, + uint32_t allocationCount, + const VmaAllocation* allocations, + const VkDeviceSize* offsets, + const VkDeviceSize* sizes) +{ + VMA_ASSERT(allocator); + + if(allocationCount == 0) + { + return VK_SUCCESS; + } + + VMA_ASSERT(allocations); + + VMA_DEBUG_LOG("vmaFlushAllocations"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + const VkResult res = allocator->FlushOrInvalidateAllocations(allocationCount, allocations, offsets, sizes, VMA_CACHE_FLUSH); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + //TODO + } +#endif + + return res; +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocations( + VmaAllocator allocator, + uint32_t allocationCount, + const VmaAllocation* allocations, + const VkDeviceSize* offsets, + const VkDeviceSize* sizes) +{ + VMA_ASSERT(allocator); + + if(allocationCount == 0) + { + return VK_SUCCESS; + } + + VMA_ASSERT(allocations); + + VMA_DEBUG_LOG("vmaInvalidateAllocations"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + const VkResult res = allocator->FlushOrInvalidateAllocations(allocationCount, allocations, offsets, sizes, VMA_CACHE_INVALIDATE); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + //TODO + } +#endif + + return res; +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(VmaAllocator allocator, uint32_t memoryTypeBits) +{ + VMA_ASSERT(allocator); + + VMA_DEBUG_LOG("vmaCheckCorruption"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + return allocator->CheckCorruption(memoryTypeBits); +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragment( + VmaAllocator allocator, + const VmaAllocation* pAllocations, size_t allocationCount, VkBool32* pAllocationsChanged, const VmaDefragmentationInfo *pDefragmentationInfo, VmaDefragmentationStats* pDefragmentationStats) { - VMA_ASSERT(allocator && pAllocations); + // Deprecated interface, reimplemented using new one. - VMA_DEBUG_LOG("vmaDefragment"); + VmaDefragmentationInfo2 info2 = {}; + info2.allocationCount = (uint32_t)allocationCount; + info2.pAllocations = pAllocations; + info2.pAllocationsChanged = pAllocationsChanged; + if(pDefragmentationInfo != VMA_NULL) + { + info2.maxCpuAllocationsToMove = pDefragmentationInfo->maxAllocationsToMove; + info2.maxCpuBytesToMove = pDefragmentationInfo->maxBytesToMove; + } + else + { + info2.maxCpuAllocationsToMove = UINT32_MAX; + info2.maxCpuBytesToMove = VK_WHOLE_SIZE; + } + // info2.flags, maxGpuAllocationsToMove, maxGpuBytesToMove, commandBuffer deliberately left zero. + + VmaDefragmentationContext ctx; + VkResult res = vmaDefragmentationBegin(allocator, &info2, pDefragmentationStats, &ctx); + if(res == VK_NOT_READY) + { + res = vmaDefragmentationEnd( allocator, ctx); + } + return res; +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationBegin( + VmaAllocator allocator, + const VmaDefragmentationInfo2* pInfo, + VmaDefragmentationStats* pStats, + VmaDefragmentationContext *pContext) +{ + VMA_ASSERT(allocator && pInfo && pContext); + + // Degenerate case: Nothing to defragment. + if(pInfo->allocationCount == 0 && pInfo->poolCount == 0) + { + return VK_SUCCESS; + } + + VMA_ASSERT(pInfo->allocationCount == 0 || pInfo->pAllocations != VMA_NULL); + VMA_ASSERT(pInfo->poolCount == 0 || pInfo->pPools != VMA_NULL); + VMA_HEAVY_ASSERT(VmaValidatePointerArray(pInfo->allocationCount, pInfo->pAllocations)); + VMA_HEAVY_ASSERT(VmaValidatePointerArray(pInfo->poolCount, pInfo->pPools)); + + VMA_DEBUG_LOG("vmaDefragmentationBegin"); VMA_DEBUG_GLOBAL_MUTEX_LOCK - return allocator->Defragment(pAllocations, allocationCount, pAllocationsChanged, pDefragmentationInfo, pDefragmentationStats); + VkResult res = allocator->DefragmentationBegin(*pInfo, pStats, pContext); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordDefragmentationBegin( + allocator->GetCurrentFrameIndex(), *pInfo, *pContext); + } +#endif + + return res; } -VkResult vmaBindBufferMemory( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationEnd( + VmaAllocator allocator, + VmaDefragmentationContext context) +{ + VMA_ASSERT(allocator); + + VMA_DEBUG_LOG("vmaDefragmentationEnd"); + + if(context != VK_NULL_HANDLE) + { + VMA_DEBUG_GLOBAL_MUTEX_LOCK + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordDefragmentationEnd( + allocator->GetCurrentFrameIndex(), context); + } +#endif + + return allocator->DefragmentationEnd(context); + } + else + { + return VK_SUCCESS; + } +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass( + VmaAllocator allocator, + VmaDefragmentationContext context, + VmaDefragmentationPassInfo* pInfo + ) +{ + VMA_ASSERT(allocator); + VMA_ASSERT(pInfo); + + VMA_DEBUG_LOG("vmaBeginDefragmentationPass"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + if(context == VK_NULL_HANDLE) + { + pInfo->moveCount = 0; + return VK_SUCCESS; + } + + return allocator->DefragmentationPassBegin(pInfo, context); +} +VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass( + VmaAllocator allocator, + VmaDefragmentationContext context) +{ + VMA_ASSERT(allocator); + + VMA_DEBUG_LOG("vmaEndDefragmentationPass"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + if(context == VK_NULL_HANDLE) + return VK_SUCCESS; + + return allocator->DefragmentationPassEnd(context); +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory( VmaAllocator allocator, VmaAllocation allocation, VkBuffer buffer) @@ -9164,10 +17464,26 @@ VkResult vmaBindBufferMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK - return allocator->BindBufferMemory(allocation, buffer); + return allocator->BindBufferMemory(allocation, 0, buffer, VMA_NULL); } -VkResult vmaBindImageMemory( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory2( + VmaAllocator allocator, + VmaAllocation allocation, + VkDeviceSize allocationLocalOffset, + VkBuffer buffer, + const void* pNext) +{ + VMA_ASSERT(allocator && allocation && buffer); + + VMA_DEBUG_LOG("vmaBindBufferMemory2"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + return allocator->BindBufferMemory(allocation, allocationLocalOffset, buffer, pNext); +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory( VmaAllocator allocator, VmaAllocation allocation, VkImage image) @@ -9178,10 +17494,26 @@ VkResult vmaBindImageMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK - return allocator->BindImageMemory(allocation, image); + return allocator->BindImageMemory(allocation, 0, image, VMA_NULL); } -VkResult vmaCreateBuffer( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory2( + VmaAllocator allocator, + VmaAllocation allocation, + VkDeviceSize allocationLocalOffset, + VkImage image, + const void* pNext) +{ + VMA_ASSERT(allocator && allocation && image); + + VMA_DEBUG_LOG("vmaBindImageMemory2"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + return allocator->BindImageMemory(allocation, allocationLocalOffset, image, pNext); +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer( VmaAllocator allocator, const VkBufferCreateInfo* pBufferCreateInfo, const VmaAllocationCreateInfo* pAllocationCreateInfo, @@ -9190,9 +17522,20 @@ VkResult vmaCreateBuffer( VmaAllocationInfo* pAllocationInfo) { VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && pBuffer && pAllocation); - + + if(pBufferCreateInfo->size == 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } + if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 && + !allocator->m_UseKhrBufferDeviceAddress) + { + VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used."); + return VK_ERROR_INITIALIZATION_FAILED; + } + VMA_DEBUG_LOG("vmaCreateBuffer"); - + VMA_DEBUG_GLOBAL_MUTEX_LOCK *pBuffer = VK_NULL_HANDLE; @@ -9213,48 +17556,53 @@ VkResult vmaCreateBuffer( allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq, requiresDedicatedAllocation, prefersDedicatedAllocation); - // Make sure alignment requirements for specific buffer usages reported - // in Physical Device Properties are included in alignment reported by memory requirements. - if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) != 0) - { - VMA_ASSERT(vkMemReq.alignment % - allocator->m_PhysicalDeviceProperties.limits.minTexelBufferOffsetAlignment == 0); - } - if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) != 0) - { - VMA_ASSERT(vkMemReq.alignment % - allocator->m_PhysicalDeviceProperties.limits.minUniformBufferOffsetAlignment == 0); - } - if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0) - { - VMA_ASSERT(vkMemReq.alignment % - allocator->m_PhysicalDeviceProperties.limits.minStorageBufferOffsetAlignment == 0); - } - // 3. Allocate memory using allocator. res = allocator->AllocateMemory( vkMemReq, requiresDedicatedAllocation, prefersDedicatedAllocation, *pBuffer, // dedicatedBuffer + pBufferCreateInfo->usage, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage *pAllocationCreateInfo, VMA_SUBALLOCATION_TYPE_BUFFER, + 1, // allocationCount pAllocation); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordCreateBuffer( + allocator->GetCurrentFrameIndex(), + *pBufferCreateInfo, + *pAllocationCreateInfo, + *pAllocation); + } +#endif + if(res >= 0) { // 3. Bind buffer with memory. - res = allocator->BindBufferMemory(*pAllocation, *pBuffer); + if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0) + { + res = allocator->BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL); + } if(res >= 0) { // All steps succeeded. + #if VMA_STATS_STRING_ENABLED + (*pAllocation)->InitBufferImageUsage(pBufferCreateInfo->usage); + #endif if(pAllocationInfo != VMA_NULL) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); } + return VK_SUCCESS; } - allocator->FreeMemory(*pAllocation); + allocator->FreeMemory( + 1, // allocationCount + pAllocation); *pAllocation = VK_NULL_HANDLE; (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks()); *pBuffer = VK_NULL_HANDLE; @@ -9267,26 +17615,147 @@ VkResult vmaCreateBuffer( return res; } -void vmaDestroyBuffer( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment( + VmaAllocator allocator, + const VkBufferCreateInfo* pBufferCreateInfo, + const VmaAllocationCreateInfo* pAllocationCreateInfo, + VkDeviceSize minAlignment, + VkBuffer* pBuffer, + VmaAllocation* pAllocation, + VmaAllocationInfo* pAllocationInfo) +{ + VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && VmaIsPow2(minAlignment) && pBuffer && pAllocation); + + if(pBufferCreateInfo->size == 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } + if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 && + !allocator->m_UseKhrBufferDeviceAddress) + { + VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used."); + return VK_ERROR_INITIALIZATION_FAILED; + } + + VMA_DEBUG_LOG("vmaCreateBufferWithAlignment"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + *pBuffer = VK_NULL_HANDLE; + *pAllocation = VK_NULL_HANDLE; + + // 1. Create VkBuffer. + VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)( + allocator->m_hDevice, + pBufferCreateInfo, + allocator->GetAllocationCallbacks(), + pBuffer); + if(res >= 0) + { + // 2. vkGetBufferMemoryRequirements. + VkMemoryRequirements vkMemReq = {}; + bool requiresDedicatedAllocation = false; + bool prefersDedicatedAllocation = false; + allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq, + requiresDedicatedAllocation, prefersDedicatedAllocation); + + // 2a. Include minAlignment + vkMemReq.alignment = VMA_MAX(vkMemReq.alignment, minAlignment); + + // 3. Allocate memory using allocator. + res = allocator->AllocateMemory( + vkMemReq, + requiresDedicatedAllocation, + prefersDedicatedAllocation, + *pBuffer, // dedicatedBuffer + pBufferCreateInfo->usage, // dedicatedBufferUsage + VK_NULL_HANDLE, // dedicatedImage + *pAllocationCreateInfo, + VMA_SUBALLOCATION_TYPE_BUFFER, + 1, // allocationCount + pAllocation); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + VMA_ASSERT(0 && "Not implemented."); + } +#endif + + if(res >= 0) + { + // 3. Bind buffer with memory. + if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0) + { + res = allocator->BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL); + } + if(res >= 0) + { + // All steps succeeded. + #if VMA_STATS_STRING_ENABLED + (*pAllocation)->InitBufferImageUsage(pBufferCreateInfo->usage); + #endif + if(pAllocationInfo != VMA_NULL) + { + allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); + } + + return VK_SUCCESS; + } + allocator->FreeMemory( + 1, // allocationCount + pAllocation); + *pAllocation = VK_NULL_HANDLE; + (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks()); + *pBuffer = VK_NULL_HANDLE; + return res; + } + (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks()); + *pBuffer = VK_NULL_HANDLE; + return res; + } + return res; +} + +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer( VmaAllocator allocator, VkBuffer buffer, VmaAllocation allocation) { + VMA_ASSERT(allocator); + + if(buffer == VK_NULL_HANDLE && allocation == VK_NULL_HANDLE) + { + return; + } + + VMA_DEBUG_LOG("vmaDestroyBuffer"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordDestroyBuffer( + allocator->GetCurrentFrameIndex(), + allocation); + } +#endif + if(buffer != VK_NULL_HANDLE) { - VMA_ASSERT(allocator); - - VMA_DEBUG_LOG("vmaDestroyBuffer"); - - VMA_DEBUG_GLOBAL_MUTEX_LOCK - (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, buffer, allocator->GetAllocationCallbacks()); - - allocator->FreeMemory(allocation); + } + + if(allocation != VK_NULL_HANDLE) + { + allocator->FreeMemory( + 1, // allocationCount + &allocation); } } -VkResult vmaCreateImage( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage( VmaAllocator allocator, const VkImageCreateInfo* pImageCreateInfo, const VmaAllocationCreateInfo* pAllocationCreateInfo, @@ -9296,6 +17765,15 @@ VkResult vmaCreateImage( { VMA_ASSERT(allocator && pImageCreateInfo && pAllocationCreateInfo && pImage && pAllocation); + if(pImageCreateInfo->extent.width == 0 || + pImageCreateInfo->extent.height == 0 || + pImageCreateInfo->extent.depth == 0 || + pImageCreateInfo->mipLevels == 0 || + pImageCreateInfo->arrayLayers == 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } + VMA_DEBUG_LOG("vmaCreateImage"); VMA_DEBUG_GLOBAL_MUTEX_LOCK @@ -9314,23 +17792,60 @@ VkResult vmaCreateImage( VmaSuballocationType suballocType = pImageCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ? VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL : VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR; - + // 2. Allocate memory using allocator. - res = AllocateMemoryForImage(allocator, *pImage, pAllocationCreateInfo, suballocType, pAllocation); + VkMemoryRequirements vkMemReq = {}; + bool requiresDedicatedAllocation = false; + bool prefersDedicatedAllocation = false; + allocator->GetImageMemoryRequirements(*pImage, vkMemReq, + requiresDedicatedAllocation, prefersDedicatedAllocation); + + res = allocator->AllocateMemory( + vkMemReq, + requiresDedicatedAllocation, + prefersDedicatedAllocation, + VK_NULL_HANDLE, // dedicatedBuffer + UINT32_MAX, // dedicatedBufferUsage + *pImage, // dedicatedImage + *pAllocationCreateInfo, + suballocType, + 1, // allocationCount + pAllocation); + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordCreateImage( + allocator->GetCurrentFrameIndex(), + *pImageCreateInfo, + *pAllocationCreateInfo, + *pAllocation); + } +#endif + if(res >= 0) { // 3. Bind image with memory. - res = allocator->BindImageMemory(*pAllocation, *pImage); + if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0) + { + res = allocator->BindImageMemory(*pAllocation, 0, *pImage, VMA_NULL); + } if(res >= 0) { // All steps succeeded. + #if VMA_STATS_STRING_ENABLED + (*pAllocation)->InitBufferImageUsage(pImageCreateInfo->usage); + #endif if(pAllocationInfo != VMA_NULL) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); } + return VK_SUCCESS; } - allocator->FreeMemory(*pAllocation); + allocator->FreeMemory( + 1, // allocationCount + pAllocation); *pAllocation = VK_NULL_HANDLE; (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks()); *pImage = VK_NULL_HANDLE; @@ -9343,23 +17858,2001 @@ VkResult vmaCreateImage( return res; } -void vmaDestroyImage( +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage( VmaAllocator allocator, VkImage image, VmaAllocation allocation) { + VMA_ASSERT(allocator); + + if(image == VK_NULL_HANDLE && allocation == VK_NULL_HANDLE) + { + return; + } + + VMA_DEBUG_LOG("vmaDestroyImage"); + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + +#if VMA_RECORDING_ENABLED + if(allocator->GetRecorder() != VMA_NULL) + { + allocator->GetRecorder()->RecordDestroyImage( + allocator->GetCurrentFrameIndex(), + allocation); + } +#endif + if(image != VK_NULL_HANDLE) { - VMA_ASSERT(allocator); - - VMA_DEBUG_LOG("vmaDestroyImage"); - - VMA_DEBUG_GLOBAL_MUTEX_LOCK - (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, image, allocator->GetAllocationCallbacks()); - - allocator->FreeMemory(allocation); + } + if(allocation != VK_NULL_HANDLE) + { + allocator->FreeMemory( + 1, // allocationCount + &allocation); } } #endif // #ifdef VMA_IMPLEMENTATION + +/** +\page quick_start Quick start + +\section quick_start_project_setup Project setup + +Vulkan Memory Allocator comes in form of a "stb-style" single header file. +You don't need to build it as a separate library project. +You can add this file directly to your project and submit it to code repository next to your other source files. + +"Single header" doesn't mean that everything is contained in C/C++ declarations, +like it tends to be in case of inline functions or C++ templates. +It means that implementation is bundled with interface in a single file and needs to be extracted using preprocessor macro. +If you don't do it properly, you will get linker errors. + +To do it properly: + +-# Include "vk_mem_alloc.h" file in each CPP file where you want to use the library. + This includes declarations of all members of the library. +-# In exactly one CPP file define following macro before this include. + It enables also internal definitions. + +\code +#define VMA_IMPLEMENTATION +#include "vk_mem_alloc.h" +\endcode + +It may be a good idea to create dedicated CPP file just for this purpose. + +Note on language: This library is written in C++, but has C-compatible interface. +Thus you can include and use vk_mem_alloc.h in C or C++ code, but full +implementation with `VMA_IMPLEMENTATION` macro must be compiled as C++, NOT as C. + +Please note that this library includes header ``, which in turn +includes `` on Windows. If you need some specific macros defined +before including these headers (like `WIN32_LEAN_AND_MEAN` or +`WINVER` for Windows, `VK_USE_PLATFORM_WIN32_KHR` for Vulkan), you must define +them before every `#include` of this library. + +You may need to configure the way you import Vulkan functions. + +- By default, VMA assumes you you link statically with Vulkan API. If this is not the case, + `#define VMA_STATIC_VULKAN_FUNCTIONS 0` before `#include` of the VMA implementation and use another way. +- You can `#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1` and make sure `vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` globals are defined. + All the remaining Vulkan functions will be fetched automatically. +- Finally, you can provide your own pointers to all Vulkan functions needed by VMA using structure member + VmaAllocatorCreateInfo::pVulkanFunctions, if you fetched them in some custom way e.g. using some loader like [Volk](https://github.com/zeux/volk). + + +\section quick_start_initialization Initialization + +At program startup: + +-# Initialize Vulkan to have `VkPhysicalDevice`, `VkDevice` and `VkInstance` object. +-# Fill VmaAllocatorCreateInfo structure and create #VmaAllocator object by + calling vmaCreateAllocator(). + +\code +VmaAllocatorCreateInfo allocatorInfo = {}; +allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2; +allocatorInfo.physicalDevice = physicalDevice; +allocatorInfo.device = device; +allocatorInfo.instance = instance; + +VmaAllocator allocator; +vmaCreateAllocator(&allocatorInfo, &allocator); +\endcode + +Only members `physicalDevice`, `device`, `instance` are required. +However, you should inform the library which Vulkan version do you use by setting +VmaAllocatorCreateInfo::vulkanApiVersion and which extensions did you enable +by setting VmaAllocatorCreateInfo::flags (like #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT for VK_KHR_buffer_device_address). +Otherwise, VMA would use only features of Vulkan 1.0 core with no extensions. + + +\section quick_start_resource_allocation Resource allocation + +When you want to create a buffer or image: + +-# Fill `VkBufferCreateInfo` / `VkImageCreateInfo` structure. +-# Fill VmaAllocationCreateInfo structure. +-# Call vmaCreateBuffer() / vmaCreateImage() to get `VkBuffer`/`VkImage` with memory + already allocated and bound to it. + +\code +VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufferInfo.size = 65536; +bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + +VmaAllocationCreateInfo allocInfo = {}; +allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + +VkBuffer buffer; +VmaAllocation allocation; +vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); +\endcode + +Don't forget to destroy your objects when no longer needed: + +\code +vmaDestroyBuffer(allocator, buffer, allocation); +vmaDestroyAllocator(allocator); +\endcode + + +\page choosing_memory_type Choosing memory type + +Physical devices in Vulkan support various combinations of memory heaps and +types. Help with choosing correct and optimal memory type for your specific +resource is one of the key features of this library. You can use it by filling +appropriate members of VmaAllocationCreateInfo structure, as described below. +You can also combine multiple methods. + +-# If you just want to find memory type index that meets your requirements, you + can use function: vmaFindMemoryTypeIndex(), vmaFindMemoryTypeIndexForBufferInfo(), + vmaFindMemoryTypeIndexForImageInfo(). +-# If you want to allocate a region of device memory without association with any + specific image or buffer, you can use function vmaAllocateMemory(). Usage of + this function is not recommended and usually not needed. + vmaAllocateMemoryPages() function is also provided for creating multiple allocations at once, + which may be useful for sparse binding. +-# If you already have a buffer or an image created, you want to allocate memory + for it and then you will bind it yourself, you can use function + vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(). + For binding you should use functions: vmaBindBufferMemory(), vmaBindImageMemory() + or their extended versions: vmaBindBufferMemory2(), vmaBindImageMemory2(). +-# If you want to create a buffer or an image, allocate memory for it and bind + them together, all in one call, you can use function vmaCreateBuffer(), + vmaCreateImage(). This is the easiest and recommended way to use this library. + +When using 3. or 4., the library internally queries Vulkan for memory types +supported for that buffer or image (function `vkGetBufferMemoryRequirements()`) +and uses only one of these types. + +If no memory type can be found that meets all the requirements, these functions +return `VK_ERROR_FEATURE_NOT_PRESENT`. + +You can leave VmaAllocationCreateInfo structure completely filled with zeros. +It means no requirements are specified for memory type. +It is valid, although not very useful. + +\section choosing_memory_type_usage Usage + +The easiest way to specify memory requirements is to fill member +VmaAllocationCreateInfo::usage using one of the values of enum #VmaMemoryUsage. +It defines high level, common usage types. +For more details, see description of this enum. + +For example, if you want to create a uniform buffer that will be filled using +transfer only once or infrequently and used for rendering every frame, you can +do it using following code: + +\code +VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufferInfo.size = 65536; +bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + +VmaAllocationCreateInfo allocInfo = {}; +allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + +VkBuffer buffer; +VmaAllocation allocation; +vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); +\endcode + +\section choosing_memory_type_required_preferred_flags Required and preferred flags + +You can specify more detailed requirements by filling members +VmaAllocationCreateInfo::requiredFlags and VmaAllocationCreateInfo::preferredFlags +with a combination of bits from enum `VkMemoryPropertyFlags`. For example, +if you want to create a buffer that will be persistently mapped on host (so it +must be `HOST_VISIBLE`) and preferably will also be `HOST_COHERENT` and `HOST_CACHED`, +use following code: + +\code +VmaAllocationCreateInfo allocInfo = {}; +allocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; +allocInfo.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; +allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + +VkBuffer buffer; +VmaAllocation allocation; +vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); +\endcode + +A memory type is chosen that has all the required flags and as many preferred +flags set as possible. + +If you use VmaAllocationCreateInfo::usage, it is just internally converted to +a set of required and preferred flags. + +\section choosing_memory_type_explicit_memory_types Explicit memory types + +If you inspected memory types available on the physical device and you have +a preference for memory types that you want to use, you can fill member +VmaAllocationCreateInfo::memoryTypeBits. It is a bit mask, where each bit set +means that a memory type with that index is allowed to be used for the +allocation. Special value 0, just like `UINT32_MAX`, means there are no +restrictions to memory type index. + +Please note that this member is NOT just a memory type index. +Still you can use it to choose just one, specific memory type. +For example, if you already determined that your buffer should be created in +memory type 2, use following code: + +\code +uint32_t memoryTypeIndex = 2; + +VmaAllocationCreateInfo allocInfo = {}; +allocInfo.memoryTypeBits = 1u << memoryTypeIndex; + +VkBuffer buffer; +VmaAllocation allocation; +vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); +\endcode + + +\section choosing_memory_type_custom_memory_pools Custom memory pools + +If you allocate from custom memory pool, all the ways of specifying memory +requirements described above are not applicable and the aforementioned members +of VmaAllocationCreateInfo structure are ignored. Memory type is selected +explicitly when creating the pool and then used to make all the allocations from +that pool. For further details, see \ref custom_memory_pools. + +\section choosing_memory_type_dedicated_allocations Dedicated allocations + +Memory for allocations is reserved out of larger block of `VkDeviceMemory` +allocated from Vulkan internally. That is the main feature of this whole library. +You can still request a separate memory block to be created for an allocation, +just like you would do in a trivial solution without using any allocator. +In that case, a buffer or image is always bound to that memory at offset 0. +This is called a "dedicated allocation". +You can explicitly request it by using flag #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. +The library can also internally decide to use dedicated allocation in some cases, e.g.: + +- When the size of the allocation is large. +- When [VK_KHR_dedicated_allocation](@ref vk_khr_dedicated_allocation) extension is enabled + and it reports that dedicated allocation is required or recommended for the resource. +- When allocation of next big memory block fails due to not enough device memory, + but allocation with the exact requested size succeeds. + + +\page memory_mapping Memory mapping + +To "map memory" in Vulkan means to obtain a CPU pointer to `VkDeviceMemory`, +to be able to read from it or write to it in CPU code. +Mapping is possible only of memory allocated from a memory type that has +`VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag. +Functions `vkMapMemory()`, `vkUnmapMemory()` are designed for this purpose. +You can use them directly with memory allocated by this library, +but it is not recommended because of following issue: +Mapping the same `VkDeviceMemory` block multiple times is illegal - only one mapping at a time is allowed. +This includes mapping disjoint regions. Mapping is not reference-counted internally by Vulkan. +Because of this, Vulkan Memory Allocator provides following facilities: + +\section memory_mapping_mapping_functions Mapping functions + +The library provides following functions for mapping of a specific #VmaAllocation: vmaMapMemory(), vmaUnmapMemory(). +They are safer and more convenient to use than standard Vulkan functions. +You can map an allocation multiple times simultaneously - mapping is reference-counted internally. +You can also map different allocations simultaneously regardless of whether they use the same `VkDeviceMemory` block. +The way it is implemented is that the library always maps entire memory block, not just region of the allocation. +For further details, see description of vmaMapMemory() function. +Example: + +\code +// Having these objects initialized: + +struct ConstantBuffer +{ + ... +}; +ConstantBuffer constantBufferData; + +VmaAllocator allocator; +VkBuffer constantBuffer; +VmaAllocation constantBufferAllocation; + +// You can map and fill your buffer using following code: + +void* mappedData; +vmaMapMemory(allocator, constantBufferAllocation, &mappedData); +memcpy(mappedData, &constantBufferData, sizeof(constantBufferData)); +vmaUnmapMemory(allocator, constantBufferAllocation); +\endcode + +When mapping, you may see a warning from Vulkan validation layer similar to this one: + +Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used. + +It happens because the library maps entire `VkDeviceMemory` block, where different +types of images and buffers may end up together, especially on GPUs with unified memory like Intel. +You can safely ignore it if you are sure you access only memory of the intended +object that you wanted to map. + + +\section memory_mapping_persistently_mapped_memory Persistently mapped memory + +Kepping your memory persistently mapped is generally OK in Vulkan. +You don't need to unmap it before using its data on the GPU. +The library provides a special feature designed for that: +Allocations made with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag set in +VmaAllocationCreateInfo::flags stay mapped all the time, +so you can just access CPU pointer to it any time +without a need to call any "map" or "unmap" function. +Example: + +\code +VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufCreateInfo.size = sizeof(ConstantBuffer); +bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + +VkBuffer buf; +VmaAllocation alloc; +VmaAllocationInfo allocInfo; +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); + +// Buffer is already mapped. You can access its memory. +memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData)); +\endcode + +There are some exceptions though, when you should consider mapping memory only for a short period of time: + +- When operating system is Windows 7 or 8.x (Windows 10 is not affected because it uses WDDM2), + device is discrete AMD GPU, + and memory type is the special 256 MiB pool of `DEVICE_LOCAL + HOST_VISIBLE` memory + (selected when you use #VMA_MEMORY_USAGE_CPU_TO_GPU), + then whenever a memory block allocated from this memory type stays mapped + for the time of any call to `vkQueueSubmit()` or `vkQueuePresentKHR()`, this + block is migrated by WDDM to system RAM, which degrades performance. It doesn't + matter if that particular memory block is actually used by the command buffer + being submitted. +- Keeping many large memory blocks mapped may impact performance or stability of some debugging tools. + +\section memory_mapping_cache_control Cache flush and invalidate + +Memory in Vulkan doesn't need to be unmapped before using it on GPU, +but unless a memory types has `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` flag set, +you need to manually **invalidate** cache before reading of mapped pointer +and **flush** cache after writing to mapped pointer. +Map/unmap operations don't do that automatically. +Vulkan provides following functions for this purpose `vkFlushMappedMemoryRanges()`, +`vkInvalidateMappedMemoryRanges()`, but this library provides more convenient +functions that refer to given allocation object: vmaFlushAllocation(), +vmaInvalidateAllocation(), +or multiple objects at once: vmaFlushAllocations(), vmaInvalidateAllocations(). + +Regions of memory specified for flush/invalidate must be aligned to +`VkPhysicalDeviceLimits::nonCoherentAtomSize`. This is automatically ensured by the library. +In any memory type that is `HOST_VISIBLE` but not `HOST_COHERENT`, all allocations +within blocks are aligned to this value, so their offsets are always multiply of +`nonCoherentAtomSize` and two different allocations never share same "line" of this size. + +Please note that memory allocated with #VMA_MEMORY_USAGE_CPU_ONLY is guaranteed to be `HOST_COHERENT`. + +Also, Windows drivers from all 3 **PC** GPU vendors (AMD, Intel, NVIDIA) +currently provide `HOST_COHERENT` flag on all memory types that are +`HOST_VISIBLE`, so on this platform you may not need to bother. + +\section memory_mapping_finding_if_memory_mappable Finding out if memory is mappable + +It may happen that your allocation ends up in memory that is `HOST_VISIBLE` (available for mapping) +despite it wasn't explicitly requested. +For example, application may work on integrated graphics with unified memory (like Intel) or +allocation from video memory might have failed, so the library chose system memory as fallback. + +You can detect this case and map such allocation to access its memory on CPU directly, +instead of launching a transfer operation. +In order to do that: inspect `allocInfo.memoryType`, call vmaGetMemoryTypeProperties(), +and look for `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag in properties of that memory type. + +\code +VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufCreateInfo.size = sizeof(ConstantBuffer); +bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocCreateInfo.preferredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + +VkBuffer buf; +VmaAllocation alloc; +VmaAllocationInfo allocInfo; +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); + +VkMemoryPropertyFlags memFlags; +vmaGetMemoryTypeProperties(allocator, allocInfo.memoryType, &memFlags); +if((memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) +{ + // Allocation ended up in mappable memory. You can map it and access it directly. + void* mappedData; + vmaMapMemory(allocator, alloc, &mappedData); + memcpy(mappedData, &constantBufferData, sizeof(constantBufferData)); + vmaUnmapMemory(allocator, alloc); +} +else +{ + // Allocation ended up in non-mappable memory. + // You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer. +} +\endcode + +You can even use #VMA_ALLOCATION_CREATE_MAPPED_BIT flag while creating allocations +that are not necessarily `HOST_VISIBLE` (e.g. using #VMA_MEMORY_USAGE_GPU_ONLY). +If the allocation ends up in memory type that is `HOST_VISIBLE`, it will be persistently mapped and you can use it directly. +If not, the flag is just ignored. +Example: + +\code +VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufCreateInfo.size = sizeof(ConstantBuffer); +bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + +VkBuffer buf; +VmaAllocation alloc; +VmaAllocationInfo allocInfo; +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); + +if(allocInfo.pMappedData != nullptr) +{ + // Allocation ended up in mappable memory. + // It is persistently mapped. You can access it directly. + memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData)); +} +else +{ + // Allocation ended up in non-mappable memory. + // You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer. +} +\endcode + + +\page staying_within_budget Staying within budget + +When developing a graphics-intensive game or program, it is important to avoid allocating +more GPU memory than it is physically available. When the memory is over-committed, +various bad things can happen, depending on the specific GPU, graphics driver, and +operating system: + +- It may just work without any problems. +- The application may slow down because some memory blocks are moved to system RAM + and the GPU has to access them through PCI Express bus. +- A new allocation may take very long time to complete, even few seconds, and possibly + freeze entire system. +- The new allocation may fail with `VK_ERROR_OUT_OF_DEVICE_MEMORY`. +- It may even result in GPU crash (TDR), observed as `VK_ERROR_DEVICE_LOST` + returned somewhere later. + +\section staying_within_budget_querying_for_budget Querying for budget + +To query for current memory usage and available budget, use function vmaGetBudget(). +Returned structure #VmaBudget contains quantities expressed in bytes, per Vulkan memory heap. + +Please note that this function returns different information and works faster than +vmaCalculateStats(). vmaGetBudget() can be called every frame or even before every +allocation, while vmaCalculateStats() is intended to be used rarely, +only to obtain statistical information, e.g. for debugging purposes. + +It is recommended to use VK_EXT_memory_budget device extension to obtain information +about the budget from Vulkan device. VMA is able to use this extension automatically. +When not enabled, the allocator behaves same way, but then it estimates current usage +and available budget based on its internal information and Vulkan memory heap sizes, +which may be less precise. In order to use this extension: + +1. Make sure extensions VK_EXT_memory_budget and VK_KHR_get_physical_device_properties2 + required by it are available and enable them. Please note that the first is a device + extension and the second is instance extension! +2. Use flag #VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT when creating #VmaAllocator object. +3. Make sure to call vmaSetCurrentFrameIndex() every frame. Budget is queried from + Vulkan inside of it to avoid overhead of querying it with every allocation. + +\section staying_within_budget_controlling_memory_usage Controlling memory usage + +There are many ways in which you can try to stay within the budget. + +First, when making new allocation requires allocating a new memory block, the library +tries not to exceed the budget automatically. If a block with default recommended size +(e.g. 256 MB) would go over budget, a smaller block is allocated, possibly even +dedicated memory for just this resource. + +If the size of the requested resource plus current memory usage is more than the +budget, by default the library still tries to create it, leaving it to the Vulkan +implementation whether the allocation succeeds or fails. You can change this behavior +by using #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag. With it, the allocation is +not made if it would exceed the budget or if the budget is already exceeded. +Some other allocations become lost instead to make room for it, if the mechanism of +[lost allocations](@ref lost_allocations) is used. +If that is not possible, the allocation fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`. +Example usage pattern may be to pass the #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag +when creating resources that are not essential for the application (e.g. the texture +of a specific object) and not to pass it when creating critically important resources +(e.g. render targets). + +Finally, you can also use #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT flag to make sure +a new allocation is created only when it fits inside one of the existing memory blocks. +If it would require to allocate a new block, if fails instead with `VK_ERROR_OUT_OF_DEVICE_MEMORY`. +This also ensures that the function call is very fast because it never goes to Vulkan +to obtain a new block. + +Please note that creating \ref custom_memory_pools with VmaPoolCreateInfo::minBlockCount +set to more than 0 will try to allocate memory blocks without checking whether they +fit within budget. + + +\page resource_aliasing Resource aliasing (overlap) + +New explicit graphics APIs (Vulkan and Direct3D 12), thanks to manual memory +management, give an opportunity to alias (overlap) multiple resources in the +same region of memory - a feature not available in the old APIs (Direct3D 11, OpenGL). +It can be useful to save video memory, but it must be used with caution. + +For example, if you know the flow of your whole render frame in advance, you +are going to use some intermediate textures or buffers only during a small range of render passes, +and you know these ranges don't overlap in time, you can bind these resources to +the same place in memory, even if they have completely different parameters (width, height, format etc.). + +![Resource aliasing (overlap)](../gfx/Aliasing.png) + +Such scenario is possible using VMA, but you need to create your images manually. +Then you need to calculate parameters of an allocation to be made using formula: + +- allocation size = max(size of each image) +- allocation alignment = max(alignment of each image) +- allocation memoryTypeBits = bitwise AND(memoryTypeBits of each image) + +Following example shows two different images bound to the same place in memory, +allocated to fit largest of them. + +\code +// A 512x512 texture to be sampled. +VkImageCreateInfo img1CreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; +img1CreateInfo.imageType = VK_IMAGE_TYPE_2D; +img1CreateInfo.extent.width = 512; +img1CreateInfo.extent.height = 512; +img1CreateInfo.extent.depth = 1; +img1CreateInfo.mipLevels = 10; +img1CreateInfo.arrayLayers = 1; +img1CreateInfo.format = VK_FORMAT_R8G8B8A8_SRGB; +img1CreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; +img1CreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; +img1CreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; +img1CreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + +// A full screen texture to be used as color attachment. +VkImageCreateInfo img2CreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; +img2CreateInfo.imageType = VK_IMAGE_TYPE_2D; +img2CreateInfo.extent.width = 1920; +img2CreateInfo.extent.height = 1080; +img2CreateInfo.extent.depth = 1; +img2CreateInfo.mipLevels = 1; +img2CreateInfo.arrayLayers = 1; +img2CreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM; +img2CreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; +img2CreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; +img2CreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; +img2CreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + +VkImage img1; +res = vkCreateImage(device, &img1CreateInfo, nullptr, &img1); +VkImage img2; +res = vkCreateImage(device, &img2CreateInfo, nullptr, &img2); + +VkMemoryRequirements img1MemReq; +vkGetImageMemoryRequirements(device, img1, &img1MemReq); +VkMemoryRequirements img2MemReq; +vkGetImageMemoryRequirements(device, img2, &img2MemReq); + +VkMemoryRequirements finalMemReq = {}; +finalMemReq.size = std::max(img1MemReq.size, img2MemReq.size); +finalMemReq.alignment = std::max(img1MemReq.alignment, img2MemReq.alignment); +finalMemReq.memoryTypeBits = img1MemReq.memoryTypeBits & img2MemReq.memoryTypeBits; +// Validate if(finalMemReq.memoryTypeBits != 0) + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + +VmaAllocation alloc; +res = vmaAllocateMemory(allocator, &finalMemReq, &allocCreateInfo, &alloc, nullptr); + +res = vmaBindImageMemory(allocator, alloc, img1); +res = vmaBindImageMemory(allocator, alloc, img2); + +// You can use img1, img2 here, but not at the same time! + +vmaFreeMemory(allocator, alloc); +vkDestroyImage(allocator, img2, nullptr); +vkDestroyImage(allocator, img1, nullptr); +\endcode + +Remember that using resources that alias in memory requires proper synchronization. +You need to issue a memory barrier to make sure commands that use `img1` and `img2` +don't overlap on GPU timeline. +You also need to treat a resource after aliasing as uninitialized - containing garbage data. +For example, if you use `img1` and then want to use `img2`, you need to issue +an image memory barrier for `img2` with `oldLayout` = `VK_IMAGE_LAYOUT_UNDEFINED`. + +Additional considerations: + +- Vulkan also allows to interpret contents of memory between aliasing resources consistently in some cases. +See chapter 11.8. "Memory Aliasing" of Vulkan specification or `VK_IMAGE_CREATE_ALIAS_BIT` flag. +- You can create more complex layout where different images and buffers are bound +at different offsets inside one large allocation. For example, one can imagine +a big texture used in some render passes, aliasing with a set of many small buffers +used between in some further passes. To bind a resource at non-zero offset of an allocation, +use vmaBindBufferMemory2() / vmaBindImageMemory2(). +- Before allocating memory for the resources you want to alias, check `memoryTypeBits` +returned in memory requirements of each resource to make sure the bits overlap. +Some GPUs may expose multiple memory types suitable e.g. only for buffers or +images with `COLOR_ATTACHMENT` usage, so the sets of memory types supported by your +resources may be disjoint. Aliasing them is not possible in that case. + + +\page custom_memory_pools Custom memory pools + +A memory pool contains a number of `VkDeviceMemory` blocks. +The library automatically creates and manages default pool for each memory type available on the device. +Default memory pool automatically grows in size. +Size of allocated blocks is also variable and managed automatically. + +You can create custom pool and allocate memory out of it. +It can be useful if you want to: + +- Keep certain kind of allocations separate from others. +- Enforce particular, fixed size of Vulkan memory blocks. +- Limit maximum amount of Vulkan memory allocated for that pool. +- Reserve minimum or fixed amount of Vulkan memory always preallocated for that pool. +- Use extra parameters for a set of your allocations that are available in #VmaPoolCreateInfo but not in + #VmaAllocationCreateInfo - e.g., custom minimum alignment, custom `pNext` chain. + +To use custom memory pools: + +-# Fill VmaPoolCreateInfo structure. +-# Call vmaCreatePool() to obtain #VmaPool handle. +-# When making an allocation, set VmaAllocationCreateInfo::pool to this handle. + You don't need to specify any other parameters of this structure, like `usage`. + +Example: + +\code +// Create a pool that can have at most 2 blocks, 128 MiB each. +VmaPoolCreateInfo poolCreateInfo = {}; +poolCreateInfo.memoryTypeIndex = ... +poolCreateInfo.blockSize = 128ull * 1024 * 1024; +poolCreateInfo.maxBlockCount = 2; + +VmaPool pool; +vmaCreatePool(allocator, &poolCreateInfo, &pool); + +// Allocate a buffer out of it. +VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufCreateInfo.size = 1024; +bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.pool = pool; + +VkBuffer buf; +VmaAllocation alloc; +VmaAllocationInfo allocInfo; +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); +\endcode + +You have to free all allocations made from this pool before destroying it. + +\code +vmaDestroyBuffer(allocator, buf, alloc); +vmaDestroyPool(allocator, pool); +\endcode + +\section custom_memory_pools_MemTypeIndex Choosing memory type index + +When creating a pool, you must explicitly specify memory type index. +To find the one suitable for your buffers or images, you can use helper functions +vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo(). +You need to provide structures with example parameters of buffers or images +that you are going to create in that pool. + +\code +VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +exampleBufCreateInfo.size = 1024; // Whatever. +exampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // Change if needed. + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; // Change if needed. + +uint32_t memTypeIndex; +vmaFindMemoryTypeIndexForBufferInfo(allocator, &exampleBufCreateInfo, &allocCreateInfo, &memTypeIndex); + +VmaPoolCreateInfo poolCreateInfo = {}; +poolCreateInfo.memoryTypeIndex = memTypeIndex; +// ... +\endcode + +When creating buffers/images allocated in that pool, provide following parameters: + +- `VkBufferCreateInfo`: Prefer to pass same parameters as above. + Otherwise you risk creating resources in a memory type that is not suitable for them, which may result in undefined behavior. + Using different `VK_BUFFER_USAGE_` flags may work, but you shouldn't create images in a pool intended for buffers + or the other way around. +- VmaAllocationCreateInfo: You don't need to pass same parameters. Fill only `pool` member. + Other members are ignored anyway. + +\section linear_algorithm Linear allocation algorithm + +Each Vulkan memory block managed by this library has accompanying metadata that +keeps track of used and unused regions. By default, the metadata structure and +algorithm tries to find best place for new allocations among free regions to +optimize memory usage. This way you can allocate and free objects in any order. + +![Default allocation algorithm](../gfx/Linear_allocator_1_algo_default.png) + +Sometimes there is a need to use simpler, linear allocation algorithm. You can +create custom pool that uses such algorithm by adding flag +#VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT to VmaPoolCreateInfo::flags while creating +#VmaPool object. Then an alternative metadata management is used. It always +creates new allocations after last one and doesn't reuse free regions after +allocations freed in the middle. It results in better allocation performance and +less memory consumed by metadata. + +![Linear allocation algorithm](../gfx/Linear_allocator_2_algo_linear.png) + +With this one flag, you can create a custom pool that can be used in many ways: +free-at-once, stack, double stack, and ring buffer. See below for details. + +\subsection linear_algorithm_free_at_once Free-at-once + +In a pool that uses linear algorithm, you still need to free all the allocations +individually, e.g. by using vmaFreeMemory() or vmaDestroyBuffer(). You can free +them in any order. New allocations are always made after last one - free space +in the middle is not reused. However, when you release all the allocation and +the pool becomes empty, allocation starts from the beginning again. This way you +can use linear algorithm to speed up creation of allocations that you are going +to release all at once. + +![Free-at-once](../gfx/Linear_allocator_3_free_at_once.png) + +This mode is also available for pools created with VmaPoolCreateInfo::maxBlockCount +value that allows multiple memory blocks. + +\subsection linear_algorithm_stack Stack + +When you free an allocation that was created last, its space can be reused. +Thanks to this, if you always release allocations in the order opposite to their +creation (LIFO - Last In First Out), you can achieve behavior of a stack. + +![Stack](../gfx/Linear_allocator_4_stack.png) + +This mode is also available for pools created with VmaPoolCreateInfo::maxBlockCount +value that allows multiple memory blocks. + +\subsection linear_algorithm_double_stack Double stack + +The space reserved by a custom pool with linear algorithm may be used by two +stacks: + +- First, default one, growing up from offset 0. +- Second, "upper" one, growing down from the end towards lower offsets. + +To make allocation from upper stack, add flag #VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT +to VmaAllocationCreateInfo::flags. + +![Double stack](../gfx/Linear_allocator_7_double_stack.png) + +Double stack is available only in pools with one memory block - +VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined. + +When the two stacks' ends meet so there is not enough space between them for a +new allocation, such allocation fails with usual +`VK_ERROR_OUT_OF_DEVICE_MEMORY` error. + +\subsection linear_algorithm_ring_buffer Ring buffer + +When you free some allocations from the beginning and there is not enough free space +for a new one at the end of a pool, allocator's "cursor" wraps around to the +beginning and starts allocation there. Thanks to this, if you always release +allocations in the same order as you created them (FIFO - First In First Out), +you can achieve behavior of a ring buffer / queue. + +![Ring buffer](../gfx/Linear_allocator_5_ring_buffer.png) + +Pools with linear algorithm support [lost allocations](@ref lost_allocations) when used as ring buffer. +If there is not enough free space for a new allocation, but existing allocations +from the front of the queue can become lost, they become lost and the allocation +succeeds. + +![Ring buffer with lost allocations](../gfx/Linear_allocator_6_ring_buffer_lost.png) + +Ring buffer is available only in pools with one memory block - +VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined. + +\section buddy_algorithm Buddy allocation algorithm + +There is another allocation algorithm that can be used with custom pools, called +"buddy". Its internal data structure is based on a tree of blocks, each having +size that is a power of two and a half of its parent's size. When you want to +allocate memory of certain size, a free node in the tree is located. If it is too +large, it is recursively split into two halves (called "buddies"). However, if +requested allocation size is not a power of two, the size of a tree node is +aligned up to the nearest power of two and the remaining space is wasted. When +two buddy nodes become free, they are merged back into one larger node. + +![Buddy allocator](../gfx/Buddy_allocator.png) + +The advantage of buddy allocation algorithm over default algorithm is faster +allocation and deallocation, as well as smaller external fragmentation. The +disadvantage is more wasted space (internal fragmentation). + +For more information, please read ["Buddy memory allocation" on Wikipedia](https://en.wikipedia.org/wiki/Buddy_memory_allocation) +or other sources that describe this concept in general. + +To use buddy allocation algorithm with a custom pool, add flag +#VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT to VmaPoolCreateInfo::flags while creating +#VmaPool object. + +Several limitations apply to pools that use buddy algorithm: + +- It is recommended to use VmaPoolCreateInfo::blockSize that is a power of two. + Otherwise, only largest power of two smaller than the size is used for + allocations. The remaining space always stays unused. +- [Margins](@ref debugging_memory_usage_margins) and + [corruption detection](@ref debugging_memory_usage_corruption_detection) + don't work in such pools. +- [Lost allocations](@ref lost_allocations) don't work in such pools. You can + use them, but they never become lost. Support may be added in the future. +- [Defragmentation](@ref defragmentation) doesn't work with allocations made from + such pool. + +\page defragmentation Defragmentation + +Interleaved allocations and deallocations of many objects of varying size can +cause fragmentation over time, which can lead to a situation where the library is unable +to find a continuous range of free memory for a new allocation despite there is +enough free space, just scattered across many small free ranges between existing +allocations. + +To mitigate this problem, you can use defragmentation feature: +structure #VmaDefragmentationInfo2, function vmaDefragmentationBegin(), vmaDefragmentationEnd(). +Given set of allocations, +this function can move them to compact used memory, ensure more continuous free +space and possibly also free some `VkDeviceMemory` blocks. + +What the defragmentation does is: + +- Updates #VmaAllocation objects to point to new `VkDeviceMemory` and offset. + After allocation has been moved, its VmaAllocationInfo::deviceMemory and/or + VmaAllocationInfo::offset changes. You must query them again using + vmaGetAllocationInfo() if you need them. +- Moves actual data in memory. + +What it doesn't do, so you need to do it yourself: + +- Recreate buffers and images that were bound to allocations that were defragmented and + bind them with their new places in memory. + You must use `vkDestroyBuffer()`, `vkDestroyImage()`, + `vkCreateBuffer()`, `vkCreateImage()`, vmaBindBufferMemory(), vmaBindImageMemory() + for that purpose and NOT vmaDestroyBuffer(), + vmaDestroyImage(), vmaCreateBuffer(), vmaCreateImage(), because you don't need to + destroy or create allocation objects! +- Recreate views and update descriptors that point to these buffers and images. + +\section defragmentation_cpu Defragmenting CPU memory + +Following example demonstrates how you can run defragmentation on CPU. +Only allocations created in memory types that are `HOST_VISIBLE` can be defragmented. +Others are ignored. + +The way it works is: + +- It temporarily maps entire memory blocks when necessary. +- It moves data using `memmove()` function. + +\code +// Given following variables already initialized: +VkDevice device; +VmaAllocator allocator; +std::vector buffers; +std::vector allocations; + + +const uint32_t allocCount = (uint32_t)allocations.size(); +std::vector allocationsChanged(allocCount); + +VmaDefragmentationInfo2 defragInfo = {}; +defragInfo.allocationCount = allocCount; +defragInfo.pAllocations = allocations.data(); +defragInfo.pAllocationsChanged = allocationsChanged.data(); +defragInfo.maxCpuBytesToMove = VK_WHOLE_SIZE; // No limit. +defragInfo.maxCpuAllocationsToMove = UINT32_MAX; // No limit. + +VmaDefragmentationContext defragCtx; +vmaDefragmentationBegin(allocator, &defragInfo, nullptr, &defragCtx); +vmaDefragmentationEnd(allocator, defragCtx); + +for(uint32_t i = 0; i < allocCount; ++i) +{ + if(allocationsChanged[i]) + { + // Destroy buffer that is immutably bound to memory region which is no longer valid. + vkDestroyBuffer(device, buffers[i], nullptr); + + // Create new buffer with same parameters. + VkBufferCreateInfo bufferInfo = ...; + vkCreateBuffer(device, &bufferInfo, nullptr, &buffers[i]); + + // You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning. + + // Bind new buffer to new memory region. Data contained in it is already moved. + VmaAllocationInfo allocInfo; + vmaGetAllocationInfo(allocator, allocations[i], &allocInfo); + vmaBindBufferMemory(allocator, allocations[i], buffers[i]); + } +} +\endcode + +Setting VmaDefragmentationInfo2::pAllocationsChanged is optional. +This output array tells whether particular allocation in VmaDefragmentationInfo2::pAllocations at the same index +has been modified during defragmentation. +You can pass null, but you then need to query every allocation passed to defragmentation +for new parameters using vmaGetAllocationInfo() if you might need to recreate and rebind a buffer or image associated with it. + +If you use [Custom memory pools](@ref choosing_memory_type_custom_memory_pools), +you can fill VmaDefragmentationInfo2::poolCount and VmaDefragmentationInfo2::pPools +instead of VmaDefragmentationInfo2::allocationCount and VmaDefragmentationInfo2::pAllocations +to defragment all allocations in given pools. +You cannot use VmaDefragmentationInfo2::pAllocationsChanged in that case. +You can also combine both methods. + +\section defragmentation_gpu Defragmenting GPU memory + +It is also possible to defragment allocations created in memory types that are not `HOST_VISIBLE`. +To do that, you need to pass a command buffer that meets requirements as described in +VmaDefragmentationInfo2::commandBuffer. The way it works is: + +- It creates temporary buffers and binds them to entire memory blocks when necessary. +- It issues `vkCmdCopyBuffer()` to passed command buffer. + +Example: + +\code +// Given following variables already initialized: +VkDevice device; +VmaAllocator allocator; +VkCommandBuffer commandBuffer; +std::vector buffers; +std::vector allocations; + + +const uint32_t allocCount = (uint32_t)allocations.size(); +std::vector allocationsChanged(allocCount); + +VkCommandBufferBeginInfo cmdBufBeginInfo = ...; +vkBeginCommandBuffer(commandBuffer, &cmdBufBeginInfo); + +VmaDefragmentationInfo2 defragInfo = {}; +defragInfo.allocationCount = allocCount; +defragInfo.pAllocations = allocations.data(); +defragInfo.pAllocationsChanged = allocationsChanged.data(); +defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE; // Notice it is "GPU" this time. +defragInfo.maxGpuAllocationsToMove = UINT32_MAX; // Notice it is "GPU" this time. +defragInfo.commandBuffer = commandBuffer; + +VmaDefragmentationContext defragCtx; +vmaDefragmentationBegin(allocator, &defragInfo, nullptr, &defragCtx); + +vkEndCommandBuffer(commandBuffer); + +// Submit commandBuffer. +// Wait for a fence that ensures commandBuffer execution finished. + +vmaDefragmentationEnd(allocator, defragCtx); + +for(uint32_t i = 0; i < allocCount; ++i) +{ + if(allocationsChanged[i]) + { + // Destroy buffer that is immutably bound to memory region which is no longer valid. + vkDestroyBuffer(device, buffers[i], nullptr); + + // Create new buffer with same parameters. + VkBufferCreateInfo bufferInfo = ...; + vkCreateBuffer(device, &bufferInfo, nullptr, &buffers[i]); + + // You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning. + + // Bind new buffer to new memory region. Data contained in it is already moved. + VmaAllocationInfo allocInfo; + vmaGetAllocationInfo(allocator, allocations[i], &allocInfo); + vmaBindBufferMemory(allocator, allocations[i], buffers[i]); + } +} +\endcode + +You can combine these two methods by specifying non-zero `maxGpu*` as well as `maxCpu*` parameters. +The library automatically chooses best method to defragment each memory pool. + +You may try not to block your entire program to wait until defragmentation finishes, +but do it in the background, as long as you carefully fullfill requirements described +in function vmaDefragmentationBegin(). + +\section defragmentation_additional_notes Additional notes + +It is only legal to defragment allocations bound to: + +- buffers +- images created with `VK_IMAGE_CREATE_ALIAS_BIT`, `VK_IMAGE_TILING_LINEAR`, and + being currently in `VK_IMAGE_LAYOUT_GENERAL` or `VK_IMAGE_LAYOUT_PREINITIALIZED`. + +Defragmentation of images created with `VK_IMAGE_TILING_OPTIMAL` or in any other +layout may give undefined results. + +If you defragment allocations bound to images, new images to be bound to new +memory region after defragmentation should be created with `VK_IMAGE_LAYOUT_PREINITIALIZED` +and then transitioned to their original layout from before defragmentation if +needed using an image memory barrier. + +While using defragmentation, you may experience validation layer warnings, which you just need to ignore. +See [Validation layer warnings](@ref general_considerations_validation_layer_warnings). + +Please don't expect memory to be fully compacted after defragmentation. +Algorithms inside are based on some heuristics that try to maximize number of Vulkan +memory blocks to make totally empty to release them, as well as to maximize continuous +empty space inside remaining blocks, while minimizing the number and size of allocations that +need to be moved. Some fragmentation may still remain - this is normal. + +\section defragmentation_custom_algorithm Writing custom defragmentation algorithm + +If you want to implement your own, custom defragmentation algorithm, +there is infrastructure prepared for that, +but it is not exposed through the library API - you need to hack its source code. +Here are steps needed to do this: + +-# Main thing you need to do is to define your own class derived from base abstract + class `VmaDefragmentationAlgorithm` and implement your version of its pure virtual methods. + See definition and comments of this class for details. +-# Your code needs to interact with device memory block metadata. + If you need more access to its data than it is provided by its public interface, + declare your new class as a friend class e.g. in class `VmaBlockMetadata_Generic`. +-# If you want to create a flag that would enable your algorithm or pass some additional + flags to configure it, add them to `VmaDefragmentationFlagBits` and use them in + VmaDefragmentationInfo2::flags. +-# Modify function `VmaBlockVectorDefragmentationContext::Begin` to create object + of your new class whenever needed. + + +\page lost_allocations Lost allocations + +If your game oversubscribes video memory, if may work OK in previous-generation +graphics APIs (DirectX 9, 10, 11, OpenGL) because resources are automatically +paged to system RAM. In Vulkan you can't do it because when you run out of +memory, an allocation just fails. If you have more data (e.g. textures) that can +fit into VRAM and you don't need it all at once, you may want to upload them to +GPU on demand and "push out" ones that are not used for a long time to make room +for the new ones, effectively using VRAM (or a cartain memory pool) as a form of +cache. Vulkan Memory Allocator can help you with that by supporting a concept of +"lost allocations". + +To create an allocation that can become lost, include #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT +flag in VmaAllocationCreateInfo::flags. Before using a buffer or image bound to +such allocation in every new frame, you need to query it if it is not lost. +To check it, call vmaTouchAllocation(). +If the allocation is lost, you should not use it or buffer/image bound to it. +You mustn't forget to destroy this allocation and this buffer/image. +vmaGetAllocationInfo() can also be used for checking status of the allocation. +Allocation is lost when returned VmaAllocationInfo::deviceMemory == `VK_NULL_HANDLE`. + +To create an allocation that can make some other allocations lost to make room +for it, use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag. You will +usually use both flags #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT and +#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT at the same time. + +Warning! Current implementation uses quite naive, brute force algorithm, +which can make allocation calls that use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT +flag quite slow. A new, more optimal algorithm and data structure to speed this +up is planned for the future. + +Q: When interleaving creation of new allocations with usage of existing ones, +how do you make sure that an allocation won't become lost while it is used in the +current frame? + +It is ensured because vmaTouchAllocation() / vmaGetAllocationInfo() not only returns allocation +status/parameters and checks whether it is not lost, but when it is not, it also +atomically marks it as used in the current frame, which makes it impossible to +become lost in that frame. It uses lockless algorithm, so it works fast and +doesn't involve locking any internal mutex. + +Q: What if my allocation may still be in use by the GPU when it is rendering a +previous frame while I already submit new frame on the CPU? + +You can make sure that allocations "touched" by vmaTouchAllocation() / vmaGetAllocationInfo() will not +become lost for a number of additional frames back from the current one by +specifying this number as VmaAllocatorCreateInfo::frameInUseCount (for default +memory pool) and VmaPoolCreateInfo::frameInUseCount (for custom pool). + +Q: How do you inform the library when new frame starts? + +You need to call function vmaSetCurrentFrameIndex(). + +Example code: + +\code +struct MyBuffer +{ + VkBuffer m_Buf = nullptr; + VmaAllocation m_Alloc = nullptr; + + // Called when the buffer is really needed in the current frame. + void EnsureBuffer(); +}; + +void MyBuffer::EnsureBuffer() +{ + // Buffer has been created. + if(m_Buf != VK_NULL_HANDLE) + { + // Check if its allocation is not lost + mark it as used in current frame. + if(vmaTouchAllocation(allocator, m_Alloc)) + { + // It is all OK - safe to use m_Buf. + return; + } + } + + // Buffer not yet exists or lost - destroy and recreate it. + + vmaDestroyBuffer(allocator, m_Buf, m_Alloc); + + VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bufCreateInfo.size = 1024; + bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + + VmaAllocationCreateInfo allocCreateInfo = {}; + allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + allocCreateInfo.flags = VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT | + VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT; + + vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &m_Buf, &m_Alloc, nullptr); +} +\endcode + +When using lost allocations, you may see some Vulkan validation layer warnings +about overlapping regions of memory bound to different kinds of buffers and +images. This is still valid as long as you implement proper handling of lost +allocations (like in the example above) and don't use them. + +You can create an allocation that is already in lost state from the beginning using function +vmaCreateLostAllocation(). It may be useful if you need a "dummy" allocation that is not null. + +You can call function vmaMakePoolAllocationsLost() to set all eligible allocations +in a specified custom pool to lost state. +Allocations that have been "touched" in current frame or VmaPoolCreateInfo::frameInUseCount frames back +cannot become lost. + +Q: Can I touch allocation that cannot become lost? + +Yes, although it has no visible effect. +Calls to vmaGetAllocationInfo() and vmaTouchAllocation() update last use frame index +also for allocations that cannot become lost, but the only way to observe it is to dump +internal allocator state using vmaBuildStatsString(). +You can use this feature for debugging purposes to explicitly mark allocations that you use +in current frame and then analyze JSON dump to see for how long each allocation stays unused. + + +\page statistics Statistics + +This library contains functions that return information about its internal state, +especially the amount of memory allocated from Vulkan. +Please keep in mind that these functions need to traverse all internal data structures +to gather these information, so they may be quite time-consuming. +Don't call them too often. + +\section statistics_numeric_statistics Numeric statistics + +You can query for overall statistics of the allocator using function vmaCalculateStats(). +Information are returned using structure #VmaStats. +It contains #VmaStatInfo - number of allocated blocks, number of allocations +(occupied ranges in these blocks), number of unused (free) ranges in these blocks, +number of bytes used and unused (but still allocated from Vulkan) and other information. +They are summed across memory heaps, memory types and total for whole allocator. + +You can query for statistics of a custom pool using function vmaGetPoolStats(). +Information are returned using structure #VmaPoolStats. + +You can query for information about specific allocation using function vmaGetAllocationInfo(). +It fill structure #VmaAllocationInfo. + +\section statistics_json_dump JSON dump + +You can dump internal state of the allocator to a string in JSON format using function vmaBuildStatsString(). +The result is guaranteed to be correct JSON. +It uses ANSI encoding. +Any strings provided by user (see [Allocation names](@ref allocation_names)) +are copied as-is and properly escaped for JSON, so if they use UTF-8, ISO-8859-2 or any other encoding, +this JSON string can be treated as using this encoding. +It must be freed using function vmaFreeStatsString(). + +The format of this JSON string is not part of official documentation of the library, +but it will not change in backward-incompatible way without increasing library major version number +and appropriate mention in changelog. + +The JSON string contains all the data that can be obtained using vmaCalculateStats(). +It can also contain detailed map of allocated memory blocks and their regions - +free and occupied by allocations. +This allows e.g. to visualize the memory or assess fragmentation. + + +\page allocation_annotation Allocation names and user data + +\section allocation_user_data Allocation user data + +You can annotate allocations with your own information, e.g. for debugging purposes. +To do that, fill VmaAllocationCreateInfo::pUserData field when creating +an allocation. It is an opaque `void*` pointer. You can use it e.g. as a pointer, +some handle, index, key, ordinal number or any other value that would associate +the allocation with your custom metadata. + +\code +VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +// Fill bufferInfo... + +MyBufferMetadata* pMetadata = CreateBufferMetadata(); + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocCreateInfo.pUserData = pMetadata; + +VkBuffer buffer; +VmaAllocation allocation; +vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, nullptr); +\endcode + +The pointer may be later retrieved as VmaAllocationInfo::pUserData: + +\code +VmaAllocationInfo allocInfo; +vmaGetAllocationInfo(allocator, allocation, &allocInfo); +MyBufferMetadata* pMetadata = (MyBufferMetadata*)allocInfo.pUserData; +\endcode + +It can also be changed using function vmaSetAllocationUserData(). + +Values of (non-zero) allocations' `pUserData` are printed in JSON report created by +vmaBuildStatsString(), in hexadecimal form. + +\section allocation_names Allocation names + +There is alternative mode available where `pUserData` pointer is used to point to +a null-terminated string, giving a name to the allocation. To use this mode, +set #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT flag in VmaAllocationCreateInfo::flags. +Then `pUserData` passed as VmaAllocationCreateInfo::pUserData or argument to +vmaSetAllocationUserData() must be either null or pointer to a null-terminated string. +The library creates internal copy of the string, so the pointer you pass doesn't need +to be valid for whole lifetime of the allocation. You can free it after the call. + +\code +VkImageCreateInfo imageInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; +// Fill imageInfo... + +std::string imageName = "Texture: "; +imageName += fileName; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT; +allocCreateInfo.pUserData = imageName.c_str(); + +VkImage image; +VmaAllocation allocation; +vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &image, &allocation, nullptr); +\endcode + +The value of `pUserData` pointer of the allocation will be different than the one +you passed when setting allocation's name - pointing to a buffer managed +internally that holds copy of the string. + +\code +VmaAllocationInfo allocInfo; +vmaGetAllocationInfo(allocator, allocation, &allocInfo); +const char* imageName = (const char*)allocInfo.pUserData; +printf("Image name: %s\n", imageName); +\endcode + +That string is also printed in JSON report created by vmaBuildStatsString(). + +\note Passing string name to VMA allocation doesn't automatically set it to the Vulkan buffer or image created with it. +You must do it manually using an extension like VK_EXT_debug_utils, which is independent of this library. + + +\page debugging_memory_usage Debugging incorrect memory usage + +If you suspect a bug with memory usage, like usage of uninitialized memory or +memory being overwritten out of bounds of an allocation, +you can use debug features of this library to verify this. + +\section debugging_memory_usage_initialization Memory initialization + +If you experience a bug with incorrect and nondeterministic data in your program and you suspect uninitialized memory to be used, +you can enable automatic memory initialization to verify this. +To do it, define macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to 1. + +\code +#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1 +#include "vk_mem_alloc.h" +\endcode + +It makes memory of all new allocations initialized to bit pattern `0xDCDCDCDC`. +Before an allocation is destroyed, its memory is filled with bit pattern `0xEFEFEFEF`. +Memory is automatically mapped and unmapped if necessary. + +If you find these values while debugging your program, good chances are that you incorrectly +read Vulkan memory that is allocated but not initialized, or already freed, respectively. + +Memory initialization works only with memory types that are `HOST_VISIBLE`. +It works also with dedicated allocations. +It doesn't work with allocations created with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag, +as they cannot be mapped. + +\section debugging_memory_usage_margins Margins + +By default, allocations are laid out in memory blocks next to each other if possible +(considering required alignment, `bufferImageGranularity`, and `nonCoherentAtomSize`). + +![Allocations without margin](../gfx/Margins_1.png) + +Define macro `VMA_DEBUG_MARGIN` to some non-zero value (e.g. 16) to enforce specified +number of bytes as a margin before and after every allocation. + +\code +#define VMA_DEBUG_MARGIN 16 +#include "vk_mem_alloc.h" +\endcode + +![Allocations with margin](../gfx/Margins_2.png) + +If your bug goes away after enabling margins, it means it may be caused by memory +being overwritten outside of allocation boundaries. It is not 100% certain though. +Change in application behavior may also be caused by different order and distribution +of allocations across memory blocks after margins are applied. + +The margin is applied also before first and after last allocation in a block. +It may occur only once between two adjacent allocations. + +Margins work with all types of memory. + +Margin is applied only to allocations made out of memory blocks and not to dedicated +allocations, which have their own memory block of specific size. +It is thus not applied to allocations made using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag +or those automatically decided to put into dedicated allocations, e.g. due to its +large size or recommended by VK_KHR_dedicated_allocation extension. +Margins are also not active in custom pools created with #VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT flag. + +Margins appear in [JSON dump](@ref statistics_json_dump) as part of free space. + +Note that enabling margins increases memory usage and fragmentation. + +\section debugging_memory_usage_corruption_detection Corruption detection + +You can additionally define macro `VMA_DEBUG_DETECT_CORRUPTION` to 1 to enable validation +of contents of the margins. + +\code +#define VMA_DEBUG_MARGIN 16 +#define VMA_DEBUG_DETECT_CORRUPTION 1 +#include "vk_mem_alloc.h" +\endcode + +When this feature is enabled, number of bytes specified as `VMA_DEBUG_MARGIN` +(it must be multiply of 4) before and after every allocation is filled with a magic number. +This idea is also know as "canary". +Memory is automatically mapped and unmapped if necessary. + +This number is validated automatically when the allocation is destroyed. +If it is not equal to the expected value, `VMA_ASSERT()` is executed. +It clearly means that either CPU or GPU overwritten the memory outside of boundaries of the allocation, +which indicates a serious bug. + +You can also explicitly request checking margins of all allocations in all memory blocks +that belong to specified memory types by using function vmaCheckCorruption(), +or in memory blocks that belong to specified custom pool, by using function +vmaCheckPoolCorruption(). + +Margin validation (corruption detection) works only for memory types that are +`HOST_VISIBLE` and `HOST_COHERENT`. + + +\page record_and_replay Record and replay + +\section record_and_replay_introduction Introduction + +While using the library, sequence of calls to its functions together with their +parameters can be recorded to a file and later replayed using standalone player +application. It can be useful to: + +- Test correctness - check if same sequence of calls will not cause crash or + failures on a target platform. +- Gather statistics - see number of allocations, peak memory usage, number of + calls etc. +- Benchmark performance - see how much time it takes to replay the whole + sequence. + +\section record_and_replay_usage Usage + +Recording functionality is disabled by default. +To enable it, define following macro before every include of this library: + +\code +#define VMA_RECORDING_ENABLED 1 +\endcode + +To record sequence of calls to a file: Fill in +VmaAllocatorCreateInfo::pRecordSettings member while creating #VmaAllocator +object. File is opened and written during whole lifetime of the allocator. + +To replay file: Use VmaReplay - standalone command-line program. +Precompiled binary can be found in "bin" directory. +Its source can be found in "src/VmaReplay" directory. +Its project is generated by Premake. +Command line syntax is printed when the program is launched without parameters. +Basic usage: + + VmaReplay.exe MyRecording.csv + +Documentation of file format can be found in file: "docs/Recording file format.md". +It is a human-readable, text file in CSV format (Comma Separated Values). + +\section record_and_replay_additional_considerations Additional considerations + +- Replaying file that was recorded on a different GPU (with different parameters + like `bufferImageGranularity`, `nonCoherentAtomSize`, and especially different + set of memory heaps and types) may give different performance and memory usage + results, as well as issue some warnings and errors. +- Current implementation of recording in VMA, as well as VmaReplay application, is + coded and tested only on Windows. Inclusion of recording code is driven by + `VMA_RECORDING_ENABLED` macro. Support for other platforms should be easy to + add. Contributions are welcomed. + + +\page opengl_interop OpenGL Interop + +VMA provides some features that help with interoperability with OpenGL. + +\section opengl_interop_exporting_memory Exporting memory + +If you want to attach `VkExportMemoryAllocateInfoKHR` structure to `pNext` chain of memory allocations made by the library: + +It is recommended to create \ref custom_memory_pools for such allocations. +Define and fill in your `VkExportMemoryAllocateInfoKHR` structure and attach it to VmaPoolCreateInfo::pMemoryAllocateNext +while creating the custom pool. +Please note that the structure must remain alive and unchanged for the whole lifetime of the #VmaPool, +not only while creating it, as no copy of the structure is made, +but its original pointer is used for each allocation instead. + +If you want to export all memory allocated by the library from certain memory types, +also dedicated allocations or other allocations made from default pools, +an alternative solution is to fill in VmaAllocatorCreateInfo::pTypeExternalMemoryHandleTypes. +It should point to an array with `VkExternalMemoryHandleTypeFlagsKHR` to be automatically passed by the library +through `VkExportMemoryAllocateInfoKHR` on each allocation made from a specific memory type. +This is currently the only method to use if you need exported dedicated allocations, as they cannot be created out of custom pools. +This will change in future versions of the library though. + +You should not mix these two methods in a way that allows to apply both to the same memory type. +Otherwise, `VkExportMemoryAllocateInfoKHR` structure would be attached twice to the `pNext` chain of `VkMemoryAllocateInfo`. + + +\section opengl_interop_custom_alignment Custom alignment + +Buffers or images exported to a different API like OpenGL may require a different alignment, +higher than the one used by the library automatically, queried from functions like `vkGetBufferMemoryRequirements`. +To impose such alignment: + +It is recommended to create \ref custom_memory_pools for such allocations. +Set VmaPoolCreateInfo::minAllocationAlignment member to the minimum alignment required for each allocation +to be made out of this pool. +The alignment actually used will be the maximum of this member and the alignment returned for the specific buffer or image +from a function like `vkGetBufferMemoryRequirements`, which is called by VMA automatically. + +If you want to create a buffer with a specific minimum alignment out of default pools, +use special function vmaCreateBufferWithAlignment(), which takes additional parameter `minAlignment`. +This is currently the only method to use if you need exported dedicated allocations, as they cannot be created out of custom pools. +This will change in future versions of the library though. + +Note the problem of alignment affects only resources placed inside bigger `VkDeviceMemory` blocks and not dedicated +allocations, as these, by definition, always have alignment = 0 because the resource is bound to the beginning of its dedicated block. +Contrary to Direct3D 12, Vulkan doesn't have a concept of alignment of the entire memory block passed on its allocation. + + +\page usage_patterns Recommended usage patterns + +See also slides from talk: +[Sawicki, Adam. Advanced Graphics Techniques Tutorial: Memory management in Vulkan and DX12. Game Developers Conference, 2018](https://www.gdcvault.com/play/1025458/Advanced-Graphics-Techniques-Tutorial-New) + + +\section usage_patterns_common_mistakes Common mistakes + +Use of CPU_TO_GPU instead of CPU_ONLY memory + +#VMA_MEMORY_USAGE_CPU_TO_GPU is recommended only for resources that will be +mapped and written by the CPU, as well as read directly by the GPU - like some +buffers or textures updated every frame (dynamic). If you create a staging copy +of a resource to be written by CPU and then used as a source of transfer to +another resource placed in the GPU memory, that staging resource should be +created with #VMA_MEMORY_USAGE_CPU_ONLY. Please read the descriptions of these +enums carefully for details. + +Unnecessary use of custom pools + +\ref custom_memory_pools may be useful for special purposes - when you want to +keep certain type of resources separate e.g. to reserve minimum amount of memory +for them, limit maximum amount of memory they can occupy, or make some of them +push out the other through the mechanism of \ref lost_allocations. For most +resources this is not needed and so it is not recommended to create #VmaPool +objects and allocations out of them. Allocating from the default pool is sufficient. + +\section usage_patterns_simple Simple patterns + +\subsection usage_patterns_simple_render_targets Render targets + +When: +Any resources that you frequently write and read on GPU, +e.g. images used as color attachments (aka "render targets"), depth-stencil attachments, +images/buffers used as storage image/buffer (aka "Unordered Access View (UAV)"). + +What to do: +Create them in video memory that is fastest to access from GPU using +#VMA_MEMORY_USAGE_GPU_ONLY. + +Consider using [VK_KHR_dedicated_allocation](@ref vk_khr_dedicated_allocation) extension +and/or manually creating them as dedicated allocations using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, +especially if they are large or if you plan to destroy and recreate them e.g. when +display resolution changes. +Prefer to create such resources first and all other GPU resources (like textures and vertex buffers) later. + +\subsection usage_patterns_simple_immutable_resources Immutable resources + +When: +Any resources that you fill on CPU only once (aka "immutable") or infrequently +and then read frequently on GPU, +e.g. textures, vertex and index buffers, constant buffers that don't change often. + +What to do: +Create them in video memory that is fastest to access from GPU using +#VMA_MEMORY_USAGE_GPU_ONLY. + +To initialize content of such resource, create a CPU-side (aka "staging") copy of it +in system memory - #VMA_MEMORY_USAGE_CPU_ONLY, map it, fill it, +and submit a transfer from it to the GPU resource. +You can keep the staging copy if you need it for another upload transfer in the future. +If you don't, you can destroy it or reuse this buffer for uploading different resource +after the transfer finishes. + +Prefer to create just buffers in system memory rather than images, even for uploading textures. +Use `vkCmdCopyBufferToImage()`. +Dont use images with `VK_IMAGE_TILING_LINEAR`. + +\subsection usage_patterns_dynamic_resources Dynamic resources + +When: +Any resources that change frequently (aka "dynamic"), e.g. every frame or every draw call, +written on CPU, read on GPU. + +What to do: +Create them using #VMA_MEMORY_USAGE_CPU_TO_GPU. +You can map it and write to it directly on CPU, as well as read from it on GPU. + +This is a more complex situation. Different solutions are possible, +and the best one depends on specific GPU type, but you can use this simple approach for the start. +Prefer to write to such resource sequentially (e.g. using `memcpy`). +Don't perform random access or any reads from it on CPU, as it may be very slow. +Also note that textures written directly from the host through a mapped pointer need to be in LINEAR not OPTIMAL layout. + +\subsection usage_patterns_readback Readback + +When: +Resources that contain data written by GPU that you want to read back on CPU, +e.g. results of some computations. + +What to do: +Create them using #VMA_MEMORY_USAGE_GPU_TO_CPU. +You can write to them directly on GPU, as well as map and read them on CPU. + +\section usage_patterns_advanced Advanced patterns + +\subsection usage_patterns_integrated_graphics Detecting integrated graphics + +You can support integrated graphics (like Intel HD Graphics, AMD APU) better +by detecting it in Vulkan. +To do it, call `vkGetPhysicalDeviceProperties()`, inspect +`VkPhysicalDeviceProperties::deviceType` and look for `VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU`. +When you find it, you can assume that memory is unified and all memory types are comparably fast +to access from GPU, regardless of `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`. + +You can then sum up sizes of all available memory heaps and treat them as useful for +your GPU resources, instead of only `DEVICE_LOCAL` ones. +You can also prefer to create your resources in memory types that are `HOST_VISIBLE` to map them +directly instead of submitting explicit transfer (see below). + +\subsection usage_patterns_direct_vs_transfer Direct access versus transfer + +For resources that you frequently write on CPU and read on GPU, many solutions are possible: + +-# Create one copy in video memory using #VMA_MEMORY_USAGE_GPU_ONLY, + second copy in system memory using #VMA_MEMORY_USAGE_CPU_ONLY and submit explicit transfer each time. +-# Create just a single copy using #VMA_MEMORY_USAGE_CPU_TO_GPU, map it and fill it on CPU, + read it directly on GPU. +-# Create just a single copy using #VMA_MEMORY_USAGE_CPU_ONLY, map it and fill it on CPU, + read it directly on GPU. + +Which solution is the most efficient depends on your resource and especially on the GPU. +It is best to measure it and then make the decision. +Some general recommendations: + +- On integrated graphics use (2) or (3) to avoid unnecessary time and memory overhead + related to using a second copy and making transfer. +- For small resources (e.g. constant buffers) use (2). + Discrete AMD cards have special 256 MiB pool of video memory that is directly mappable. + Even if the resource ends up in system memory, its data may be cached on GPU after first + fetch over PCIe bus. +- For larger resources (e.g. textures), decide between (1) and (2). + You may want to differentiate NVIDIA and AMD, e.g. by looking for memory type that is + both `DEVICE_LOCAL` and `HOST_VISIBLE`. When you find it, use (2), otherwise use (1). + +Similarly, for resources that you frequently write on GPU and read on CPU, multiple +solutions are possible: + +-# Create one copy in video memory using #VMA_MEMORY_USAGE_GPU_ONLY, + second copy in system memory using #VMA_MEMORY_USAGE_GPU_TO_CPU and submit explicit tranfer each time. +-# Create just single copy using #VMA_MEMORY_USAGE_GPU_TO_CPU, write to it directly on GPU, + map it and read it on CPU. + +You should take some measurements to decide which option is faster in case of your specific +resource. + +Note that textures accessed directly from the host through a mapped pointer need to be in LINEAR layout, +which may slow down their usage on the device. +Textures accessed only by the device and transfer operations can use OPTIMAL layout. + +If you don't want to specialize your code for specific types of GPUs, you can still make +an simple optimization for cases when your resource ends up in mappable memory to use it +directly in this case instead of creating CPU-side staging copy. +For details see [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable). + + +\page configuration Configuration + +Please check "CONFIGURATION SECTION" in the code to find macros that you can define +before each include of this file or change directly in this file to provide +your own implementation of basic facilities like assert, `min()` and `max()` functions, +mutex, atomic etc. +The library uses its own implementation of containers by default, but you can switch to using +STL containers instead. + +For example, define `VMA_ASSERT(expr)` before including the library to provide +custom implementation of the assertion, compatible with your project. +By default it is defined to standard C `assert(expr)` in `_DEBUG` configuration +and empty otherwise. + +\section config_Vulkan_functions Pointers to Vulkan functions + +There are multiple ways to import pointers to Vulkan functions in the library. +In the simplest case you don't need to do anything. +If the compilation or linking of your program or the initialization of the #VmaAllocator +doesn't work for you, you can try to reconfigure it. + +First, the allocator tries to fetch pointers to Vulkan functions linked statically, +like this: + +\code +m_VulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkAllocateMemory; +\endcode + +If you want to disable this feature, set configuration macro: `#define VMA_STATIC_VULKAN_FUNCTIONS 0`. + +Second, you can provide the pointers yourself by setting member VmaAllocatorCreateInfo::pVulkanFunctions. +You can fetch them e.g. using functions `vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` or +by using a helper library like [volk](https://github.com/zeux/volk). + +Third, VMA tries to fetch remaining pointers that are still null by calling +`vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` on its own. +If you want to disable this feature, set configuration macro: `#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0`. + +Finally, all the function pointers required by the library (considering selected +Vulkan version and enabled extensions) are checked with `VMA_ASSERT` if they are not null. + + +\section custom_memory_allocator Custom host memory allocator + +If you use custom allocator for CPU memory rather than default operator `new` +and `delete` from C++, you can make this library using your allocator as well +by filling optional member VmaAllocatorCreateInfo::pAllocationCallbacks. These +functions will be passed to Vulkan, as well as used by the library itself to +make any CPU-side allocations. + +\section allocation_callbacks Device memory allocation callbacks + +The library makes calls to `vkAllocateMemory()` and `vkFreeMemory()` internally. +You can setup callbacks to be informed about these calls, e.g. for the purpose +of gathering some statistics. To do it, fill optional member +VmaAllocatorCreateInfo::pDeviceMemoryCallbacks. + +\section heap_memory_limit Device heap memory limit + +When device memory of certain heap runs out of free space, new allocations may +fail (returning error code) or they may succeed, silently pushing some existing +memory blocks from GPU VRAM to system RAM (which degrades performance). This +behavior is implementation-dependent - it depends on GPU vendor and graphics +driver. + +On AMD cards it can be controlled while creating Vulkan device object by using +VK_AMD_memory_overallocation_behavior extension, if available. + +Alternatively, if you want to test how your program behaves with limited amount of Vulkan device +memory available without switching your graphics card to one that really has +smaller VRAM, you can use a feature of this library intended for this purpose. +To do it, fill optional member VmaAllocatorCreateInfo::pHeapSizeLimit. + + + +\page vk_khr_dedicated_allocation VK_KHR_dedicated_allocation + +VK_KHR_dedicated_allocation is a Vulkan extension which can be used to improve +performance on some GPUs. It augments Vulkan API with possibility to query +driver whether it prefers particular buffer or image to have its own, dedicated +allocation (separate `VkDeviceMemory` block) for better efficiency - to be able +to do some internal optimizations. + +The extension is supported by this library. It will be used automatically when +enabled. To enable it: + +1 . When creating Vulkan device, check if following 2 device extensions are +supported (call `vkEnumerateDeviceExtensionProperties()`). +If yes, enable them (fill `VkDeviceCreateInfo::ppEnabledExtensionNames`). + +- VK_KHR_get_memory_requirements2 +- VK_KHR_dedicated_allocation + +If you enabled these extensions: + +2 . Use #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag when creating +your #VmaAllocator`to inform the library that you enabled required extensions +and you want the library to use them. + +\code +allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT; + +vmaCreateAllocator(&allocatorInfo, &allocator); +\endcode + +That is all. The extension will be automatically used whenever you create a +buffer using vmaCreateBuffer() or image using vmaCreateImage(). + +When using the extension together with Vulkan Validation Layer, you will receive +warnings like this: + + vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer. + +It is OK, you should just ignore it. It happens because you use function +`vkGetBufferMemoryRequirements2KHR()` instead of standard +`vkGetBufferMemoryRequirements()`, while the validation layer seems to be +unaware of it. + +To learn more about this extension, see: + +- [VK_KHR_dedicated_allocation in Vulkan specification](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap50.html#VK_KHR_dedicated_allocation) +- [VK_KHR_dedicated_allocation unofficial manual](http://asawicki.info/articles/VK_KHR_dedicated_allocation.php5) + + + +\page vk_amd_device_coherent_memory VK_AMD_device_coherent_memory + +VK_AMD_device_coherent_memory is a device extension that enables access to +additional memory types with `VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD` and +`VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD` flag. It is useful mostly for +allocation of buffers intended for writing "breadcrumb markers" in between passes +or draw calls, which in turn are useful for debugging GPU crash/hang/TDR cases. + +When the extension is available but has not been enabled, Vulkan physical device +still exposes those memory types, but their usage is forbidden. VMA automatically +takes care of that - it returns `VK_ERROR_FEATURE_NOT_PRESENT` when an attempt +to allocate memory of such type is made. + +If you want to use this extension in connection with VMA, follow these steps: + +\section vk_amd_device_coherent_memory_initialization Initialization + +1) Call `vkEnumerateDeviceExtensionProperties` for the physical device. +Check if the extension is supported - if returned array of `VkExtensionProperties` contains "VK_AMD_device_coherent_memory". + +2) Call `vkGetPhysicalDeviceFeatures2` for the physical device instead of old `vkGetPhysicalDeviceFeatures`. +Attach additional structure `VkPhysicalDeviceCoherentMemoryFeaturesAMD` to `VkPhysicalDeviceFeatures2::pNext` to be returned. +Check if the device feature is really supported - check if `VkPhysicalDeviceCoherentMemoryFeaturesAMD::deviceCoherentMemory` is true. + +3) While creating device with `vkCreateDevice`, enable this extension - add "VK_AMD_device_coherent_memory" +to the list passed as `VkDeviceCreateInfo::ppEnabledExtensionNames`. + +4) While creating the device, also don't set `VkDeviceCreateInfo::pEnabledFeatures`. +Fill in `VkPhysicalDeviceFeatures2` structure instead and pass it as `VkDeviceCreateInfo::pNext`. +Enable this device feature - attach additional structure `VkPhysicalDeviceCoherentMemoryFeaturesAMD` to +`VkPhysicalDeviceFeatures2::pNext` and set its member `deviceCoherentMemory` to `VK_TRUE`. + +5) While creating #VmaAllocator with vmaCreateAllocator() inform VMA that you +have enabled this extension and feature - add #VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT +to VmaAllocatorCreateInfo::flags. + +\section vk_amd_device_coherent_memory_usage Usage + +After following steps described above, you can create VMA allocations and custom pools +out of the special `DEVICE_COHERENT` and `DEVICE_UNCACHED` memory types on eligible +devices. There are multiple ways to do it, for example: + +- You can request or prefer to allocate out of such memory types by adding + `VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD` to VmaAllocationCreateInfo::requiredFlags + or VmaAllocationCreateInfo::preferredFlags. Those flags can be freely mixed with + other ways of \ref choosing_memory_type, like setting VmaAllocationCreateInfo::usage. +- If you manually found memory type index to use for this purpose, force allocation + from this specific index by setting VmaAllocationCreateInfo::memoryTypeBits `= 1u << index`. + +\section vk_amd_device_coherent_memory_more_information More information + +To learn more about this extension, see [VK_AMD_device_coherent_memory in Vulkan specification](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_AMD_device_coherent_memory.html) + +Example use of this extension can be found in the code of the sample and test suite +accompanying this library. + + +\page enabling_buffer_device_address Enabling buffer device address + +Device extension VK_KHR_buffer_device_address +allow to fetch raw GPU pointer to a buffer and pass it for usage in a shader code. +It is promoted to core Vulkan 1.2. + +If you want to use this feature in connection with VMA, follow these steps: + +\section enabling_buffer_device_address_initialization Initialization + +1) (For Vulkan version < 1.2) Call `vkEnumerateDeviceExtensionProperties` for the physical device. +Check if the extension is supported - if returned array of `VkExtensionProperties` contains +"VK_KHR_buffer_device_address". + +2) Call `vkGetPhysicalDeviceFeatures2` for the physical device instead of old `vkGetPhysicalDeviceFeatures`. +Attach additional structure `VkPhysicalDeviceBufferDeviceAddressFeatures*` to `VkPhysicalDeviceFeatures2::pNext` to be returned. +Check if the device feature is really supported - check if `VkPhysicalDeviceBufferDeviceAddressFeatures::bufferDeviceAddress` is true. + +3) (For Vulkan version < 1.2) While creating device with `vkCreateDevice`, enable this extension - add +"VK_KHR_buffer_device_address" to the list passed as `VkDeviceCreateInfo::ppEnabledExtensionNames`. + +4) While creating the device, also don't set `VkDeviceCreateInfo::pEnabledFeatures`. +Fill in `VkPhysicalDeviceFeatures2` structure instead and pass it as `VkDeviceCreateInfo::pNext`. +Enable this device feature - attach additional structure `VkPhysicalDeviceBufferDeviceAddressFeatures*` to +`VkPhysicalDeviceFeatures2::pNext` and set its member `bufferDeviceAddress` to `VK_TRUE`. + +5) While creating #VmaAllocator with vmaCreateAllocator() inform VMA that you +have enabled this feature - add #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT +to VmaAllocatorCreateInfo::flags. + +\section enabling_buffer_device_address_usage Usage + +After following steps described above, you can create buffers with `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT*` using VMA. +The library automatically adds `VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT*` to +allocated memory blocks wherever it might be needed. + +Please note that the library supports only `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT*`. +The second part of this functionality related to "capture and replay" is not supported, +as it is intended for usage in debugging tools like RenderDoc, not in everyday Vulkan usage. + +\section enabling_buffer_device_address_more_information More information + +To learn more about this extension, see [VK_KHR_buffer_device_address in Vulkan specification](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap46.html#VK_KHR_buffer_device_address) + +Example use of this extension can be found in the code of the sample and test suite +accompanying this library. + +\page general_considerations General considerations + +\section general_considerations_thread_safety Thread safety + +- The library has no global state, so separate #VmaAllocator objects can be used + independently. + There should be no need to create multiple such objects though - one per `VkDevice` is enough. +- By default, all calls to functions that take #VmaAllocator as first parameter + are safe to call from multiple threads simultaneously because they are + synchronized internally when needed. +- When the allocator is created with #VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT + flag, calls to functions that take such #VmaAllocator object must be + synchronized externally. +- Access to a #VmaAllocation object must be externally synchronized. For example, + you must not call vmaGetAllocationInfo() and vmaMapMemory() from different + threads at the same time if you pass the same #VmaAllocation object to these + functions. + +\section general_considerations_validation_layer_warnings Validation layer warnings + +When using this library, you can meet following types of warnings issued by +Vulkan validation layer. They don't necessarily indicate a bug, so you may need +to just ignore them. + +- *vkBindBufferMemory(): Binding memory to buffer 0xeb8e4 but vkGetBufferMemoryRequirements() has not been called on that buffer.* + - It happens when VK_KHR_dedicated_allocation extension is enabled. + `vkGetBufferMemoryRequirements2KHR` function is used instead, while validation layer seems to be unaware of it. +- *Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.* + - It happens when you map a buffer or image, because the library maps entire + `VkDeviceMemory` block, where different types of images and buffers may end + up together, especially on GPUs with unified memory like Intel. +- *Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug.* + - It happens when you use lost allocations, and a new image or buffer is + created in place of an existing object that became lost. + - It may happen also when you use [defragmentation](@ref defragmentation). + +\section general_considerations_allocation_algorithm Allocation algorithm + +The library uses following algorithm for allocation, in order: + +-# Try to find free range of memory in existing blocks. +-# If failed, try to create a new block of `VkDeviceMemory`, with preferred block size. +-# If failed, try to create such block with size/2, size/4, size/8. +-# If failed and #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag was + specified, try to find space in existing blocks, possilby making some other + allocations lost. +-# If failed, try to allocate separate `VkDeviceMemory` for this allocation, + just like when you use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. +-# If failed, choose other memory type that meets the requirements specified in + VmaAllocationCreateInfo and go to point 1. +-# If failed, return `VK_ERROR_OUT_OF_DEVICE_MEMORY`. + +\section general_considerations_features_not_supported Features not supported + +Features deliberately excluded from the scope of this library: + +- **Data transfer.** Uploading (streaming) and downloading data of buffers and images + between CPU and GPU memory and related synchronization is responsibility of the user. + Defining some "texture" object that would automatically stream its data from a + staging copy in CPU memory to GPU memory would rather be a feature of another, + higher-level library implemented on top of VMA. +- **Recreation of buffers and images.** Although the library has functions for + buffer and image creation (vmaCreateBuffer(), vmaCreateImage()), you need to + recreate these objects yourself after defragmentation. That is because the big + structures `VkBufferCreateInfo`, `VkImageCreateInfo` are not stored in + #VmaAllocation object. +- **Handling CPU memory allocation failures.** When dynamically creating small C++ + objects in CPU memory (not Vulkan memory), allocation failures are not checked + and handled gracefully, because that would complicate code significantly and + is usually not needed in desktop PC applications anyway. + Success of an allocation is just checked with an assert. +- **Code free of any compiler warnings.** Maintaining the library to compile and + work correctly on so many different platforms is hard enough. Being free of + any warnings, on any version of any compiler, is simply not feasible. + There are many preprocessor macros that make some variables unused, function parameters unreferenced, + or conditional expressions constant in some configurations. + The code of this library should not be bigger or more complicated just to silence these warnings. + It is recommended to disable such warnings instead. +- This is a C++ library with C interface. **Bindings or ports to any other programming languages** are welcome as external projects but + are not going to be included into this repository. +*/ diff --git a/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.natvis b/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.natvis new file mode 100644 index 000000000..85c75335f --- /dev/null +++ b/source/common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.natvis @@ -0,0 +1,40 @@ + + + + {{ Count={m_Count} }} + + m_Count + + m_Count + m_pFront + pNext + Value + + + + + + {{ Count={m_RawList.m_Count} }} + + m_RawList.m_Count + + m_RawList.m_Count + m_RawList.m_pFront + pNext + Value + + + + + + {{ Count={m_Count} }} + + m_Count + m_Capacity + + m_Count + m_pArray + + + + \ No newline at end of file diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vk_icd.h b/source/common/rendering/vulkan/thirdparty/vulkan/vk_icd.h index a2d960a63..ae006d06d 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vk_icd.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vk_icd.h @@ -41,17 +41,45 @@ // that if the loader is older, it should automatically fail a // call for any API version > 1.0. Otherwise, the loader will // manually determine if it can support the expected version. -#define CURRENT_LOADER_ICD_INTERFACE_VERSION 5 +// Version 6 - Add support for vk_icdEnumerateAdapterPhysicalDevices. +#define CURRENT_LOADER_ICD_INTERFACE_VERSION 6 #define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0 #define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4 -typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); +// Old typedefs that don't follow a proper naming convention but are preserved for compatibility +typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); // This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this // file directly, it won't be found. #ifndef PFN_GetPhysicalDeviceProcAddr typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName); #endif +// Typedefs for loader/ICD interface +typedef VkResult (VKAPI_PTR *PFN_vk_icdNegotiateLoaderICDInterfaceVersion)(uint32_t* pVersion); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetInstanceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); +#if defined(VK_USE_PLATFORM_WIN32_KHR) +typedef VkResult (VKAPI_PTR *PFN_vk_icdEnumerateAdapterPhysicalDevices)(VkInstance instance, LUID adapterLUID, + uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +#endif + +// Prototypes for loader/ICD interface +#if !defined(VK_NO_PROTOTYPES) +#ifdef __cplusplus +extern "C" { +#endif + VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pVersion); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance isntance, const char* pName); +#if defined(VK_USE_PLATFORM_WIN32_KHR) + VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, + uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +#endif +#ifdef __cplusplus +} +#endif +#endif + /* * The ICD must reserve space for a pointer for the loader's dispatch * table, at the start of . @@ -89,7 +117,12 @@ typedef enum { VK_ICD_WSI_PLATFORM_MACOS, VK_ICD_WSI_PLATFORM_IOS, VK_ICD_WSI_PLATFORM_DISPLAY, - VK_ICD_WSI_PLATFORM_HEADLESS + VK_ICD_WSI_PLATFORM_HEADLESS, + VK_ICD_WSI_PLATFORM_METAL, + VK_ICD_WSI_PLATFORM_DIRECTFB, + VK_ICD_WSI_PLATFORM_VI, + VK_ICD_WSI_PLATFORM_GGP, + VK_ICD_WSI_PLATFORM_SCREEN, } VkIcdWsiPlatform; typedef struct { @@ -136,6 +169,14 @@ typedef struct { } VkIcdSurfaceXlib; #endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT +typedef struct { + VkIcdSurfaceBase base; + IDirectFB *dfb; + IDirectFBSurface *surface; +} VkIcdSurfaceDirectFB; +#endif // VK_USE_PLATFORM_DIRECTFB_EXT + #ifdef VK_USE_PLATFORM_ANDROID_KHR typedef struct { VkIcdSurfaceBase base; @@ -157,6 +198,13 @@ typedef struct { } VkIcdSurfaceIOS; #endif // VK_USE_PLATFORM_IOS_MVK +#ifdef VK_USE_PLATFORM_GGP +typedef struct { + VkIcdSurfaceBase base; + GgpStreamDescriptor streamDescriptor; +} VkIcdSurfaceGgp; +#endif // VK_USE_PLATFORM_GGP + typedef struct { VkIcdSurfaceBase base; VkDisplayModeKHR displayMode; @@ -172,4 +220,26 @@ typedef struct { VkIcdSurfaceBase base; } VkIcdSurfaceHeadless; +#ifdef VK_USE_PLATFORM_METAL_EXT +typedef struct { + VkIcdSurfaceBase base; + const CAMetalLayer *pLayer; +} VkIcdSurfaceMetal; +#endif // VK_USE_PLATFORM_METAL_EXT + +#ifdef VK_USE_PLATFORM_VI_NN +typedef struct { + VkIcdSurfaceBase base; + void *window; +} VkIcdSurfaceVi; +#endif // VK_USE_PLATFORM_VI_NN + +#ifdef VK_USE_PLATFORM_SCREEN_QNX +typedef struct { + VkIcdSurfaceBase base; + struct _screen_context *context; + struct _screen_window *window; +} VkIcdSurfaceScreen; +#endif // VK_USE_PLATFORM_SCREEN_QNX + #endif // VKICD_H diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vk_layer.h b/source/common/rendering/vulkan/thirdparty/vulkan/vk_layer.h index fa7652008..0651870c7 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vk_layer.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vk_layer.h @@ -83,7 +83,8 @@ typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device); typedef enum VkLayerFunction_ { VK_LAYER_LINK_INFO = 0, VK_LOADER_DATA_CALLBACK = 1, - VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2 + VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2, + VK_LOADER_FEATURES = 3, } VkLayerFunction; typedef struct VkLayerInstanceLink_ { @@ -111,6 +112,12 @@ typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device, typedef VkResult (VKAPI_PTR *PFN_vkLayerCreateDevice)(VkInstance instance, VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA); typedef void (VKAPI_PTR *PFN_vkLayerDestroyDevice)(VkDevice physicalDevice, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction); + +typedef enum VkLoaderFeastureFlagBits { + VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING = 0x00000001, +} VkLoaderFlagBits; +typedef VkFlags VkLoaderFeatureFlags; + typedef struct { VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO const void *pNext; @@ -119,9 +126,10 @@ typedef struct { VkLayerInstanceLink *pLayerInfo; PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData; struct { - PFN_vkLayerCreateDevice pfnLayerCreateDevice; - PFN_vkLayerDestroyDevice pfnLayerDestroyDevice; - } layerDevice; + PFN_vkLayerCreateDevice pfnLayerCreateDevice; + PFN_vkLayerDestroyDevice pfnLayerDestroyDevice; + } layerDevice; + VkLoaderFeatureFlags loaderFeatures; } u; } VkLayerInstanceCreateInfo; diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vk_layer_dispatch_table.h b/source/common/rendering/vulkan/thirdparty/vulkan/vk_layer_dispatch_table.h deleted file mode 100644 index 63d06b6c9..000000000 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vk_layer_dispatch_table.h +++ /dev/null @@ -1,525 +0,0 @@ -// *** THIS FILE IS GENERATED - DO NOT EDIT *** -// See loader_extension_generator.py for modifications - -/* - * Copyright (c) 2015-2017 The Khronos Group Inc. - * Copyright (c) 2015-2017 Valve Corporation - * Copyright (c) 2015-2017 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Mark Lobodzinski - * Author: Mark Young - */ - -#pragma once - -typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); - -// Instance function pointer dispatch table -typedef struct VkLayerInstanceDispatchTable_ { - // Manually add in GetPhysicalDeviceProcAddr entry - PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr; - - // ---- Core 1_0 commands - PFN_vkCreateInstance CreateInstance; - PFN_vkDestroyInstance DestroyInstance; - PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; - PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures; - PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties; - PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties; - PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties; - PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties; - PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties; - PFN_vkGetInstanceProcAddr GetInstanceProcAddr; - PFN_vkCreateDevice CreateDevice; - PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; - PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; - PFN_vkEnumerateInstanceLayerProperties EnumerateInstanceLayerProperties; - PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties; - - // ---- Core 1_1 commands - PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion; - PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups; - PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2; - PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2; - PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2; - PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysicalDeviceImageFormatProperties2; - PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2; - PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysicalDeviceSparseImageFormatProperties2; - PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties; - PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties; - PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties; - - // ---- VK_KHR_surface extension commands - PFN_vkDestroySurfaceKHR DestroySurfaceKHR; - PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR; - - // ---- VK_KHR_swapchain extension commands - PFN_vkGetPhysicalDevicePresentRectanglesKHR GetPhysicalDevicePresentRectanglesKHR; - - // ---- VK_KHR_display extension commands - PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR; - PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR; - PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR; - PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR; - PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR; - PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR; - PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR; - - // ---- VK_KHR_xlib_surface extension commands -#ifdef VK_USE_PLATFORM_XLIB_KHR - PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR; -#endif // VK_USE_PLATFORM_XLIB_KHR -#ifdef VK_USE_PLATFORM_XLIB_KHR - PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR GetPhysicalDeviceXlibPresentationSupportKHR; -#endif // VK_USE_PLATFORM_XLIB_KHR - - // ---- VK_KHR_xcb_surface extension commands -#ifdef VK_USE_PLATFORM_XCB_KHR - PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR; -#endif // VK_USE_PLATFORM_XCB_KHR -#ifdef VK_USE_PLATFORM_XCB_KHR - PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR GetPhysicalDeviceXcbPresentationSupportKHR; -#endif // VK_USE_PLATFORM_XCB_KHR - - // ---- VK_KHR_wayland_surface extension commands -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR; -#endif // VK_USE_PLATFORM_WAYLAND_KHR -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR GetPhysicalDeviceWaylandPresentationSupportKHR; -#endif // VK_USE_PLATFORM_WAYLAND_KHR - - // ---- VK_KHR_mir_surface extension commands -#ifdef VK_USE_PLATFORM_MIR_KHR - PFN_vkCreateMirSurfaceKHR CreateMirSurfaceKHR; -#endif // VK_USE_PLATFORM_MIR_KHR -#ifdef VK_USE_PLATFORM_MIR_KHR - PFN_vkGetPhysicalDeviceMirPresentationSupportKHR GetPhysicalDeviceMirPresentationSupportKHR; -#endif // VK_USE_PLATFORM_MIR_KHR - - // ---- VK_KHR_android_surface extension commands -#ifdef VK_USE_PLATFORM_ANDROID_KHR - PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR; -#endif // VK_USE_PLATFORM_ANDROID_KHR - - // ---- VK_KHR_win32_surface extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR GetPhysicalDeviceWin32PresentationSupportKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_get_physical_device_properties2 extension commands - PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR; - PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR; - PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysicalDeviceFormatProperties2KHR; - PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysicalDeviceImageFormatProperties2KHR; - PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysicalDeviceQueueFamilyProperties2KHR; - PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysicalDeviceSparseImageFormatProperties2KHR; - - // ---- VK_KHR_device_group_creation extension commands - PFN_vkEnumeratePhysicalDeviceGroupsKHR EnumeratePhysicalDeviceGroupsKHR; - - // ---- VK_KHR_external_memory_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR; - - // ---- VK_KHR_external_semaphore_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR; - - // ---- VK_KHR_external_fence_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR; - - // ---- VK_KHR_get_surface_capabilities2 extension commands - PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR; - PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR; - - // ---- VK_KHR_get_display_properties2 extension commands - PFN_vkGetPhysicalDeviceDisplayProperties2KHR GetPhysicalDeviceDisplayProperties2KHR; - PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR GetPhysicalDeviceDisplayPlaneProperties2KHR; - PFN_vkGetDisplayModeProperties2KHR GetDisplayModeProperties2KHR; - PFN_vkGetDisplayPlaneCapabilities2KHR GetDisplayPlaneCapabilities2KHR; - - // ---- VK_EXT_debug_report extension commands - PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; - PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; - PFN_vkDebugReportMessageEXT DebugReportMessageEXT; - - // ---- VK_NV_external_memory_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV; - - // ---- VK_NN_vi_surface extension commands -#ifdef VK_USE_PLATFORM_VI_NN - PFN_vkCreateViSurfaceNN CreateViSurfaceNN; -#endif // VK_USE_PLATFORM_VI_NN - - // ---- VK_NVX_device_generated_commands extension commands - PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX GetPhysicalDeviceGeneratedCommandsPropertiesNVX; - - // ---- VK_EXT_direct_mode_display extension commands - PFN_vkReleaseDisplayEXT ReleaseDisplayEXT; - - // ---- VK_EXT_acquire_xlib_display extension commands -#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT - PFN_vkAcquireXlibDisplayEXT AcquireXlibDisplayEXT; -#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT -#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT - PFN_vkGetRandROutputDisplayEXT GetRandROutputDisplayEXT; -#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT - - // ---- VK_EXT_display_surface_counter extension commands - PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT GetPhysicalDeviceSurfaceCapabilities2EXT; - - // ---- VK_MVK_ios_surface extension commands -#ifdef VK_USE_PLATFORM_IOS_MVK - PFN_vkCreateIOSSurfaceMVK CreateIOSSurfaceMVK; -#endif // VK_USE_PLATFORM_IOS_MVK - - // ---- VK_MVK_macos_surface extension commands -#ifdef VK_USE_PLATFORM_MACOS_MVK - PFN_vkCreateMacOSSurfaceMVK CreateMacOSSurfaceMVK; -#endif // VK_USE_PLATFORM_MACOS_MVK - - // ---- VK_EXT_debug_utils extension commands - PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT; - PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT; - PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT; - - // ---- VK_EXT_sample_locations extension commands - PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT; -} VkLayerInstanceDispatchTable; - -// Device function pointer dispatch table -typedef struct VkLayerDispatchTable_ { - - // ---- Core 1_0 commands - PFN_vkGetDeviceProcAddr GetDeviceProcAddr; - PFN_vkDestroyDevice DestroyDevice; - PFN_vkGetDeviceQueue GetDeviceQueue; - PFN_vkQueueSubmit QueueSubmit; - PFN_vkQueueWaitIdle QueueWaitIdle; - PFN_vkDeviceWaitIdle DeviceWaitIdle; - PFN_vkAllocateMemory AllocateMemory; - PFN_vkFreeMemory FreeMemory; - PFN_vkMapMemory MapMemory; - PFN_vkUnmapMemory UnmapMemory; - PFN_vkFlushMappedMemoryRanges FlushMappedMemoryRanges; - PFN_vkInvalidateMappedMemoryRanges InvalidateMappedMemoryRanges; - PFN_vkGetDeviceMemoryCommitment GetDeviceMemoryCommitment; - PFN_vkBindBufferMemory BindBufferMemory; - PFN_vkBindImageMemory BindImageMemory; - PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements; - PFN_vkGetImageMemoryRequirements GetImageMemoryRequirements; - PFN_vkGetImageSparseMemoryRequirements GetImageSparseMemoryRequirements; - PFN_vkQueueBindSparse QueueBindSparse; - PFN_vkCreateFence CreateFence; - PFN_vkDestroyFence DestroyFence; - PFN_vkResetFences ResetFences; - PFN_vkGetFenceStatus GetFenceStatus; - PFN_vkWaitForFences WaitForFences; - PFN_vkCreateSemaphore CreateSemaphore; - PFN_vkDestroySemaphore DestroySemaphore; - PFN_vkCreateEvent CreateEvent; - PFN_vkDestroyEvent DestroyEvent; - PFN_vkGetEventStatus GetEventStatus; - PFN_vkSetEvent SetEvent; - PFN_vkResetEvent ResetEvent; - PFN_vkCreateQueryPool CreateQueryPool; - PFN_vkDestroyQueryPool DestroyQueryPool; - PFN_vkGetQueryPoolResults GetQueryPoolResults; - PFN_vkCreateBuffer CreateBuffer; - PFN_vkDestroyBuffer DestroyBuffer; - PFN_vkCreateBufferView CreateBufferView; - PFN_vkDestroyBufferView DestroyBufferView; - PFN_vkCreateImage CreateImage; - PFN_vkDestroyImage DestroyImage; - PFN_vkGetImageSubresourceLayout GetImageSubresourceLayout; - PFN_vkCreateImageView CreateImageView; - PFN_vkDestroyImageView DestroyImageView; - PFN_vkCreateShaderModule CreateShaderModule; - PFN_vkDestroyShaderModule DestroyShaderModule; - PFN_vkCreatePipelineCache CreatePipelineCache; - PFN_vkDestroyPipelineCache DestroyPipelineCache; - PFN_vkGetPipelineCacheData GetPipelineCacheData; - PFN_vkMergePipelineCaches MergePipelineCaches; - PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines; - PFN_vkCreateComputePipelines CreateComputePipelines; - PFN_vkDestroyPipeline DestroyPipeline; - PFN_vkCreatePipelineLayout CreatePipelineLayout; - PFN_vkDestroyPipelineLayout DestroyPipelineLayout; - PFN_vkCreateSampler CreateSampler; - PFN_vkDestroySampler DestroySampler; - PFN_vkCreateDescriptorSetLayout CreateDescriptorSetLayout; - PFN_vkDestroyDescriptorSetLayout DestroyDescriptorSetLayout; - PFN_vkCreateDescriptorPool CreateDescriptorPool; - PFN_vkDestroyDescriptorPool DestroyDescriptorPool; - PFN_vkResetDescriptorPool ResetDescriptorPool; - PFN_vkAllocateDescriptorSets AllocateDescriptorSets; - PFN_vkFreeDescriptorSets FreeDescriptorSets; - PFN_vkUpdateDescriptorSets UpdateDescriptorSets; - PFN_vkCreateFramebuffer CreateFramebuffer; - PFN_vkDestroyFramebuffer DestroyFramebuffer; - PFN_vkCreateRenderPass CreateRenderPass; - PFN_vkDestroyRenderPass DestroyRenderPass; - PFN_vkGetRenderAreaGranularity GetRenderAreaGranularity; - PFN_vkCreateCommandPool CreateCommandPool; - PFN_vkDestroyCommandPool DestroyCommandPool; - PFN_vkResetCommandPool ResetCommandPool; - PFN_vkAllocateCommandBuffers AllocateCommandBuffers; - PFN_vkFreeCommandBuffers FreeCommandBuffers; - PFN_vkBeginCommandBuffer BeginCommandBuffer; - PFN_vkEndCommandBuffer EndCommandBuffer; - PFN_vkResetCommandBuffer ResetCommandBuffer; - PFN_vkCmdBindPipeline CmdBindPipeline; - PFN_vkCmdSetViewport CmdSetViewport; - PFN_vkCmdSetScissor CmdSetScissor; - PFN_vkCmdSetLineWidth CmdSetLineWidth; - PFN_vkCmdSetDepthBias CmdSetDepthBias; - PFN_vkCmdSetBlendConstants CmdSetBlendConstants; - PFN_vkCmdSetDepthBounds CmdSetDepthBounds; - PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask; - PFN_vkCmdSetStencilWriteMask CmdSetStencilWriteMask; - PFN_vkCmdSetStencilReference CmdSetStencilReference; - PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets; - PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer; - PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers; - PFN_vkCmdDraw CmdDraw; - PFN_vkCmdDrawIndexed CmdDrawIndexed; - PFN_vkCmdDrawIndirect CmdDrawIndirect; - PFN_vkCmdDrawIndexedIndirect CmdDrawIndexedIndirect; - PFN_vkCmdDispatch CmdDispatch; - PFN_vkCmdDispatchIndirect CmdDispatchIndirect; - PFN_vkCmdCopyBuffer CmdCopyBuffer; - PFN_vkCmdCopyImage CmdCopyImage; - PFN_vkCmdBlitImage CmdBlitImage; - PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage; - PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer; - PFN_vkCmdUpdateBuffer CmdUpdateBuffer; - PFN_vkCmdFillBuffer CmdFillBuffer; - PFN_vkCmdClearColorImage CmdClearColorImage; - PFN_vkCmdClearDepthStencilImage CmdClearDepthStencilImage; - PFN_vkCmdClearAttachments CmdClearAttachments; - PFN_vkCmdResolveImage CmdResolveImage; - PFN_vkCmdSetEvent CmdSetEvent; - PFN_vkCmdResetEvent CmdResetEvent; - PFN_vkCmdWaitEvents CmdWaitEvents; - PFN_vkCmdPipelineBarrier CmdPipelineBarrier; - PFN_vkCmdBeginQuery CmdBeginQuery; - PFN_vkCmdEndQuery CmdEndQuery; - PFN_vkCmdResetQueryPool CmdResetQueryPool; - PFN_vkCmdWriteTimestamp CmdWriteTimestamp; - PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults; - PFN_vkCmdPushConstants CmdPushConstants; - PFN_vkCmdBeginRenderPass CmdBeginRenderPass; - PFN_vkCmdNextSubpass CmdNextSubpass; - PFN_vkCmdEndRenderPass CmdEndRenderPass; - PFN_vkCmdExecuteCommands CmdExecuteCommands; - - // ---- Core 1_1 commands - PFN_vkBindBufferMemory2 BindBufferMemory2; - PFN_vkBindImageMemory2 BindImageMemory2; - PFN_vkGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeatures; - PFN_vkCmdSetDeviceMask CmdSetDeviceMask; - PFN_vkCmdDispatchBase CmdDispatchBase; - PFN_vkGetImageMemoryRequirements2 GetImageMemoryRequirements2; - PFN_vkGetBufferMemoryRequirements2 GetBufferMemoryRequirements2; - PFN_vkGetImageSparseMemoryRequirements2 GetImageSparseMemoryRequirements2; - PFN_vkTrimCommandPool TrimCommandPool; - PFN_vkGetDeviceQueue2 GetDeviceQueue2; - PFN_vkCreateSamplerYcbcrConversion CreateSamplerYcbcrConversion; - PFN_vkDestroySamplerYcbcrConversion DestroySamplerYcbcrConversion; - PFN_vkCreateDescriptorUpdateTemplate CreateDescriptorUpdateTemplate; - PFN_vkDestroyDescriptorUpdateTemplate DestroyDescriptorUpdateTemplate; - PFN_vkUpdateDescriptorSetWithTemplate UpdateDescriptorSetWithTemplate; - PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport; - - // ---- VK_KHR_swapchain extension commands - PFN_vkCreateSwapchainKHR CreateSwapchainKHR; - PFN_vkDestroySwapchainKHR DestroySwapchainKHR; - PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR; - PFN_vkAcquireNextImageKHR AcquireNextImageKHR; - PFN_vkQueuePresentKHR QueuePresentKHR; - PFN_vkGetDeviceGroupPresentCapabilitiesKHR GetDeviceGroupPresentCapabilitiesKHR; - PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR; - PFN_vkAcquireNextImage2KHR AcquireNextImage2KHR; - - // ---- VK_KHR_display_swapchain extension commands - PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR; - - // ---- VK_KHR_device_group extension commands - PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR GetDeviceGroupPeerMemoryFeaturesKHR; - PFN_vkCmdSetDeviceMaskKHR CmdSetDeviceMaskKHR; - PFN_vkCmdDispatchBaseKHR CmdDispatchBaseKHR; - - // ---- VK_KHR_maintenance1 extension commands - PFN_vkTrimCommandPoolKHR TrimCommandPoolKHR; - - // ---- VK_KHR_external_memory_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetMemoryWin32HandleKHR GetMemoryWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetMemoryWin32HandlePropertiesKHR GetMemoryWin32HandlePropertiesKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_external_memory_fd extension commands - PFN_vkGetMemoryFdKHR GetMemoryFdKHR; - PFN_vkGetMemoryFdPropertiesKHR GetMemoryFdPropertiesKHR; - - // ---- VK_KHR_external_semaphore_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkImportSemaphoreWin32HandleKHR ImportSemaphoreWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetSemaphoreWin32HandleKHR GetSemaphoreWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_external_semaphore_fd extension commands - PFN_vkImportSemaphoreFdKHR ImportSemaphoreFdKHR; - PFN_vkGetSemaphoreFdKHR GetSemaphoreFdKHR; - - // ---- VK_KHR_push_descriptor extension commands - PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSetKHR; - PFN_vkCmdPushDescriptorSetWithTemplateKHR CmdPushDescriptorSetWithTemplateKHR; - - // ---- VK_KHR_descriptor_update_template extension commands - PFN_vkCreateDescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplateKHR; - PFN_vkDestroyDescriptorUpdateTemplateKHR DestroyDescriptorUpdateTemplateKHR; - PFN_vkUpdateDescriptorSetWithTemplateKHR UpdateDescriptorSetWithTemplateKHR; - - // ---- VK_KHR_shared_presentable_image extension commands - PFN_vkGetSwapchainStatusKHR GetSwapchainStatusKHR; - - // ---- VK_KHR_external_fence_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkImportFenceWin32HandleKHR ImportFenceWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetFenceWin32HandleKHR GetFenceWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_external_fence_fd extension commands - PFN_vkImportFenceFdKHR ImportFenceFdKHR; - PFN_vkGetFenceFdKHR GetFenceFdKHR; - - // ---- VK_KHR_get_memory_requirements2 extension commands - PFN_vkGetImageMemoryRequirements2KHR GetImageMemoryRequirements2KHR; - PFN_vkGetBufferMemoryRequirements2KHR GetBufferMemoryRequirements2KHR; - PFN_vkGetImageSparseMemoryRequirements2KHR GetImageSparseMemoryRequirements2KHR; - - // ---- VK_KHR_sampler_ycbcr_conversion extension commands - PFN_vkCreateSamplerYcbcrConversionKHR CreateSamplerYcbcrConversionKHR; - PFN_vkDestroySamplerYcbcrConversionKHR DestroySamplerYcbcrConversionKHR; - - // ---- VK_KHR_bind_memory2 extension commands - PFN_vkBindBufferMemory2KHR BindBufferMemory2KHR; - PFN_vkBindImageMemory2KHR BindImageMemory2KHR; - - // ---- VK_KHR_maintenance3 extension commands - PFN_vkGetDescriptorSetLayoutSupportKHR GetDescriptorSetLayoutSupportKHR; - - // ---- VK_KHR_draw_indirect_count extension commands - PFN_vkCmdDrawIndirectCountKHR CmdDrawIndirectCountKHR; - PFN_vkCmdDrawIndexedIndirectCountKHR CmdDrawIndexedIndirectCountKHR; - - // ---- VK_EXT_debug_marker extension commands - PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; - PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT; - PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT; - PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT; - PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT; - - // ---- VK_AMD_draw_indirect_count extension commands - PFN_vkCmdDrawIndirectCountAMD CmdDrawIndirectCountAMD; - PFN_vkCmdDrawIndexedIndirectCountAMD CmdDrawIndexedIndirectCountAMD; - - // ---- VK_AMD_shader_info extension commands - PFN_vkGetShaderInfoAMD GetShaderInfoAMD; - - // ---- VK_NV_external_memory_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetMemoryWin32HandleNV GetMemoryWin32HandleNV; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_NVX_device_generated_commands extension commands - PFN_vkCmdProcessCommandsNVX CmdProcessCommandsNVX; - PFN_vkCmdReserveSpaceForCommandsNVX CmdReserveSpaceForCommandsNVX; - PFN_vkCreateIndirectCommandsLayoutNVX CreateIndirectCommandsLayoutNVX; - PFN_vkDestroyIndirectCommandsLayoutNVX DestroyIndirectCommandsLayoutNVX; - PFN_vkCreateObjectTableNVX CreateObjectTableNVX; - PFN_vkDestroyObjectTableNVX DestroyObjectTableNVX; - PFN_vkRegisterObjectsNVX RegisterObjectsNVX; - PFN_vkUnregisterObjectsNVX UnregisterObjectsNVX; - - // ---- VK_NV_clip_space_w_scaling extension commands - PFN_vkCmdSetViewportWScalingNV CmdSetViewportWScalingNV; - - // ---- VK_EXT_display_control extension commands - PFN_vkDisplayPowerControlEXT DisplayPowerControlEXT; - PFN_vkRegisterDeviceEventEXT RegisterDeviceEventEXT; - PFN_vkRegisterDisplayEventEXT RegisterDisplayEventEXT; - PFN_vkGetSwapchainCounterEXT GetSwapchainCounterEXT; - - // ---- VK_GOOGLE_display_timing extension commands - PFN_vkGetRefreshCycleDurationGOOGLE GetRefreshCycleDurationGOOGLE; - PFN_vkGetPastPresentationTimingGOOGLE GetPastPresentationTimingGOOGLE; - - // ---- VK_EXT_discard_rectangles extension commands - PFN_vkCmdSetDiscardRectangleEXT CmdSetDiscardRectangleEXT; - - // ---- VK_EXT_hdr_metadata extension commands - PFN_vkSetHdrMetadataEXT SetHdrMetadataEXT; - - // ---- VK_EXT_debug_utils extension commands - PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT; - PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT; - PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT; - PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT; - PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT; - PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT; - PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT; - PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT; - - // ---- VK_ANDROID_external_memory_android_hardware_buffer extension commands -#ifdef VK_USE_PLATFORM_ANDROID_KHR - PFN_vkGetAndroidHardwareBufferPropertiesANDROID GetAndroidHardwareBufferPropertiesANDROID; -#endif // VK_USE_PLATFORM_ANDROID_KHR -#ifdef VK_USE_PLATFORM_ANDROID_KHR - PFN_vkGetMemoryAndroidHardwareBufferANDROID GetMemoryAndroidHardwareBufferANDROID; -#endif // VK_USE_PLATFORM_ANDROID_KHR - - // ---- VK_EXT_sample_locations extension commands - PFN_vkCmdSetSampleLocationsEXT CmdSetSampleLocationsEXT; - - // ---- VK_EXT_validation_cache extension commands - PFN_vkCreateValidationCacheEXT CreateValidationCacheEXT; - PFN_vkDestroyValidationCacheEXT DestroyValidationCacheEXT; - PFN_vkMergeValidationCachesEXT MergeValidationCachesEXT; - PFN_vkGetValidationCacheDataEXT GetValidationCacheDataEXT; - - // ---- VK_EXT_external_memory_host extension commands - PFN_vkGetMemoryHostPointerPropertiesEXT GetMemoryHostPointerPropertiesEXT; - - // ---- VK_AMD_buffer_marker extension commands - PFN_vkCmdWriteBufferMarkerAMD CmdWriteBufferMarkerAMD; -} VkLayerDispatchTable; - - diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vk_platform.h b/source/common/rendering/vulkan/thirdparty/vulkan/vk_platform.h index 728929924..18b913abc 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vk_platform.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vk_platform.h @@ -2,19 +2,9 @@ // File: vk_platform.h // /* -** Copyright (c) 2014-2017 The Khronos Group Inc. +** Copyright 2014-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ @@ -68,7 +58,9 @@ extern "C" #define VKAPI_PTR #endif -#include +#if !defined(VK_NO_STDDEF_H) + #include +#endif // !defined(VK_NO_STDDEF_H) #if !defined(VK_NO_STDINT_H) #if defined(_MSC_VER) && (_MSC_VER < 1600) diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan.h index 5f853f9fc..3f7cdba58 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan.h @@ -2,19 +2,9 @@ #define VULKAN_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ #include "vk_platform.h" @@ -71,6 +61,12 @@ #endif +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT +#include +#include "vulkan_directfb.h" +#endif + + #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT #include #include @@ -83,4 +79,14 @@ #include "vulkan_ggp.h" #endif + +#ifdef VK_USE_PLATFORM_SCREEN_QNX +#include +#include "vulkan_screen.h" +#endif + +#ifdef VK_ENABLE_BETA_EXTENSIONS +#include "vulkan_beta.h" +#endif + #endif // VULKAN_H_ diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_android.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_android.h index 186180241..2160e3e7c 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_android.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_android.h @@ -1,24 +1,10 @@ #ifndef VULKAN_ANDROID_H_ #define VULKAN_ANDROID_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_KHR_android_surface 1 struct ANativeWindow; diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_beta.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_beta.h new file mode 100644 index 000000000..e2337adfd --- /dev/null +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_beta.h @@ -0,0 +1,704 @@ +#ifndef VULKAN_BETA_H_ +#define VULKAN_BETA_H_ 1 + +/* +** Copyright 2015-2021 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define VK_KHR_video_queue 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR) +#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 2 +#define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue" + +typedef enum VkQueryResultStatusKHR { + VK_QUERY_RESULT_STATUS_ERROR_KHR = -1, + VK_QUERY_RESULT_STATUS_NOT_READY_KHR = 0, + VK_QUERY_RESULT_STATUS_COMPLETE_KHR = 1, + VK_QUERY_RESULT_STATUS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkQueryResultStatusKHR; + +typedef enum VkVideoCodecOperationFlagBitsKHR { + VK_VIDEO_CODEC_OPERATION_INVALID_BIT_KHR = 0, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT = 0x00010000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_EXT = 0x00000001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_EXT = 0x00000002, +#endif + VK_VIDEO_CODEC_OPERATION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoCodecOperationFlagBitsKHR; +typedef VkFlags VkVideoCodecOperationFlagsKHR; + +typedef enum VkVideoChromaSubsamplingFlagBitsKHR { + VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_BIT_KHR = 0, + VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR = 0x00000001, + VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR = 0x00000002, + VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR = 0x00000004, + VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR = 0x00000008, + VK_VIDEO_CHROMA_SUBSAMPLING_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoChromaSubsamplingFlagBitsKHR; +typedef VkFlags VkVideoChromaSubsamplingFlagsKHR; + +typedef enum VkVideoComponentBitDepthFlagBitsKHR { + VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR = 0, + VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR = 0x00000001, + VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR = 0x00000004, + VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR = 0x00000010, + VK_VIDEO_COMPONENT_BIT_DEPTH_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoComponentBitDepthFlagBitsKHR; +typedef VkFlags VkVideoComponentBitDepthFlagsKHR; + +typedef enum VkVideoCapabilityFlagBitsKHR { + VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR = 0x00000001, + VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002, + VK_VIDEO_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoCapabilityFlagBitsKHR; +typedef VkFlags VkVideoCapabilityFlagsKHR; + +typedef enum VkVideoSessionCreateFlagBitsKHR { + VK_VIDEO_SESSION_CREATE_DEFAULT_KHR = 0, + VK_VIDEO_SESSION_CREATE_PROTECTED_CONTENT_BIT_KHR = 0x00000001, + VK_VIDEO_SESSION_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoSessionCreateFlagBitsKHR; +typedef VkFlags VkVideoSessionCreateFlagsKHR; +typedef VkFlags VkVideoBeginCodingFlagsKHR; +typedef VkFlags VkVideoEndCodingFlagsKHR; + +typedef enum VkVideoCodingControlFlagBitsKHR { + VK_VIDEO_CODING_CONTROL_DEFAULT_KHR = 0, + VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR = 0x00000001, + VK_VIDEO_CODING_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoCodingControlFlagBitsKHR; +typedef VkFlags VkVideoCodingControlFlagsKHR; + +typedef enum VkVideoCodingQualityPresetFlagBitsKHR { + VK_VIDEO_CODING_QUALITY_PRESET_DEFAULT_BIT_KHR = 0, + VK_VIDEO_CODING_QUALITY_PRESET_NORMAL_BIT_KHR = 0x00000001, + VK_VIDEO_CODING_QUALITY_PRESET_POWER_BIT_KHR = 0x00000002, + VK_VIDEO_CODING_QUALITY_PRESET_QUALITY_BIT_KHR = 0x00000004, + VK_VIDEO_CODING_QUALITY_PRESET_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoCodingQualityPresetFlagBitsKHR; +typedef VkFlags VkVideoCodingQualityPresetFlagsKHR; +typedef struct VkVideoQueueFamilyProperties2KHR { + VkStructureType sType; + void* pNext; + VkVideoCodecOperationFlagsKHR videoCodecOperations; +} VkVideoQueueFamilyProperties2KHR; + +typedef struct VkVideoProfileKHR { + VkStructureType sType; + void* pNext; + VkVideoCodecOperationFlagBitsKHR videoCodecOperation; + VkVideoChromaSubsamplingFlagsKHR chromaSubsampling; + VkVideoComponentBitDepthFlagsKHR lumaBitDepth; + VkVideoComponentBitDepthFlagsKHR chromaBitDepth; +} VkVideoProfileKHR; + +typedef struct VkVideoProfilesKHR { + VkStructureType sType; + void* pNext; + uint32_t profileCount; + const VkVideoProfileKHR* pProfiles; +} VkVideoProfilesKHR; + +typedef struct VkVideoCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoCapabilityFlagsKHR capabilityFlags; + VkDeviceSize minBitstreamBufferOffsetAlignment; + VkDeviceSize minBitstreamBufferSizeAlignment; + VkExtent2D videoPictureExtentGranularity; + VkExtent2D minExtent; + VkExtent2D maxExtent; + uint32_t maxReferencePicturesSlotsCount; + uint32_t maxReferencePicturesActiveCount; +} VkVideoCapabilitiesKHR; + +typedef struct VkPhysicalDeviceVideoFormatInfoKHR { + VkStructureType sType; + void* pNext; + VkImageUsageFlags imageUsage; + const VkVideoProfilesKHR* pVideoProfiles; +} VkPhysicalDeviceVideoFormatInfoKHR; + +typedef struct VkVideoFormatPropertiesKHR { + VkStructureType sType; + void* pNext; + VkFormat format; +} VkVideoFormatPropertiesKHR; + +typedef struct VkVideoPictureResourceKHR { + VkStructureType sType; + const void* pNext; + VkOffset2D codedOffset; + VkExtent2D codedExtent; + uint32_t baseArrayLayer; + VkImageView imageViewBinding; +} VkVideoPictureResourceKHR; + +typedef struct VkVideoReferenceSlotKHR { + VkStructureType sType; + const void* pNext; + int8_t slotIndex; + const VkVideoPictureResourceKHR* pPictureResource; +} VkVideoReferenceSlotKHR; + +typedef struct VkVideoGetMemoryPropertiesKHR { + VkStructureType sType; + const void* pNext; + uint32_t memoryBindIndex; + VkMemoryRequirements2* pMemoryRequirements; +} VkVideoGetMemoryPropertiesKHR; + +typedef struct VkVideoBindMemoryKHR { + VkStructureType sType; + const void* pNext; + uint32_t memoryBindIndex; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkDeviceSize memorySize; +} VkVideoBindMemoryKHR; + +typedef struct VkVideoSessionCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t queueFamilyIndex; + VkVideoSessionCreateFlagsKHR flags; + const VkVideoProfileKHR* pVideoProfile; + VkFormat pictureFormat; + VkExtent2D maxCodedExtent; + VkFormat referencePicturesFormat; + uint32_t maxReferencePicturesSlotsCount; + uint32_t maxReferencePicturesActiveCount; +} VkVideoSessionCreateInfoKHR; + +typedef struct VkVideoSessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoSessionParametersKHR videoSessionParametersTemplate; + VkVideoSessionKHR videoSession; +} VkVideoSessionParametersCreateInfoKHR; + +typedef struct VkVideoSessionParametersUpdateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t updateSequenceCount; +} VkVideoSessionParametersUpdateInfoKHR; + +typedef struct VkVideoBeginCodingInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoBeginCodingFlagsKHR flags; + VkVideoCodingQualityPresetFlagsKHR codecQualityPreset; + VkVideoSessionKHR videoSession; + VkVideoSessionParametersKHR videoSessionParameters; + uint32_t referenceSlotCount; + const VkVideoReferenceSlotKHR* pReferenceSlots; +} VkVideoBeginCodingInfoKHR; + +typedef struct VkVideoEndCodingInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEndCodingFlagsKHR flags; +} VkVideoEndCodingInfoKHR; + +typedef struct VkVideoCodingControlInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoCodingControlFlagsKHR flags; +} VkVideoCodingControlInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)(VkPhysicalDevice physicalDevice, const VkVideoProfileKHR* pVideoProfile, VkVideoCapabilitiesKHR* pCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo, uint32_t* pVideoFormatPropertyCount, VkVideoFormatPropertiesKHR* pVideoFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreateVideoSessionKHR)(VkDevice device, const VkVideoSessionCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionKHR* pVideoSession); +typedef void (VKAPI_PTR *PFN_vkDestroyVideoSessionKHR)(VkDevice device, VkVideoSessionKHR videoSession, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetVideoSessionMemoryRequirementsKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t* pVideoSessionMemoryRequirementsCount, VkVideoGetMemoryPropertiesKHR* pVideoSessionMemoryRequirements); +typedef VkResult (VKAPI_PTR *PFN_vkBindVideoSessionMemoryKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t videoSessionBindMemoryCount, const VkVideoBindMemoryKHR* pVideoSessionBindMemories); +typedef VkResult (VKAPI_PTR *PFN_vkCreateVideoSessionParametersKHR)(VkDevice device, const VkVideoSessionParametersCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionParametersKHR* pVideoSessionParameters); +typedef VkResult (VKAPI_PTR *PFN_vkUpdateVideoSessionParametersKHR)(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo); +typedef void (VKAPI_PTR *PFN_vkDestroyVideoSessionParametersKHR)(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdBeginVideoCodingKHR)(VkCommandBuffer commandBuffer, const VkVideoBeginCodingInfoKHR* pBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndVideoCodingKHR)(VkCommandBuffer commandBuffer, const VkVideoEndCodingInfoKHR* pEndCodingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdControlVideoCodingKHR)(VkCommandBuffer commandBuffer, const VkVideoCodingControlInfoKHR* pCodingControlInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + const VkVideoProfileKHR* pVideoProfile, + VkVideoCapabilitiesKHR* pCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoFormatPropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo, + uint32_t* pVideoFormatPropertyCount, + VkVideoFormatPropertiesKHR* pVideoFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateVideoSessionKHR( + VkDevice device, + const VkVideoSessionCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkVideoSessionKHR* pVideoSession); + +VKAPI_ATTR void VKAPI_CALL vkDestroyVideoSessionKHR( + VkDevice device, + VkVideoSessionKHR videoSession, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetVideoSessionMemoryRequirementsKHR( + VkDevice device, + VkVideoSessionKHR videoSession, + uint32_t* pVideoSessionMemoryRequirementsCount, + VkVideoGetMemoryPropertiesKHR* pVideoSessionMemoryRequirements); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindVideoSessionMemoryKHR( + VkDevice device, + VkVideoSessionKHR videoSession, + uint32_t videoSessionBindMemoryCount, + const VkVideoBindMemoryKHR* pVideoSessionBindMemories); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateVideoSessionParametersKHR( + VkDevice device, + const VkVideoSessionParametersCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkVideoSessionParametersKHR* pVideoSessionParameters); + +VKAPI_ATTR VkResult VKAPI_CALL vkUpdateVideoSessionParametersKHR( + VkDevice device, + VkVideoSessionParametersKHR videoSessionParameters, + const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo); + +VKAPI_ATTR void VKAPI_CALL vkDestroyVideoSessionParametersKHR( + VkDevice device, + VkVideoSessionParametersKHR videoSessionParameters, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginVideoCodingKHR( + VkCommandBuffer commandBuffer, + const VkVideoBeginCodingInfoKHR* pBeginInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndVideoCodingKHR( + VkCommandBuffer commandBuffer, + const VkVideoEndCodingInfoKHR* pEndCodingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdControlVideoCodingKHR( + VkCommandBuffer commandBuffer, + const VkVideoCodingControlInfoKHR* pCodingControlInfo); +#endif + + +#define VK_KHR_video_decode_queue 1 +#define VK_KHR_VIDEO_DECODE_QUEUE_SPEC_VERSION 1 +#define VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME "VK_KHR_video_decode_queue" + +typedef enum VkVideoDecodeFlagBitsKHR { + VK_VIDEO_DECODE_DEFAULT_KHR = 0, + VK_VIDEO_DECODE_RESERVED_0_BIT_KHR = 0x00000001, + VK_VIDEO_DECODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoDecodeFlagBitsKHR; +typedef VkFlags VkVideoDecodeFlagsKHR; +typedef struct VkVideoDecodeInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoDecodeFlagsKHR flags; + VkOffset2D codedOffset; + VkExtent2D codedExtent; + VkBuffer srcBuffer; + VkDeviceSize srcBufferOffset; + VkDeviceSize srcBufferRange; + VkVideoPictureResourceKHR dstPictureResource; + const VkVideoReferenceSlotKHR* pSetupReferenceSlot; + uint32_t referenceSlotCount; + const VkVideoReferenceSlotKHR* pReferenceSlots; +} VkVideoDecodeInfoKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdDecodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR* pFrameInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDecodeVideoKHR( + VkCommandBuffer commandBuffer, + const VkVideoDecodeInfoKHR* pFrameInfo); +#endif + + +#define VK_KHR_portability_subset 1 +#define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1 +#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset" +typedef struct VkPhysicalDevicePortabilitySubsetFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 constantAlphaColorBlendFactors; + VkBool32 events; + VkBool32 imageViewFormatReinterpretation; + VkBool32 imageViewFormatSwizzle; + VkBool32 imageView2DOn3DImage; + VkBool32 multisampleArrayImage; + VkBool32 mutableComparisonSamplers; + VkBool32 pointPolygons; + VkBool32 samplerMipLodBias; + VkBool32 separateStencilMaskRef; + VkBool32 shaderSampleRateInterpolationFunctions; + VkBool32 tessellationIsolines; + VkBool32 tessellationPointMode; + VkBool32 triangleFans; + VkBool32 vertexAttributeAccessBeyondStride; +} VkPhysicalDevicePortabilitySubsetFeaturesKHR; + +typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t minVertexInputBindingStrideAlignment; +} VkPhysicalDevicePortabilitySubsetPropertiesKHR; + + + +#define VK_KHR_video_encode_queue 1 +#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 2 +#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue" + +typedef enum VkVideoEncodeFlagBitsKHR { + VK_VIDEO_ENCODE_DEFAULT_KHR = 0, + VK_VIDEO_ENCODE_RESERVED_0_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeFlagBitsKHR; +typedef VkFlags VkVideoEncodeFlagsKHR; + +typedef enum VkVideoEncodeRateControlFlagBitsKHR { + VK_VIDEO_ENCODE_RATE_CONTROL_DEFAULT_KHR = 0, + VK_VIDEO_ENCODE_RATE_CONTROL_RESET_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_RATE_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeRateControlFlagBitsKHR; +typedef VkFlags VkVideoEncodeRateControlFlagsKHR; + +typedef enum VkVideoEncodeRateControlModeFlagBitsKHR { + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_NONE_BIT_KHR = 0, + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 1, + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 2, + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeRateControlModeFlagBitsKHR; +typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR; +typedef struct VkVideoEncodeInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeFlagsKHR flags; + uint32_t qualityLevel; + VkExtent2D codedExtent; + VkBuffer dstBitstreamBuffer; + VkDeviceSize dstBitstreamBufferOffset; + VkDeviceSize dstBitstreamBufferMaxRange; + VkVideoPictureResourceKHR srcPictureResource; + const VkVideoReferenceSlotKHR* pSetupReferenceSlot; + uint32_t referenceSlotCount; + const VkVideoReferenceSlotKHR* pReferenceSlots; +} VkVideoEncodeInfoKHR; + +typedef struct VkVideoEncodeRateControlInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeRateControlFlagsKHR flags; + VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode; + uint32_t averageBitrate; + uint16_t peakToAverageBitrateRatio; + uint16_t frameRateNumerator; + uint16_t frameRateDenominator; + uint32_t virtualBufferSizeInMs; +} VkVideoEncodeRateControlInfoKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR( + VkCommandBuffer commandBuffer, + const VkVideoEncodeInfoKHR* pEncodeInfo); +#endif + + +#define VK_EXT_video_encode_h264 1 +#include "vk_video/vulkan_video_codec_h264std.h" +#include "vk_video/vulkan_video_codec_h264std_encode.h" +#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 2 +#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264" + +typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT { + VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00000001, + VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00000002, + VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT = 0x00000004, + VK_VIDEO_ENCODE_H264_CAPABILITY_TRANSFORM_8X8_BIT_EXT = 0x00000008, + VK_VIDEO_ENCODE_H264_CAPABILITY_CHROMA_QP_OFFSET_BIT_EXT = 0x00000010, + VK_VIDEO_ENCODE_H264_CAPABILITY_SECOND_CHROMA_QP_OFFSET_BIT_EXT = 0x00000020, + VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_DISABLED_BIT_EXT = 0x00000040, + VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_ENABLED_BIT_EXT = 0x00000080, + VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00000100, + VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00000200, + VK_VIDEO_ENCODE_H264_CAPABILITY_EVENLY_DISTRIBUTED_SLICE_SIZE_BIT_EXT = 0x00000400, + VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkVideoEncodeH264CapabilityFlagBitsEXT; +typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT; + +typedef enum VkVideoEncodeH264InputModeFlagBitsEXT { + VK_VIDEO_ENCODE_H264_INPUT_MODE_FRAME_BIT_EXT = 0x00000001, + VK_VIDEO_ENCODE_H264_INPUT_MODE_SLICE_BIT_EXT = 0x00000002, + VK_VIDEO_ENCODE_H264_INPUT_MODE_NON_VCL_BIT_EXT = 0x00000004, + VK_VIDEO_ENCODE_H264_INPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkVideoEncodeH264InputModeFlagBitsEXT; +typedef VkFlags VkVideoEncodeH264InputModeFlagsEXT; + +typedef enum VkVideoEncodeH264OutputModeFlagBitsEXT { + VK_VIDEO_ENCODE_H264_OUTPUT_MODE_FRAME_BIT_EXT = 0x00000001, + VK_VIDEO_ENCODE_H264_OUTPUT_MODE_SLICE_BIT_EXT = 0x00000002, + VK_VIDEO_ENCODE_H264_OUTPUT_MODE_NON_VCL_BIT_EXT = 0x00000004, + VK_VIDEO_ENCODE_H264_OUTPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkVideoEncodeH264OutputModeFlagBitsEXT; +typedef VkFlags VkVideoEncodeH264OutputModeFlagsEXT; + +typedef enum VkVideoEncodeH264CreateFlagBitsEXT { + VK_VIDEO_ENCODE_H264_CREATE_DEFAULT_EXT = 0, + VK_VIDEO_ENCODE_H264_CREATE_RESERVED_0_BIT_EXT = 0x00000001, + VK_VIDEO_ENCODE_H264_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkVideoEncodeH264CreateFlagBitsEXT; +typedef VkFlags VkVideoEncodeH264CreateFlagsEXT; +typedef struct VkVideoEncodeH264CapabilitiesEXT { + VkStructureType sType; + const void* pNext; + VkVideoEncodeH264CapabilityFlagsEXT flags; + VkVideoEncodeH264InputModeFlagsEXT inputModeFlags; + VkVideoEncodeH264OutputModeFlagsEXT outputModeFlags; + VkExtent2D minPictureSizeInMbs; + VkExtent2D maxPictureSizeInMbs; + VkExtent2D inputImageDataAlignment; + uint8_t maxNumL0ReferenceForP; + uint8_t maxNumL0ReferenceForB; + uint8_t maxNumL1Reference; + uint8_t qualityLevelCount; + VkExtensionProperties stdExtensionVersion; +} VkVideoEncodeH264CapabilitiesEXT; + +typedef struct VkVideoEncodeH264SessionCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkVideoEncodeH264CreateFlagsEXT flags; + VkExtent2D maxPictureSizeInMbs; + const VkExtensionProperties* pStdExtensionVersion; +} VkVideoEncodeH264SessionCreateInfoEXT; + +typedef struct VkVideoEncodeH264SessionParametersAddInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t spsStdCount; + const StdVideoH264SequenceParameterSet* pSpsStd; + uint32_t ppsStdCount; + const StdVideoH264PictureParameterSet* pPpsStd; +} VkVideoEncodeH264SessionParametersAddInfoEXT; + +typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t maxSpsStdCount; + uint32_t maxPpsStdCount; + const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo; +} VkVideoEncodeH264SessionParametersCreateInfoEXT; + +typedef struct VkVideoEncodeH264DpbSlotInfoEXT { + VkStructureType sType; + const void* pNext; + int8_t slotIndex; + const StdVideoEncodeH264PictureInfo* pStdPictureInfo; +} VkVideoEncodeH264DpbSlotInfoEXT; + +typedef struct VkVideoEncodeH264NaluSliceEXT { + VkStructureType sType; + const void* pNext; + const StdVideoEncodeH264SliceHeader* pSliceHeaderStd; + uint32_t mbCount; + uint8_t refFinalList0EntryCount; + const VkVideoEncodeH264DpbSlotInfoEXT* pRefFinalList0Entries; + uint8_t refFinalList1EntryCount; + const VkVideoEncodeH264DpbSlotInfoEXT* pRefFinalList1Entries; + uint32_t precedingNaluBytes; + uint8_t minQp; + uint8_t maxQp; +} VkVideoEncodeH264NaluSliceEXT; + +typedef struct VkVideoEncodeH264VclFrameInfoEXT { + VkStructureType sType; + const void* pNext; + uint8_t refDefaultFinalList0EntryCount; + const VkVideoEncodeH264DpbSlotInfoEXT* pRefDefaultFinalList0Entries; + uint8_t refDefaultFinalList1EntryCount; + const VkVideoEncodeH264DpbSlotInfoEXT* pRefDefaultFinalList1Entries; + uint32_t naluSliceEntryCount; + const VkVideoEncodeH264NaluSliceEXT* pNaluSliceEntries; + const VkVideoEncodeH264DpbSlotInfoEXT* pCurrentPictureInfo; +} VkVideoEncodeH264VclFrameInfoEXT; + +typedef struct VkVideoEncodeH264EmitPictureParametersEXT { + VkStructureType sType; + const void* pNext; + uint8_t spsId; + VkBool32 emitSpsEnable; + uint32_t ppsIdEntryCount; + const uint8_t* ppsIdEntries; +} VkVideoEncodeH264EmitPictureParametersEXT; + +typedef struct VkVideoEncodeH264ProfileEXT { + VkStructureType sType; + const void* pNext; + StdVideoH264ProfileIdc stdProfileIdc; +} VkVideoEncodeH264ProfileEXT; + + + +#define VK_EXT_video_decode_h264 1 +#include "vk_video/vulkan_video_codec_h264std_decode.h" +#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 3 +#define VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME "VK_EXT_video_decode_h264" + +typedef enum VkVideoDecodeH264PictureLayoutFlagBitsEXT { + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT = 0, + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT = 0x00000001, + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT = 0x00000002, + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkVideoDecodeH264PictureLayoutFlagBitsEXT; +typedef VkFlags VkVideoDecodeH264PictureLayoutFlagsEXT; +typedef VkFlags VkVideoDecodeH264CreateFlagsEXT; +typedef struct VkVideoDecodeH264ProfileEXT { + VkStructureType sType; + const void* pNext; + StdVideoH264ProfileIdc stdProfileIdc; + VkVideoDecodeH264PictureLayoutFlagsEXT pictureLayout; +} VkVideoDecodeH264ProfileEXT; + +typedef struct VkVideoDecodeH264CapabilitiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxLevel; + VkOffset2D fieldOffsetGranularity; + VkExtensionProperties stdExtensionVersion; +} VkVideoDecodeH264CapabilitiesEXT; + +typedef struct VkVideoDecodeH264SessionCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkVideoDecodeH264CreateFlagsEXT flags; + const VkExtensionProperties* pStdExtensionVersion; +} VkVideoDecodeH264SessionCreateInfoEXT; + +typedef struct VkVideoDecodeH264SessionParametersAddInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t spsStdCount; + const StdVideoH264SequenceParameterSet* pSpsStd; + uint32_t ppsStdCount; + const StdVideoH264PictureParameterSet* pPpsStd; +} VkVideoDecodeH264SessionParametersAddInfoEXT; + +typedef struct VkVideoDecodeH264SessionParametersCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t maxSpsStdCount; + uint32_t maxPpsStdCount; + const VkVideoDecodeH264SessionParametersAddInfoEXT* pParametersAddInfo; +} VkVideoDecodeH264SessionParametersCreateInfoEXT; + +typedef struct VkVideoDecodeH264PictureInfoEXT { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH264PictureInfo* pStdPictureInfo; + uint32_t slicesCount; + const uint32_t* pSlicesDataOffsets; +} VkVideoDecodeH264PictureInfoEXT; + +typedef struct VkVideoDecodeH264MvcEXT { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH264Mvc* pStdMvc; +} VkVideoDecodeH264MvcEXT; + +typedef struct VkVideoDecodeH264DpbSlotInfoEXT { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH264ReferenceInfo* pStdReferenceInfo; +} VkVideoDecodeH264DpbSlotInfoEXT; + + + +#define VK_EXT_video_decode_h265 1 +#include "vk_video/vulkan_video_codec_h265std.h" +#include "vk_video/vulkan_video_codec_h265std_decode.h" +#define VK_EXT_VIDEO_DECODE_H265_SPEC_VERSION 1 +#define VK_EXT_VIDEO_DECODE_H265_EXTENSION_NAME "VK_EXT_video_decode_h265" +typedef VkFlags VkVideoDecodeH265CreateFlagsEXT; +typedef struct VkVideoDecodeH265ProfileEXT { + VkStructureType sType; + const void* pNext; + StdVideoH265ProfileIdc stdProfileIdc; +} VkVideoDecodeH265ProfileEXT; + +typedef struct VkVideoDecodeH265CapabilitiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxLevel; + VkExtensionProperties stdExtensionVersion; +} VkVideoDecodeH265CapabilitiesEXT; + +typedef struct VkVideoDecodeH265SessionCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkVideoDecodeH265CreateFlagsEXT flags; + const VkExtensionProperties* pStdExtensionVersion; +} VkVideoDecodeH265SessionCreateInfoEXT; + +typedef struct VkVideoDecodeH265SessionParametersAddInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t spsStdCount; + const StdVideoH265SequenceParameterSet* pSpsStd; + uint32_t ppsStdCount; + const StdVideoH265PictureParameterSet* pPpsStd; +} VkVideoDecodeH265SessionParametersAddInfoEXT; + +typedef struct VkVideoDecodeH265SessionParametersCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t maxSpsStdCount; + uint32_t maxPpsStdCount; + const VkVideoDecodeH265SessionParametersAddInfoEXT* pParametersAddInfo; +} VkVideoDecodeH265SessionParametersCreateInfoEXT; + +typedef struct VkVideoDecodeH265PictureInfoEXT { + VkStructureType sType; + const void* pNext; + StdVideoDecodeH265PictureInfo* pStdPictureInfo; + uint32_t slicesCount; + const uint32_t* pSlicesDataOffsets; +} VkVideoDecodeH265PictureInfoEXT; + +typedef struct VkVideoDecodeH265DpbSlotInfoEXT { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH265ReferenceInfo* pStdReferenceInfo; +} VkVideoDecodeH265DpbSlotInfoEXT; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_core.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_core.h index 544f24fb6..9d2b315dd 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_core.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_core.h @@ -1,24 +1,10 @@ #ifndef VULKAN_CORE_H_ #define VULKAN_CORE_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,43 +13,90 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_VERSION_1_0 1 #include "vk_platform.h" -#define VK_MAKE_VERSION(major, minor, patch) \ - (((major) << 22) | ((minor) << 12) | (patch)) - -// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. -//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 - -// Vulkan 1.0 version number -#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)// Patch version should always be set to 0 - -#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) -#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) -#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) -// Version of this file -#define VK_HEADER_VERSION 114 - - -#define VK_NULL_HANDLE 0 - #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; -#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE) -#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; -#else - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; -#endif +#ifndef VK_USE_64_BIT_PTR_DEFINES + #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define VK_USE_64_BIT_PTR_DEFINES 1 + #else + #define VK_USE_64_BIT_PTR_DEFINES 0 + #endif #endif -typedef uint32_t VkFlags; + +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)) + #define VK_NULL_HANDLE nullptr + #else + #define VK_NULL_HANDLE ((void*)0) + #endif + #else + #define VK_NULL_HANDLE 0ULL + #endif +#endif +#ifndef VK_NULL_HANDLE + #define VK_NULL_HANDLE 0 +#endif + + +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; + #else + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; + #endif +#endif + +// DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead. +#define VK_MAKE_VERSION(major, minor, patch) \ + ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) + +// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. +//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 + +#define VK_MAKE_API_VERSION(variant, major, minor, patch) \ + ((((uint32_t)(variant)) << 29) | (((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) + +// Vulkan 1.0 version number +#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 + +// Version of this file +#define VK_HEADER_VERSION 189 + +// Complete version of this file +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION) + +// DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. +#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) + +// DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead. +#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) + +// DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead. +#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) + +#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29) +#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU) +#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) +#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) typedef uint32_t VkBool32; +typedef uint64_t VkDeviceAddress; typedef uint64_t VkDeviceSize; +typedef uint32_t VkFlags; typedef uint32_t VkSampleMask; +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) VK_DEFINE_HANDLE(VkInstance) VK_DEFINE_HANDLE(VkPhysicalDevice) VK_DEFINE_HANDLE(VkDevice) @@ -72,8 +105,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) VK_DEFINE_HANDLE(VkCommandBuffer) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) @@ -81,37 +112,29 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) -#define VK_LOD_CLAMP_NONE 1000.0f -#define VK_REMAINING_MIP_LEVELS (~0U) -#define VK_REMAINING_ARRAY_LAYERS (~0U) -#define VK_WHOLE_SIZE (~0ULL) +#define VK_UUID_SIZE 16U #define VK_ATTACHMENT_UNUSED (~0U) -#define VK_TRUE 1 -#define VK_FALSE 0 +#define VK_FALSE 0U +#define VK_LOD_CLAMP_NONE 1000.0F #define VK_QUEUE_FAMILY_IGNORED (~0U) +#define VK_REMAINING_ARRAY_LAYERS (~0U) +#define VK_REMAINING_MIP_LEVELS (~0U) #define VK_SUBPASS_EXTERNAL (~0U) -#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 -#define VK_UUID_SIZE 16 -#define VK_MAX_MEMORY_TYPES 32 -#define VK_MAX_MEMORY_HEAPS 16 -#define VK_MAX_EXTENSION_NAME_SIZE 256 -#define VK_MAX_DESCRIPTION_SIZE 256 - -typedef enum VkPipelineCacheHeaderVersion { - VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, - VK_PIPELINE_CACHE_HEADER_VERSION_BEGIN_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, - VK_PIPELINE_CACHE_HEADER_VERSION_END_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, - VK_PIPELINE_CACHE_HEADER_VERSION_RANGE_SIZE = (VK_PIPELINE_CACHE_HEADER_VERSION_ONE - VK_PIPELINE_CACHE_HEADER_VERSION_ONE + 1), - VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheHeaderVersion; +#define VK_TRUE 1U +#define VK_WHOLE_SIZE (~0ULL) +#define VK_MAX_MEMORY_TYPES 32U +#define VK_MAX_MEMORY_HEAPS 16U +#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256U +#define VK_MAX_EXTENSION_NAME_SIZE 256U +#define VK_MAX_DESCRIPTION_SIZE 256U typedef enum VkResult { VK_SUCCESS = 0, @@ -132,8 +155,11 @@ typedef enum VkResult { VK_ERROR_TOO_MANY_OBJECTS = -10, VK_ERROR_FORMAT_NOT_SUPPORTED = -11, VK_ERROR_FRAGMENTED_POOL = -12, + VK_ERROR_UNKNOWN = -13, VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, + VK_ERROR_FRAGMENTATION = -1000161000, + VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, @@ -142,15 +168,19 @@ typedef enum VkResult { VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - VK_ERROR_FRAGMENTATION_EXT = -1000161000, VK_ERROR_NOT_PERMITTED_EXT = -1000174001, - VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = -1000244000, VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, + VK_THREAD_IDLE_KHR = 1000268000, + VK_THREAD_DONE_KHR = 1000268001, + VK_OPERATION_DEFERRED_KHR = 1000268002, + VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, + VK_PIPELINE_COMPILE_REQUIRED_EXT = 1000297000, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, - VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL, - VK_RESULT_END_RANGE = VK_INCOMPLETE, - VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1), + VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, + VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED_EXT, VK_RESULT_MAX_ENUM = 0x7FFFFFFF } VkResult; @@ -269,6 +299,56 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002, + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, + VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004, + VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001, + VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, + VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, @@ -290,13 +370,119 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_PROFILE_KHR = 1000023000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR = 1000023001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_KHR = 1000023002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_GET_MEMORY_PROPERTIES_KHR = 1000023003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_BIND_MEMORY_KHR = 1000023004, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR = 1000023005, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR = 1000023008, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR = 1000023009, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR = 1000023010, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_KHR = 1000023011, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000023012, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_PROFILES_KHR = 1000023013, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR = 1000024000, +#endif VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, + VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX = 1000029000, + VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX = 1000029001, + VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX = 1000029002, VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_CREATE_INFO_EXT = 1000038001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038004, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038005, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038006, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038007, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038008, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_CREATE_INFO_EXT = 1000040001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040004, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040005, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040006, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040007, +#endif VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, @@ -307,6 +493,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000, VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, @@ -327,14 +514,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = 1000082000, VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, - VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000, - VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001, - VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX = 1000086002, - VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003, - VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004, - VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000, VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000, @@ -351,23 +531,19 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = 1000108000, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = 1000108001, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = 1000108002, - VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = 1000108003, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002, - VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004, - VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005, - VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006, VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000, VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, + VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, + VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, + VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR = 1000116005, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001, VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002, @@ -389,8 +565,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000, - VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, @@ -400,27 +574,47 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009, + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, + VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013, VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, - VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001, +#endif VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, @@ -441,23 +635,40 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, + VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_CREATE_INFO_EXT = 1000187001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187004, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187005, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187006, +#endif VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = 1000197000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = 1000199000, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = 1000199001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, @@ -467,33 +678,43 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000, VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS2_FEATURES_INTEL = 1000209000, - VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = 1000210000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, + VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL = 1000210002, VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = 1000215000, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002, + VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, + VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, - VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = 1000244001, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, @@ -502,15 +723,126 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = 1000253000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002, VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = 1000261000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, + VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, + VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV = 1000277005, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, + VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, + VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, + VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, + VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, + VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR = 1000299000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, +#endif + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, + VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = 1000314000, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = 1000314001, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = 1000314002, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = 1000314003, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = 1000314004, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = 1000314005, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = 1000314006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = 1000314007, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, + VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = 1000325000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, + VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, + VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = 1000337000, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = 1000337001, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = 1000337002, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = 1000337003, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = 1000337004, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = 1000337005, + VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = 1000337006, + VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = 1000337007, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = 1000337008, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = 1000337009, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, + VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, + VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000, + VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, + VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, + VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, + VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, + VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, + VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, + VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, + VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, + VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = 1000388000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = 1000388001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, @@ -546,9 +878,22 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, @@ -556,15 +901,18 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, @@ -573,32 +921,176 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, + VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, - VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, - VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, - VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, + VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; +typedef enum VkImageLayout { + VK_IMAGE_LAYOUT_UNDEFINED = 0, + VK_IMAGE_LAYOUT_GENERAL = 1, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, + VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR = 1000024001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR = 1000024002, +#endif + VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, + VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR = 1000164003, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR = 1000299000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR = 1000299001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, +#endif + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = 1000314000, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = 1000314001, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF +} VkImageLayout; + +typedef enum VkObjectType { + VK_OBJECT_TYPE_UNKNOWN = 0, + VK_OBJECT_TYPE_INSTANCE = 1, + VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, + VK_OBJECT_TYPE_DEVICE = 3, + VK_OBJECT_TYPE_QUEUE = 4, + VK_OBJECT_TYPE_SEMAPHORE = 5, + VK_OBJECT_TYPE_COMMAND_BUFFER = 6, + VK_OBJECT_TYPE_FENCE = 7, + VK_OBJECT_TYPE_DEVICE_MEMORY = 8, + VK_OBJECT_TYPE_BUFFER = 9, + VK_OBJECT_TYPE_IMAGE = 10, + VK_OBJECT_TYPE_EVENT = 11, + VK_OBJECT_TYPE_QUERY_POOL = 12, + VK_OBJECT_TYPE_BUFFER_VIEW = 13, + VK_OBJECT_TYPE_IMAGE_VIEW = 14, + VK_OBJECT_TYPE_SHADER_MODULE = 15, + VK_OBJECT_TYPE_PIPELINE_CACHE = 16, + VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, + VK_OBJECT_TYPE_RENDER_PASS = 18, + VK_OBJECT_TYPE_PIPELINE = 19, + VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, + VK_OBJECT_TYPE_SAMPLER = 21, + VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, + VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, + VK_OBJECT_TYPE_FRAMEBUFFER = 24, + VK_OBJECT_TYPE_COMMAND_POOL = 25, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, + VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, + VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, + VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001, + VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_OBJECT_TYPE_VIDEO_SESSION_KHR = 1000023000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR = 1000023001, +#endif + VK_OBJECT_TYPE_CU_MODULE_NVX = 1000029000, + VK_OBJECT_TYPE_CU_FUNCTION_NVX = 1000029001, + VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, + VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, + VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, + VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, + VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = 1000295000, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, + VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkObjectType; + +typedef enum VkPipelineCacheHeaderVersion { + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheHeaderVersion; + +typedef enum VkVendorId { + VK_VENDOR_ID_VIV = 0x10001, + VK_VENDOR_ID_VSI = 0x10002, + VK_VENDOR_ID_KAZAN = 0x10003, + VK_VENDOR_ID_CODEPLAY = 0x10004, + VK_VENDOR_ID_MESA = 0x10005, + VK_VENDOR_ID_POCL = 0x10006, + VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF +} VkVendorId; + typedef enum VkSystemAllocationScope { VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, - VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND, - VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE, - VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1), VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF } VkSystemAllocationScope; typedef enum VkInternalAllocationType { VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, - VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1), VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF } VkInternalAllocationType; @@ -830,6 +1322,26 @@ typedef enum VkFormat { VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = 1000066000, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = 1000066001, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = 1000066002, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = 1000066003, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = 1000066004, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = 1000066005, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = 1000066006, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = 1000066007, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = 1000066008, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = 1000066009, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = 1000066010, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = 1000066011, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = 1000066012, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = 1000066013, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = 1000330000, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = 1000330001, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = 1000330002, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = 1000330003, + VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = 1000340000, + VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = 1000340001, VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, @@ -864,41 +1376,29 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, - VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED, - VK_FORMAT_END_RANGE = VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - VK_FORMAT_RANGE_SIZE = (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1), VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; -typedef enum VkImageType { - VK_IMAGE_TYPE_1D = 0, - VK_IMAGE_TYPE_2D = 1, - VK_IMAGE_TYPE_3D = 2, - VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D, - VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D, - VK_IMAGE_TYPE_RANGE_SIZE = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1), - VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageType; - typedef enum VkImageTiling { VK_IMAGE_TILING_OPTIMAL = 0, VK_IMAGE_TILING_LINEAR = 1, VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000, - VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR, - VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1), VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF } VkImageTiling; +typedef enum VkImageType { + VK_IMAGE_TYPE_1D = 0, + VK_IMAGE_TYPE_2D = 1, + VK_IMAGE_TYPE_3D = 2, + VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageType; + typedef enum VkPhysicalDeviceType { VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, VK_PHYSICAL_DEVICE_TYPE_CPU = 4, - VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER, - VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU, - VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1), VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkPhysicalDeviceType; @@ -906,62 +1406,27 @@ typedef enum VkQueryType { VK_QUERY_TYPE_OCCLUSION = 0, VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, VK_QUERY_TYPE_TIMESTAMP = 2, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR = 1000023000, +#endif VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004, + VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR = 1000116000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR = 1000150000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR = 1000150001, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000, - VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION, - VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP, - VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1), +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000, +#endif VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF } VkQueryType; typedef enum VkSharingMode { VK_SHARING_MODE_EXCLUSIVE = 0, VK_SHARING_MODE_CONCURRENT = 1, - VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE, - VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT, - VK_SHARING_MODE_RANGE_SIZE = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1), VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF } VkSharingMode; -typedef enum VkImageLayout { - VK_IMAGE_LAYOUT_UNDEFINED = 0, - VK_IMAGE_LAYOUT_GENERAL = 1, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, - VK_IMAGE_LAYOUT_PREINITIALIZED = 8, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, - VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, - VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003, - VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED, - VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1), - VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF -} VkImageLayout; - -typedef enum VkImageViewType { - VK_IMAGE_VIEW_TYPE_1D = 0, - VK_IMAGE_VIEW_TYPE_2D = 1, - VK_IMAGE_VIEW_TYPE_3D = 2, - VK_IMAGE_VIEW_TYPE_CUBE = 3, - VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, - VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, - VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, - VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D, - VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, - VK_IMAGE_VIEW_TYPE_RANGE_SIZE = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1), - VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageViewType; - typedef enum VkComponentSwizzle { VK_COMPONENT_SWIZZLE_IDENTITY = 0, VK_COMPONENT_SWIZZLE_ZERO = 1, @@ -970,111 +1435,19 @@ typedef enum VkComponentSwizzle { VK_COMPONENT_SWIZZLE_G = 4, VK_COMPONENT_SWIZZLE_B = 5, VK_COMPONENT_SWIZZLE_A = 6, - VK_COMPONENT_SWIZZLE_BEGIN_RANGE = VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_END_RANGE = VK_COMPONENT_SWIZZLE_A, - VK_COMPONENT_SWIZZLE_RANGE_SIZE = (VK_COMPONENT_SWIZZLE_A - VK_COMPONENT_SWIZZLE_IDENTITY + 1), VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF } VkComponentSwizzle; -typedef enum VkVertexInputRate { - VK_VERTEX_INPUT_RATE_VERTEX = 0, - VK_VERTEX_INPUT_RATE_INSTANCE = 1, - VK_VERTEX_INPUT_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_RATE_VERTEX, - VK_VERTEX_INPUT_RATE_END_RANGE = VK_VERTEX_INPUT_RATE_INSTANCE, - VK_VERTEX_INPUT_RATE_RANGE_SIZE = (VK_VERTEX_INPUT_RATE_INSTANCE - VK_VERTEX_INPUT_RATE_VERTEX + 1), - VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF -} VkVertexInputRate; - -typedef enum VkPrimitiveTopology { - VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, - VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, - VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, - VK_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1), - VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF -} VkPrimitiveTopology; - -typedef enum VkPolygonMode { - VK_POLYGON_MODE_FILL = 0, - VK_POLYGON_MODE_LINE = 1, - VK_POLYGON_MODE_POINT = 2, - VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, - VK_POLYGON_MODE_BEGIN_RANGE = VK_POLYGON_MODE_FILL, - VK_POLYGON_MODE_END_RANGE = VK_POLYGON_MODE_POINT, - VK_POLYGON_MODE_RANGE_SIZE = (VK_POLYGON_MODE_POINT - VK_POLYGON_MODE_FILL + 1), - VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF -} VkPolygonMode; - -typedef enum VkFrontFace { - VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, - VK_FRONT_FACE_CLOCKWISE = 1, - VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_COUNTER_CLOCKWISE, - VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CLOCKWISE, - VK_FRONT_FACE_RANGE_SIZE = (VK_FRONT_FACE_CLOCKWISE - VK_FRONT_FACE_COUNTER_CLOCKWISE + 1), - VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF -} VkFrontFace; - -typedef enum VkCompareOp { - VK_COMPARE_OP_NEVER = 0, - VK_COMPARE_OP_LESS = 1, - VK_COMPARE_OP_EQUAL = 2, - VK_COMPARE_OP_LESS_OR_EQUAL = 3, - VK_COMPARE_OP_GREATER = 4, - VK_COMPARE_OP_NOT_EQUAL = 5, - VK_COMPARE_OP_GREATER_OR_EQUAL = 6, - VK_COMPARE_OP_ALWAYS = 7, - VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER, - VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS, - VK_COMPARE_OP_RANGE_SIZE = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1), - VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF -} VkCompareOp; - -typedef enum VkStencilOp { - VK_STENCIL_OP_KEEP = 0, - VK_STENCIL_OP_ZERO = 1, - VK_STENCIL_OP_REPLACE = 2, - VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, - VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, - VK_STENCIL_OP_INVERT = 5, - VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, - VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, - VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP, - VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DECREMENT_AND_WRAP, - VK_STENCIL_OP_RANGE_SIZE = (VK_STENCIL_OP_DECREMENT_AND_WRAP - VK_STENCIL_OP_KEEP + 1), - VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF -} VkStencilOp; - -typedef enum VkLogicOp { - VK_LOGIC_OP_CLEAR = 0, - VK_LOGIC_OP_AND = 1, - VK_LOGIC_OP_AND_REVERSE = 2, - VK_LOGIC_OP_COPY = 3, - VK_LOGIC_OP_AND_INVERTED = 4, - VK_LOGIC_OP_NO_OP = 5, - VK_LOGIC_OP_XOR = 6, - VK_LOGIC_OP_OR = 7, - VK_LOGIC_OP_NOR = 8, - VK_LOGIC_OP_EQUIVALENT = 9, - VK_LOGIC_OP_INVERT = 10, - VK_LOGIC_OP_OR_REVERSE = 11, - VK_LOGIC_OP_COPY_INVERTED = 12, - VK_LOGIC_OP_OR_INVERTED = 13, - VK_LOGIC_OP_NAND = 14, - VK_LOGIC_OP_SET = 15, - VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR, - VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET, - VK_LOGIC_OP_RANGE_SIZE = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1), - VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF -} VkLogicOp; +typedef enum VkImageViewType { + VK_IMAGE_VIEW_TYPE_1D = 0, + VK_IMAGE_VIEW_TYPE_2D = 1, + VK_IMAGE_VIEW_TYPE_3D = 2, + VK_IMAGE_VIEW_TYPE_CUBE = 3, + VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, + VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, + VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, + VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageViewType; typedef enum VkBlendFactor { VK_BLEND_FACTOR_ZERO = 0, @@ -1096,9 +1469,6 @@ typedef enum VkBlendFactor { VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, VK_BLEND_FACTOR_SRC1_ALPHA = 17, VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, - VK_BLEND_FACTOR_BEGIN_RANGE = VK_BLEND_FACTOR_ZERO, - VK_BLEND_FACTOR_END_RANGE = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - VK_BLEND_FACTOR_RANGE_SIZE = (VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - VK_BLEND_FACTOR_ZERO + 1), VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF } VkBlendFactor; @@ -1154,12 +1524,21 @@ typedef enum VkBlendOp { VK_BLEND_OP_RED_EXT = 1000148043, VK_BLEND_OP_GREEN_EXT = 1000148044, VK_BLEND_OP_BLUE_EXT = 1000148045, - VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD, - VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX, - VK_BLEND_OP_RANGE_SIZE = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1), VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF } VkBlendOp; +typedef enum VkCompareOp { + VK_COMPARE_OP_NEVER = 0, + VK_COMPARE_OP_LESS = 1, + VK_COMPARE_OP_EQUAL = 2, + VK_COMPARE_OP_LESS_OR_EQUAL = 3, + VK_COMPARE_OP_GREATER = 4, + VK_COMPARE_OP_NOT_EQUAL = 5, + VK_COMPARE_OP_GREATER_OR_EQUAL = 6, + VK_COMPARE_OP_ALWAYS = 7, + VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF +} VkCompareOp; + typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT = 0, VK_DYNAMIC_STATE_SCISSOR = 1, @@ -1173,46 +1552,100 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, + VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1000347000, VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004, VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006, VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, - VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1), + VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000, + VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, + VK_DYNAMIC_STATE_CULL_MODE_EXT = 1000267000, + VK_DYNAMIC_STATE_FRONT_FACE_EXT = 1000267001, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = 1000267002, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = 1000267003, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = 1000267004, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = 1000267005, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = 1000267006, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = 1000267007, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = 1000267008, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = 1000267009, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = 1000267010, + VK_DYNAMIC_STATE_STENCIL_OP_EXT = 1000267011, + VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000, + VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = 1000377001, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = 1000377002, + VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = 1000377004, + VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000, VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } VkDynamicState; -typedef enum VkFilter { - VK_FILTER_NEAREST = 0, - VK_FILTER_LINEAR = 1, - VK_FILTER_CUBIC_IMG = 1000015000, - VK_FILTER_CUBIC_EXT = VK_FILTER_CUBIC_IMG, - VK_FILTER_BEGIN_RANGE = VK_FILTER_NEAREST, - VK_FILTER_END_RANGE = VK_FILTER_LINEAR, - VK_FILTER_RANGE_SIZE = (VK_FILTER_LINEAR - VK_FILTER_NEAREST + 1), - VK_FILTER_MAX_ENUM = 0x7FFFFFFF -} VkFilter; +typedef enum VkFrontFace { + VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, + VK_FRONT_FACE_CLOCKWISE = 1, + VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF +} VkFrontFace; -typedef enum VkSamplerMipmapMode { - VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, - VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, - VK_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = VK_SAMPLER_MIPMAP_MODE_NEAREST, - VK_SAMPLER_MIPMAP_MODE_END_RANGE = VK_SAMPLER_MIPMAP_MODE_LINEAR, - VK_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (VK_SAMPLER_MIPMAP_MODE_LINEAR - VK_SAMPLER_MIPMAP_MODE_NEAREST + 1), - VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerMipmapMode; +typedef enum VkVertexInputRate { + VK_VERTEX_INPUT_RATE_VERTEX = 0, + VK_VERTEX_INPUT_RATE_INSTANCE = 1, + VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF +} VkVertexInputRate; -typedef enum VkSamplerAddressMode { - VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, - VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, - VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, - VK_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = VK_SAMPLER_ADDRESS_MODE_REPEAT, - VK_SAMPLER_ADDRESS_MODE_END_RANGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - VK_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - VK_SAMPLER_ADDRESS_MODE_REPEAT + 1), - VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerAddressMode; +typedef enum VkPrimitiveTopology { + VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, + VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, + VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF +} VkPrimitiveTopology; + +typedef enum VkPolygonMode { + VK_POLYGON_MODE_FILL = 0, + VK_POLYGON_MODE_LINE = 1, + VK_POLYGON_MODE_POINT = 2, + VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, + VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF +} VkPolygonMode; + +typedef enum VkStencilOp { + VK_STENCIL_OP_KEEP = 0, + VK_STENCIL_OP_ZERO = 1, + VK_STENCIL_OP_REPLACE = 2, + VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, + VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, + VK_STENCIL_OP_INVERT = 5, + VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, + VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, + VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF +} VkStencilOp; + +typedef enum VkLogicOp { + VK_LOGIC_OP_CLEAR = 0, + VK_LOGIC_OP_AND = 1, + VK_LOGIC_OP_AND_REVERSE = 2, + VK_LOGIC_OP_COPY = 3, + VK_LOGIC_OP_AND_INVERTED = 4, + VK_LOGIC_OP_NO_OP = 5, + VK_LOGIC_OP_XOR = 6, + VK_LOGIC_OP_OR = 7, + VK_LOGIC_OP_NOR = 8, + VK_LOGIC_OP_EQUIVALENT = 9, + VK_LOGIC_OP_INVERT = 10, + VK_LOGIC_OP_OR_REVERSE = 11, + VK_LOGIC_OP_COPY_INVERTED = 12, + VK_LOGIC_OP_OR_INVERTED = 13, + VK_LOGIC_OP_NAND = 14, + VK_LOGIC_OP_SET = 15, + VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF +} VkLogicOp; typedef enum VkBorderColor { VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, @@ -1221,12 +1654,35 @@ typedef enum VkBorderColor { VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, - VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, - VK_BORDER_COLOR_RANGE_SIZE = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1), + VK_BORDER_COLOR_FLOAT_CUSTOM_EXT = 1000287003, + VK_BORDER_COLOR_INT_CUSTOM_EXT = 1000287004, VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF } VkBorderColor; +typedef enum VkFilter { + VK_FILTER_NEAREST = 0, + VK_FILTER_LINEAR = 1, + VK_FILTER_CUBIC_IMG = 1000015000, + VK_FILTER_CUBIC_EXT = VK_FILTER_CUBIC_IMG, + VK_FILTER_MAX_ENUM = 0x7FFFFFFF +} VkFilter; + +typedef enum VkSamplerAddressMode { + VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, + VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerAddressMode; + +typedef enum VkSamplerMipmapMode { + VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerMipmapMode; + typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_SAMPLER = 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, @@ -1240,10 +1696,9 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, - VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER, - VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1), + VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = 1000351000, VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorType; @@ -1251,117 +1706,103 @@ typedef enum VkAttachmentLoadOp { VK_ATTACHMENT_LOAD_OP_LOAD = 0, VK_ATTACHMENT_LOAD_OP_CLEAR = 1, VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, - VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD, - VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_RANGE_SIZE = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1), + VK_ATTACHMENT_LOAD_OP_NONE_EXT = 1000400000, VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentLoadOp; typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_RANGE_SIZE = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1), + VK_ATTACHMENT_STORE_OP_NONE_EXT = 1000301000, + VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE_EXT, VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentStoreOp; typedef enum VkPipelineBindPoint { VK_PIPELINE_BIND_POINT_GRAPHICS = 0, VK_PIPELINE_BIND_POINT_COMPUTE = 1, - VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = 1000165000, - VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS, - VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE, - VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1), + VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR = 1000165000, + VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI = 1000369003, + VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF } VkPipelineBindPoint; typedef enum VkCommandBufferLevel { VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, - VK_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - VK_COMMAND_BUFFER_LEVEL_END_RANGE = VK_COMMAND_BUFFER_LEVEL_SECONDARY, - VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (VK_COMMAND_BUFFER_LEVEL_SECONDARY - VK_COMMAND_BUFFER_LEVEL_PRIMARY + 1), VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF } VkCommandBufferLevel; typedef enum VkIndexType { VK_INDEX_TYPE_UINT16 = 0, VK_INDEX_TYPE_UINT32 = 1, - VK_INDEX_TYPE_NONE_NV = 1000165000, - VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16, - VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32, - VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1), + VK_INDEX_TYPE_NONE_KHR = 1000165000, + VK_INDEX_TYPE_UINT8_EXT = 1000265000, + VK_INDEX_TYPE_NONE_NV = VK_INDEX_TYPE_NONE_KHR, VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF } VkIndexType; typedef enum VkSubpassContents { VK_SUBPASS_CONTENTS_INLINE = 0, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, - VK_SUBPASS_CONTENTS_BEGIN_RANGE = VK_SUBPASS_CONTENTS_INLINE, - VK_SUBPASS_CONTENTS_END_RANGE = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, - VK_SUBPASS_CONTENTS_RANGE_SIZE = (VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - VK_SUBPASS_CONTENTS_INLINE + 1), VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF } VkSubpassContents; -typedef enum VkObjectType { - VK_OBJECT_TYPE_UNKNOWN = 0, - VK_OBJECT_TYPE_INSTANCE = 1, - VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, - VK_OBJECT_TYPE_DEVICE = 3, - VK_OBJECT_TYPE_QUEUE = 4, - VK_OBJECT_TYPE_SEMAPHORE = 5, - VK_OBJECT_TYPE_COMMAND_BUFFER = 6, - VK_OBJECT_TYPE_FENCE = 7, - VK_OBJECT_TYPE_DEVICE_MEMORY = 8, - VK_OBJECT_TYPE_BUFFER = 9, - VK_OBJECT_TYPE_IMAGE = 10, - VK_OBJECT_TYPE_EVENT = 11, - VK_OBJECT_TYPE_QUERY_POOL = 12, - VK_OBJECT_TYPE_BUFFER_VIEW = 13, - VK_OBJECT_TYPE_IMAGE_VIEW = 14, - VK_OBJECT_TYPE_SHADER_MODULE = 15, - VK_OBJECT_TYPE_PIPELINE_CACHE = 16, - VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, - VK_OBJECT_TYPE_RENDER_PASS = 18, - VK_OBJECT_TYPE_PIPELINE = 19, - VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, - VK_OBJECT_TYPE_SAMPLER = 21, - VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, - VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, - VK_OBJECT_TYPE_FRAMEBUFFER = 24, - VK_OBJECT_TYPE_COMMAND_POOL = 25, - VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, - VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, - VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, - VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, - VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, - VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001, - VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, - VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000, - VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001, - VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, - VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, - VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, - VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, - VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, - VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, - VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN, - VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_COMMAND_POOL, - VK_OBJECT_TYPE_RANGE_SIZE = (VK_OBJECT_TYPE_COMMAND_POOL - VK_OBJECT_TYPE_UNKNOWN + 1), - VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkObjectType; +typedef enum VkAccessFlagBits { + VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, + VK_ACCESS_INDEX_READ_BIT = 0x00000002, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, + VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, + VK_ACCESS_SHADER_READ_BIT = 0x00000020, + VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, + VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, + VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, + VK_ACCESS_HOST_READ_BIT = 0x00002000, + VK_ACCESS_HOST_WRITE_BIT = 0x00004000, + VK_ACCESS_MEMORY_READ_BIT = 0x00008000, + VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, + VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, + VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000, + VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, + VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, + VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, + VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, + VK_ACCESS_NONE_KHR = 0, + VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAccessFlagBits; +typedef VkFlags VkAccessFlags; -typedef enum VkVendorId { - VK_VENDOR_ID_VIV = 0x10001, - VK_VENDOR_ID_VSI = 0x10002, - VK_VENDOR_ID_KAZAN = 0x10003, - VK_VENDOR_ID_BEGIN_RANGE = VK_VENDOR_ID_VIV, - VK_VENDOR_ID_END_RANGE = VK_VENDOR_ID_KAZAN, - VK_VENDOR_ID_RANGE_SIZE = (VK_VENDOR_ID_KAZAN - VK_VENDOR_ID_VIV + 1), - VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF -} VkVendorId; -typedef VkFlags VkInstanceCreateFlags; +typedef enum VkImageAspectFlagBits { + VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, + VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, + VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, + VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, + VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, + VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, + VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, + VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, + VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, + VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400, + VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, + VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, + VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, + VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageAspectFlagBits; +typedef VkFlags VkImageAspectFlags; typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, @@ -1386,11 +1827,26 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000, VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000, VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_FORMAT_FEATURE_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_FORMAT_FEATURE_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000, +#endif + VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000, VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, + VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_FORMAT_FEATURE_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_FORMAT_FEATURE_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000, +#endif VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, @@ -1403,21 +1859,6 @@ typedef enum VkFormatFeatureFlagBits { } VkFormatFeatureFlagBits; typedef VkFlags VkFormatFeatureFlags; -typedef enum VkImageUsageFlagBits { - VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, - VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, - VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, - VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, - VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100, - VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, - VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageUsageFlagBits; -typedef VkFlags VkImageUsageFlags; - typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, @@ -1456,26 +1897,41 @@ typedef enum VkSampleCountFlagBits { } VkSampleCountFlagBits; typedef VkFlags VkSampleCountFlags; -typedef enum VkQueueFlagBits { - VK_QUEUE_GRAPHICS_BIT = 0x00000001, - VK_QUEUE_COMPUTE_BIT = 0x00000002, - VK_QUEUE_TRANSFER_BIT = 0x00000004, - VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, - VK_QUEUE_PROTECTED_BIT = 0x00000010, - VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueueFlagBits; -typedef VkFlags VkQueueFlags; - -typedef enum VkMemoryPropertyFlagBits { - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, - VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, - VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, - VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020, - VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryPropertyFlagBits; -typedef VkFlags VkMemoryPropertyFlags; +typedef enum VkImageUsageFlagBits { + VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, + VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00000400, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00000800, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR = 0x00001000, +#endif + VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, + VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00000100, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00002000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00004000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000, +#endif + VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000, + VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageUsageFlagBits; +typedef VkFlags VkImageUsageFlags; +typedef VkFlags VkInstanceCreateFlags; typedef enum VkMemoryHeapFlagBits { VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, @@ -1484,6 +1940,36 @@ typedef enum VkMemoryHeapFlagBits { VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkMemoryHeapFlagBits; typedef VkFlags VkMemoryHeapFlags; + +typedef enum VkMemoryPropertyFlagBits { + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, + VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, + VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020, + VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040, + VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080, + VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100, + VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryPropertyFlagBits; +typedef VkFlags VkMemoryPropertyFlags; + +typedef enum VkQueueFlagBits { + VK_QUEUE_GRAPHICS_BIT = 0x00000001, + VK_QUEUE_COMPUTE_BIT = 0x00000002, + VK_QUEUE_TRANSFER_BIT = 0x00000004, + VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, + VK_QUEUE_PROTECTED_BIT = 0x00000010, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_QUEUE_VIDEO_DECODE_BIT_KHR = 0x00000020, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_QUEUE_VIDEO_ENCODE_BIT_KHR = 0x00000040, +#endif + VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueueFlagBits; +typedef VkFlags VkQueueFlags; typedef VkFlags VkDeviceCreateFlags; typedef enum VkDeviceQueueCreateFlagBits { @@ -1512,36 +1998,27 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, - VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000, - VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000, - VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = 0x00200000, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, + VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000, + VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, + VK_PIPELINE_STAGE_NONE_KHR = 0, + VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef VkFlags VkPipelineStageFlags; typedef VkFlags VkMemoryMapFlags; -typedef enum VkImageAspectFlagBits { - VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, - VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, - VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, - VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, - VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, - VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, - VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, - VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, - VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, - VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, - VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400, - VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, - VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, - VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, - VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageAspectFlagBits; -typedef VkFlags VkImageAspectFlags; +typedef enum VkSparseMemoryBindFlagBits { + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, + VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseMemoryBindFlagBits; +typedef VkFlags VkSparseMemoryBindFlags; typedef enum VkSparseImageFormatFlagBits { VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, @@ -1551,20 +2028,18 @@ typedef enum VkSparseImageFormatFlagBits { } VkSparseImageFormatFlagBits; typedef VkFlags VkSparseImageFormatFlags; -typedef enum VkSparseMemoryBindFlagBits { - VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, - VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseMemoryBindFlagBits; -typedef VkFlags VkSparseMemoryBindFlags; - typedef enum VkFenceCreateFlagBits { VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkFenceCreateFlagBits; typedef VkFlags VkFenceCreateFlags; typedef VkFlags VkSemaphoreCreateFlags; + +typedef enum VkEventCreateFlagBits { + VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = 0x00000001, + VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkEventCreateFlagBits; typedef VkFlags VkEventCreateFlags; -typedef VkFlags VkQueryPoolCreateFlags; typedef enum VkQueryPipelineStatisticFlagBits { VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, @@ -1581,12 +2056,16 @@ typedef enum VkQueryPipelineStatisticFlagBits { VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueryPipelineStatisticFlagBits; typedef VkFlags VkQueryPipelineStatisticFlags; +typedef VkFlags VkQueryPoolCreateFlags; typedef enum VkQueryResultFlagBits { VK_QUERY_RESULT_64_BIT = 0x00000001, VK_QUERY_RESULT_WAIT_BIT = 0x00000002, VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_QUERY_RESULT_WITH_STATUS_BIT_KHR = 0x00000010, +#endif VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkQueryResultFlagBits; typedef VkFlags VkQueryResultFlags; @@ -1596,7 +2075,9 @@ typedef enum VkBufferCreateFlagBits { VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008, - VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = 0x00000010, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000010, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferCreateFlagBits; typedef VkFlags VkBufferCreateFlags; @@ -1611,11 +2092,28 @@ typedef enum VkBufferUsageFlagBits { VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 0x00020000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00004000, +#endif VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000, VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200, - VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = 0x00000400, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = 0x00020000, + VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000, + VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000, + VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000, +#endif + VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferUsageFlagBits; typedef VkFlags VkBufferUsageFlags; @@ -1623,24 +2121,64 @@ typedef VkFlags VkBufferViewCreateFlags; typedef enum VkImageViewCreateFlagBits { VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, + VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT = 0x00000002, VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageViewCreateFlagBits; typedef VkFlags VkImageViewCreateFlags; + +typedef enum VkShaderModuleCreateFlagBits { + VK_SHADER_MODULE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkShaderModuleCreateFlagBits; typedef VkFlags VkShaderModuleCreateFlags; + +typedef enum VkPipelineCacheCreateFlagBits { + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheCreateFlagBits; typedef VkFlags VkPipelineCacheCreateFlags; +typedef enum VkColorComponentFlagBits { + VK_COLOR_COMPONENT_R_BIT = 0x00000001, + VK_COLOR_COMPONENT_G_BIT = 0x00000002, + VK_COLOR_COMPONENT_B_BIT = 0x00000004, + VK_COLOR_COMPONENT_A_BIT = 0x00000008, + VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkColorComponentFlagBits; +typedef VkFlags VkColorComponentFlags; + typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, - VK_PIPELINE_CREATE_DISPATCH_BASE = 0x00000010, + VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000, + VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000, + VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000, + VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000, VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020, + VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR = 0x00000040, + VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, + VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, + VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = 0x00000100, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = 0x00000200, + VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, + VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCreateFlagBits; typedef VkFlags VkPipelineCreateFlags; + +typedef enum VkPipelineShaderStageCreateFlagBits { + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = 0x00000001, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineShaderStageCreateFlagBits; typedef VkFlags VkPipelineShaderStageCreateFlags; typedef enum VkShaderStageFlagBits { @@ -1652,21 +2190,23 @@ typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, VK_SHADER_STAGE_ALL = 0x7FFFFFFF, - VK_SHADER_STAGE_RAYGEN_BIT_NV = 0x00000100, - VK_SHADER_STAGE_ANY_HIT_BIT_NV = 0x00000200, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = 0x00000400, - VK_SHADER_STAGE_MISS_BIT_NV = 0x00000800, - VK_SHADER_STAGE_INTERSECTION_BIT_NV = 0x00001000, - VK_SHADER_STAGE_CALLABLE_BIT_NV = 0x00002000, + VK_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, + VK_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, + VK_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, + VK_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, + VK_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, VK_SHADER_STAGE_TASK_BIT_NV = 0x00000040, VK_SHADER_STAGE_MESH_BIT_NV = 0x00000080, + VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000, + VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR, + VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, + VK_SHADER_STAGE_MISS_BIT_NV = VK_SHADER_STAGE_MISS_BIT_KHR, + VK_SHADER_STAGE_INTERSECTION_BIT_NV = VK_SHADER_STAGE_INTERSECTION_BIT_KHR, + VK_SHADER_STAGE_CALLABLE_BIT_NV = VK_SHADER_STAGE_CALLABLE_BIT_KHR, VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkShaderStageFlagBits; -typedef VkFlags VkPipelineVertexInputStateCreateFlags; -typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; -typedef VkFlags VkPipelineTessellationStateCreateFlags; -typedef VkFlags VkPipelineViewportStateCreateFlags; -typedef VkFlags VkPipelineRasterizationStateCreateFlags; typedef enum VkCullModeFlagBits { VK_CULL_MODE_NONE = 0, @@ -1676,18 +2216,14 @@ typedef enum VkCullModeFlagBits { VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkCullModeFlagBits; typedef VkFlags VkCullModeFlags; +typedef VkFlags VkPipelineVertexInputStateCreateFlags; +typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; +typedef VkFlags VkPipelineTessellationStateCreateFlags; +typedef VkFlags VkPipelineViewportStateCreateFlags; +typedef VkFlags VkPipelineRasterizationStateCreateFlags; typedef VkFlags VkPipelineMultisampleStateCreateFlags; typedef VkFlags VkPipelineDepthStencilStateCreateFlags; typedef VkFlags VkPipelineColorBlendStateCreateFlags; - -typedef enum VkColorComponentFlagBits { - VK_COLOR_COMPONENT_R_BIT = 0x00000001, - VK_COLOR_COMPONENT_G_BIT = 0x00000002, - VK_COLOR_COMPONENT_B_BIT = 0x00000004, - VK_COLOR_COMPONENT_A_BIT = 0x00000008, - VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkColorComponentFlagBits; -typedef VkFlags VkColorComponentFlags; typedef VkFlags VkPipelineDynamicStateCreateFlags; typedef VkFlags VkPipelineLayoutCreateFlags; typedef VkFlags VkShaderStageFlags; @@ -1699,27 +2235,24 @@ typedef enum VkSamplerCreateFlagBits { } VkSamplerCreateFlagBits; typedef VkFlags VkSamplerCreateFlags; -typedef enum VkDescriptorSetLayoutCreateFlagBits { - VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorSetLayoutCreateFlagBits; -typedef VkFlags VkDescriptorSetLayoutCreateFlags; - typedef enum VkDescriptorPoolCreateFlagBits { VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, - VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002, + VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE = 0x00000004, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorPoolCreateFlagBits; typedef VkFlags VkDescriptorPoolCreateFlags; typedef VkFlags VkDescriptorPoolResetFlags; -typedef enum VkFramebufferCreateFlagBits { - VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = 0x00000001, - VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFramebufferCreateFlagBits; -typedef VkFlags VkFramebufferCreateFlags; -typedef VkFlags VkRenderPassCreateFlags; +typedef enum VkDescriptorSetLayoutCreateFlagBits { + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE = 0x00000004, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorSetLayoutCreateFlagBits; +typedef VkFlags VkDescriptorSetLayoutCreateFlags; typedef enum VkAttachmentDescriptionFlagBits { VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, @@ -1727,46 +2260,6 @@ typedef enum VkAttachmentDescriptionFlagBits { } VkAttachmentDescriptionFlagBits; typedef VkFlags VkAttachmentDescriptionFlags; -typedef enum VkSubpassDescriptionFlagBits { - VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, - VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, - VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSubpassDescriptionFlagBits; -typedef VkFlags VkSubpassDescriptionFlags; - -typedef enum VkAccessFlagBits { - VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, - VK_ACCESS_INDEX_READ_BIT = 0x00000002, - VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, - VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, - VK_ACCESS_SHADER_READ_BIT = 0x00000020, - VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, - VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, - VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, - VK_ACCESS_HOST_READ_BIT = 0x00002000, - VK_ACCESS_HOST_WRITE_BIT = 0x00004000, - VK_ACCESS_MEMORY_READ_BIT = 0x00008000, - VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, - VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, - VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, - VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, - VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, - VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000, - VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000, - VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, - VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000, - VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000, - VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000, - VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, - VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAccessFlagBits; -typedef VkFlags VkAccessFlags; - typedef enum VkDependencyFlagBits { VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, @@ -1777,6 +2270,28 @@ typedef enum VkDependencyFlagBits { } VkDependencyFlagBits; typedef VkFlags VkDependencyFlags; +typedef enum VkFramebufferCreateFlagBits { + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001, + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, + VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFramebufferCreateFlagBits; +typedef VkFlags VkFramebufferCreateFlags; + +typedef enum VkRenderPassCreateFlagBits { + VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM = 0x00000002, + VK_RENDER_PASS_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderPassCreateFlagBits; +typedef VkFlags VkRenderPassCreateFlags; + +typedef enum VkSubpassDescriptionFlagBits { + VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, + VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, + VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, + VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, + VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubpassDescriptionFlagBits; +typedef VkFlags VkSubpassDescriptionFlags; + typedef enum VkCommandPoolCreateFlagBits { VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, @@ -1814,30 +2329,116 @@ typedef VkFlags VkCommandBufferResetFlags; typedef enum VkStencilFaceFlagBits { VK_STENCIL_FACE_FRONT_BIT = 0x00000001, VK_STENCIL_FACE_BACK_BIT = 0x00000002, - VK_STENCIL_FRONT_AND_BACK = 0x00000003, + VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003, + VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK, VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkStencilFaceFlagBits; typedef VkFlags VkStencilFaceFlags; -typedef struct VkApplicationInfo { +typedef struct VkExtent2D { + uint32_t width; + uint32_t height; +} VkExtent2D; + +typedef struct VkExtent3D { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkExtent3D; + +typedef struct VkOffset2D { + int32_t x; + int32_t y; +} VkOffset2D; + +typedef struct VkOffset3D { + int32_t x; + int32_t y; + int32_t z; +} VkOffset3D; + +typedef struct VkRect2D { + VkOffset2D offset; + VkExtent2D extent; +} VkRect2D; + +typedef struct VkBaseInStructure { + VkStructureType sType; + const struct VkBaseInStructure* pNext; +} VkBaseInStructure; + +typedef struct VkBaseOutStructure { + VkStructureType sType; + struct VkBaseOutStructure* pNext; +} VkBaseOutStructure; + +typedef struct VkBufferMemoryBarrier { VkStructureType sType; const void* pNext; - const char* pApplicationName; - uint32_t applicationVersion; - const char* pEngineName; - uint32_t engineVersion; - uint32_t apiVersion; -} VkApplicationInfo; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier; -typedef struct VkInstanceCreateInfo { - VkStructureType sType; - const void* pNext; - VkInstanceCreateFlags flags; - const VkApplicationInfo* pApplicationInfo; - uint32_t enabledLayerCount; - const char* const* ppEnabledLayerNames; - uint32_t enabledExtensionCount; - const char* const* ppEnabledExtensionNames; -} VkInstanceCreateInfo; +typedef struct VkDispatchIndirectCommand { + uint32_t x; + uint32_t y; + uint32_t z; +} VkDispatchIndirectCommand; + +typedef struct VkDrawIndexedIndirectCommand { + uint32_t indexCount; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +} VkDrawIndexedIndirectCommand; + +typedef struct VkDrawIndirectCommand { + uint32_t vertexCount; + uint32_t instanceCount; + uint32_t firstVertex; + uint32_t firstInstance; +} VkDrawIndirectCommand; + +typedef struct VkImageSubresourceRange { + VkImageAspectFlags aspectMask; + uint32_t baseMipLevel; + uint32_t levelCount; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceRange; + +typedef struct VkImageMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier; + +typedef struct VkMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; +} VkMemoryBarrier; + +typedef struct VkPipelineCacheHeaderVersionOne { + uint32_t headerSize; + VkPipelineCacheHeaderVersion headerVersion; + uint32_t vendorID; + uint32_t deviceID; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; +} VkPipelineCacheHeaderVersionOne; typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( void* pUserData, @@ -1845,13 +2446,6 @@ typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( size_t alignment, VkSystemAllocationScope allocationScope); -typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( - void* pUserData, - void* pOriginal, - size_t size, - size_t alignment, - VkSystemAllocationScope allocationScope); - typedef void (VKAPI_PTR *PFN_vkFreeFunction)( void* pUserData, void* pMemory); @@ -1868,6 +2462,14 @@ typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope); +typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( + void* pUserData, + void* pOriginal, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); typedef struct VkAllocationCallbacks { void* pUserData; PFN_vkAllocationFunction pfnAllocation; @@ -1877,6 +2479,51 @@ typedef struct VkAllocationCallbacks { PFN_vkInternalFreeNotification pfnInternalFree; } VkAllocationCallbacks; +typedef struct VkApplicationInfo { + VkStructureType sType; + const void* pNext; + const char* pApplicationName; + uint32_t applicationVersion; + const char* pEngineName; + uint32_t engineVersion; + uint32_t apiVersion; +} VkApplicationInfo; + +typedef struct VkFormatProperties { + VkFormatFeatureFlags linearTilingFeatures; + VkFormatFeatureFlags optimalTilingFeatures; + VkFormatFeatureFlags bufferFeatures; +} VkFormatProperties; + +typedef struct VkImageFormatProperties { + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize maxResourceSize; +} VkImageFormatProperties; + +typedef struct VkInstanceCreateInfo { + VkStructureType sType; + const void* pNext; + VkInstanceCreateFlags flags; + const VkApplicationInfo* pApplicationInfo; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; +} VkInstanceCreateInfo; + +typedef struct VkMemoryHeap { + VkDeviceSize size; + VkMemoryHeapFlags flags; +} VkMemoryHeap; + +typedef struct VkMemoryType { + VkMemoryPropertyFlags propertyFlags; + uint32_t heapIndex; +} VkMemoryType; + typedef struct VkPhysicalDeviceFeatures { VkBool32 robustBufferAccess; VkBool32 fullDrawIndexUint32; @@ -1935,26 +2582,6 @@ typedef struct VkPhysicalDeviceFeatures { VkBool32 inheritedQueries; } VkPhysicalDeviceFeatures; -typedef struct VkFormatProperties { - VkFormatFeatureFlags linearTilingFeatures; - VkFormatFeatureFlags optimalTilingFeatures; - VkFormatFeatureFlags bufferFeatures; -} VkFormatProperties; - -typedef struct VkExtent3D { - uint32_t width; - uint32_t height; - uint32_t depth; -} VkExtent3D; - -typedef struct VkImageFormatProperties { - VkExtent3D maxExtent; - uint32_t maxMipLevels; - uint32_t maxArrayLayers; - VkSampleCountFlags sampleCounts; - VkDeviceSize maxResourceSize; -} VkImageFormatProperties; - typedef struct VkPhysicalDeviceLimits { uint32_t maxImageDimension1D; uint32_t maxImageDimension2D; @@ -2064,6 +2691,13 @@ typedef struct VkPhysicalDeviceLimits { VkDeviceSize nonCoherentAtomSize; } VkPhysicalDeviceLimits; +typedef struct VkPhysicalDeviceMemoryProperties { + uint32_t memoryTypeCount; + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; + uint32_t memoryHeapCount; + VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryProperties; + typedef struct VkPhysicalDeviceSparseProperties { VkBool32 residencyStandard2DBlockShape; VkBool32 residencyStandard2DMultisampleBlockShape; @@ -2091,24 +2725,6 @@ typedef struct VkQueueFamilyProperties { VkExtent3D minImageTransferGranularity; } VkQueueFamilyProperties; -typedef struct VkMemoryType { - VkMemoryPropertyFlags propertyFlags; - uint32_t heapIndex; -} VkMemoryType; - -typedef struct VkMemoryHeap { - VkDeviceSize size; - VkMemoryHeapFlags flags; -} VkMemoryHeap; - -typedef struct VkPhysicalDeviceMemoryProperties { - uint32_t memoryTypeCount; - VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; - uint32_t memoryHeapCount; - VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; -} VkPhysicalDeviceMemoryProperties; - -typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); typedef struct VkDeviceQueueCreateInfo { VkStructureType sType; const void* pNext; @@ -2155,13 +2771,6 @@ typedef struct VkSubmitInfo { const VkSemaphore* pSignalSemaphores; } VkSubmitInfo; -typedef struct VkMemoryAllocateInfo { - VkStructureType sType; - const void* pNext; - VkDeviceSize allocationSize; - uint32_t memoryTypeIndex; -} VkMemoryAllocateInfo; - typedef struct VkMappedMemoryRange { VkStructureType sType; const void* pNext; @@ -2170,26 +2779,19 @@ typedef struct VkMappedMemoryRange { VkDeviceSize size; } VkMappedMemoryRange; +typedef struct VkMemoryAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeIndex; +} VkMemoryAllocateInfo; + typedef struct VkMemoryRequirements { VkDeviceSize size; VkDeviceSize alignment; uint32_t memoryTypeBits; } VkMemoryRequirements; -typedef struct VkSparseImageFormatProperties { - VkImageAspectFlags aspectMask; - VkExtent3D imageGranularity; - VkSparseImageFormatFlags flags; -} VkSparseImageFormatProperties; - -typedef struct VkSparseImageMemoryRequirements { - VkSparseImageFormatProperties formatProperties; - uint32_t imageMipTailFirstLod; - VkDeviceSize imageMipTailSize; - VkDeviceSize imageMipTailOffset; - VkDeviceSize imageMipTailStride; -} VkSparseImageMemoryRequirements; - typedef struct VkSparseMemoryBind { VkDeviceSize resourceOffset; VkDeviceSize size; @@ -2216,12 +2818,6 @@ typedef struct VkImageSubresource { uint32_t arrayLayer; } VkImageSubresource; -typedef struct VkOffset3D { - int32_t x; - int32_t y; - int32_t z; -} VkOffset3D; - typedef struct VkSparseImageMemoryBind { VkImageSubresource subresource; VkOffset3D offset; @@ -2252,6 +2848,20 @@ typedef struct VkBindSparseInfo { const VkSemaphore* pSignalSemaphores; } VkBindSparseInfo; +typedef struct VkSparseImageFormatProperties { + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; + VkSparseImageFormatFlags flags; +} VkSparseImageFormatProperties; + +typedef struct VkSparseImageMemoryRequirements { + VkSparseImageFormatProperties formatProperties; + uint32_t imageMipTailFirstLod; + VkDeviceSize imageMipTailSize; + VkDeviceSize imageMipTailOffset; + VkDeviceSize imageMipTailStride; +} VkSparseImageMemoryRequirements; + typedef struct VkFenceCreateInfo { VkStructureType sType; const void* pNext; @@ -2333,14 +2943,6 @@ typedef struct VkComponentMapping { VkComponentSwizzle a; } VkComponentMapping; -typedef struct VkImageSubresourceRange { - VkImageAspectFlags aspectMask; - uint32_t baseMipLevel; - uint32_t levelCount; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceRange; - typedef struct VkImageViewCreateInfo { VkStructureType sType; const void* pNext; @@ -2391,6 +2993,16 @@ typedef struct VkPipelineShaderStageCreateInfo { const VkSpecializationInfo* pSpecializationInfo; } VkPipelineShaderStageCreateInfo; +typedef struct VkComputePipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + VkPipelineShaderStageCreateInfo stage; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkComputePipelineCreateInfo; + typedef struct VkVertexInputBindingDescription { uint32_t binding; uint32_t stride; @@ -2438,21 +3050,6 @@ typedef struct VkViewport { float maxDepth; } VkViewport; -typedef struct VkOffset2D { - int32_t x; - int32_t y; -} VkOffset2D; - -typedef struct VkExtent2D { - uint32_t width; - uint32_t height; -} VkExtent2D; - -typedef struct VkRect2D { - VkOffset2D offset; - VkExtent2D extent; -} VkRect2D; - typedef struct VkPipelineViewportStateCreateInfo { VkStructureType sType; const void* pNext; @@ -2568,16 +3165,6 @@ typedef struct VkGraphicsPipelineCreateInfo { int32_t basePipelineIndex; } VkGraphicsPipelineCreateInfo; -typedef struct VkComputePipelineCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags flags; - VkPipelineShaderStageCreateInfo stage; - VkPipelineLayout layout; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkComputePipelineCreateInfo; - typedef struct VkPushConstantRange { VkShaderStageFlags stageFlags; uint32_t offset; @@ -2615,21 +3202,29 @@ typedef struct VkSamplerCreateInfo { VkBool32 unnormalizedCoordinates; } VkSamplerCreateInfo; -typedef struct VkDescriptorSetLayoutBinding { - uint32_t binding; - VkDescriptorType descriptorType; - uint32_t descriptorCount; - VkShaderStageFlags stageFlags; - const VkSampler* pImmutableSamplers; -} VkDescriptorSetLayoutBinding; +typedef struct VkCopyDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet srcSet; + uint32_t srcBinding; + uint32_t srcArrayElement; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; +} VkCopyDescriptorSet; -typedef struct VkDescriptorSetLayoutCreateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorSetLayoutCreateFlags flags; - uint32_t bindingCount; - const VkDescriptorSetLayoutBinding* pBindings; -} VkDescriptorSetLayoutCreateInfo; +typedef struct VkDescriptorBufferInfo { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize range; +} VkDescriptorBufferInfo; + +typedef struct VkDescriptorImageInfo { + VkSampler sampler; + VkImageView imageView; + VkImageLayout imageLayout; +} VkDescriptorImageInfo; typedef struct VkDescriptorPoolSize { VkDescriptorType type; @@ -2653,17 +3248,21 @@ typedef struct VkDescriptorSetAllocateInfo { const VkDescriptorSetLayout* pSetLayouts; } VkDescriptorSetAllocateInfo; -typedef struct VkDescriptorImageInfo { - VkSampler sampler; - VkImageView imageView; - VkImageLayout imageLayout; -} VkDescriptorImageInfo; +typedef struct VkDescriptorSetLayoutBinding { + uint32_t binding; + VkDescriptorType descriptorType; + uint32_t descriptorCount; + VkShaderStageFlags stageFlags; + const VkSampler* pImmutableSamplers; +} VkDescriptorSetLayoutBinding; -typedef struct VkDescriptorBufferInfo { - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize range; -} VkDescriptorBufferInfo; +typedef struct VkDescriptorSetLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayoutCreateFlags flags; + uint32_t bindingCount; + const VkDescriptorSetLayoutBinding* pBindings; +} VkDescriptorSetLayoutCreateInfo; typedef struct VkWriteDescriptorSet { VkStructureType sType; @@ -2678,30 +3277,6 @@ typedef struct VkWriteDescriptorSet { const VkBufferView* pTexelBufferView; } VkWriteDescriptorSet; -typedef struct VkCopyDescriptorSet { - VkStructureType sType; - const void* pNext; - VkDescriptorSet srcSet; - uint32_t srcBinding; - uint32_t srcArrayElement; - VkDescriptorSet dstSet; - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; -} VkCopyDescriptorSet; - -typedef struct VkFramebufferCreateInfo { - VkStructureType sType; - const void* pNext; - VkFramebufferCreateFlags flags; - VkRenderPass renderPass; - uint32_t attachmentCount; - const VkImageView* pAttachments; - uint32_t width; - uint32_t height; - uint32_t layers; -} VkFramebufferCreateInfo; - typedef struct VkAttachmentDescription { VkAttachmentDescriptionFlags flags; VkFormat format; @@ -2719,6 +3294,18 @@ typedef struct VkAttachmentReference { VkImageLayout layout; } VkAttachmentReference; +typedef struct VkFramebufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkFramebufferCreateFlags flags; + VkRenderPass renderPass; + uint32_t attachmentCount; + const VkImageView* pAttachments; + uint32_t width; + uint32_t height; + uint32_t layers; +} VkFramebufferCreateInfo; + typedef struct VkSubpassDescription { VkSubpassDescriptionFlags flags; VkPipelineBindPoint pipelineBindPoint; @@ -2800,21 +3387,6 @@ typedef struct VkImageSubresourceLayers { uint32_t layerCount; } VkImageSubresourceLayers; -typedef struct VkImageCopy { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy; - -typedef struct VkImageBlit { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets[2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets[2]; -} VkImageBlit; - typedef struct VkBufferImageCopy { VkDeviceSize bufferOffset; uint32_t bufferRowLength; @@ -2852,6 +3424,21 @@ typedef struct VkClearRect { uint32_t layerCount; } VkClearRect; +typedef struct VkImageBlit { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit; + +typedef struct VkImageCopy { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy; + typedef struct VkImageResolve { VkImageSubresourceLayers srcSubresource; VkOffset3D srcOffset; @@ -2860,38 +3447,6 @@ typedef struct VkImageResolve { VkExtent3D extent; } VkImageResolve; -typedef struct VkMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; -} VkMemoryBarrier; - -typedef struct VkBufferMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier; - -typedef struct VkImageMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier; - typedef struct VkRenderPassBeginInfo { VkStructureType sType; const void* pNext; @@ -2902,37 +3457,6 @@ typedef struct VkRenderPassBeginInfo { const VkClearValue* pClearValues; } VkRenderPassBeginInfo; -typedef struct VkDispatchIndirectCommand { - uint32_t x; - uint32_t y; - uint32_t z; -} VkDispatchIndirectCommand; - -typedef struct VkDrawIndexedIndirectCommand { - uint32_t indexCount; - uint32_t instanceCount; - uint32_t firstIndex; - int32_t vertexOffset; - uint32_t firstInstance; -} VkDrawIndexedIndirectCommand; - -typedef struct VkDrawIndirectCommand { - uint32_t vertexCount; - uint32_t instanceCount; - uint32_t firstVertex; - uint32_t firstInstance; -} VkDrawIndirectCommand; - -typedef struct VkBaseOutStructure { - VkStructureType sType; - struct VkBaseOutStructure* pNext; -} VkBaseOutStructure; - -typedef struct VkBaseInStructure { - VkStructureType sType; - const struct VkBaseInStructure* pNext; -} VkBaseInStructure; - typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); @@ -3873,22 +4397,19 @@ VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( #define VK_VERSION_1_1 1 // Vulkan 1.1 version number -#define VK_API_VERSION_1_1 VK_MAKE_VERSION(1, 1, 0)// Patch version should always be set to 0 +#define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)// Patch version should always be set to 0 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) -#define VK_MAX_DEVICE_GROUP_SIZE 32 -#define VK_LUID_SIZE 8 -#define VK_QUEUE_FAMILY_EXTERNAL (~0U-1) +#define VK_MAX_DEVICE_GROUP_SIZE 32U +#define VK_LUID_SIZE 8U +#define VK_QUEUE_FAMILY_EXTERNAL (~1U) typedef enum VkPointClippingBehavior { VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0, VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, - VK_POINT_CLIPPING_BEHAVIOR_BEGIN_RANGE = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, - VK_POINT_CLIPPING_BEHAVIOR_END_RANGE = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, - VK_POINT_CLIPPING_BEHAVIOR_RANGE_SIZE = (VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES + 1), VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF } VkPointClippingBehavior; @@ -3897,9 +4418,6 @@ typedef enum VkTessellationDomainOrigin { VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_BEGIN_RANGE = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_END_RANGE = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_RANGE_SIZE = (VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT + 1), VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF } VkTessellationDomainOrigin; @@ -3914,9 +4432,6 @@ typedef enum VkSamplerYcbcrModelConversion { VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709, VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601, VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_BEGIN_RANGE = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_END_RANGE = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RANGE_SIZE = (VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + 1), VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF } VkSamplerYcbcrModelConversion; @@ -3925,9 +4440,6 @@ typedef enum VkSamplerYcbcrRange { VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, - VK_SAMPLER_YCBCR_RANGE_BEGIN_RANGE = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, - VK_SAMPLER_YCBCR_RANGE_END_RANGE = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, - VK_SAMPLER_YCBCR_RANGE_RANGE_SIZE = (VK_SAMPLER_YCBCR_RANGE_ITU_NARROW - VK_SAMPLER_YCBCR_RANGE_ITU_FULL + 1), VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF } VkSamplerYcbcrRange; @@ -3936,9 +4448,6 @@ typedef enum VkChromaLocation { VK_CHROMA_LOCATION_MIDPOINT = 1, VK_CHROMA_LOCATION_COSITED_EVEN_KHR = VK_CHROMA_LOCATION_COSITED_EVEN, VK_CHROMA_LOCATION_MIDPOINT_KHR = VK_CHROMA_LOCATION_MIDPOINT, - VK_CHROMA_LOCATION_BEGIN_RANGE = VK_CHROMA_LOCATION_COSITED_EVEN, - VK_CHROMA_LOCATION_END_RANGE = VK_CHROMA_LOCATION_MIDPOINT, - VK_CHROMA_LOCATION_RANGE_SIZE = (VK_CHROMA_LOCATION_MIDPOINT - VK_CHROMA_LOCATION_COSITED_EVEN + 1), VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF } VkChromaLocation; @@ -3946,9 +4455,6 @@ typedef enum VkDescriptorUpdateTemplateType { VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_END_RANGE = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET + 1), VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorUpdateTemplateType; @@ -3981,7 +4487,11 @@ typedef VkFlags VkPeerMemoryFeatureFlags; typedef enum VkMemoryAllocateFlagBits { VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004, VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkMemoryAllocateFlagBits; typedef VkFlags VkMemoryAllocateFlags; @@ -4000,6 +4510,8 @@ typedef enum VkExternalMemoryHandleTypeFlagBits { VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID = 0x00000400, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, @@ -4064,6 +4576,8 @@ typedef enum VkExternalSemaphoreHandleTypeFlagBits { VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 0x00000008, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000010, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA = 0x00000080, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, @@ -4223,8 +4737,6 @@ typedef struct VkMemoryRequirements2 { VkMemoryRequirements memoryRequirements; } VkMemoryRequirements2; -typedef VkMemoryRequirements2 VkMemoryRequirements2KHR; - typedef struct VkSparseImageMemoryRequirements2 { VkStructureType sType; void* pNext; @@ -4748,11 +5260,767 @@ VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport( #endif +#define VK_VERSION_1_2 1 +// Vulkan 1.2 version number +#define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0)// Patch version should always be set to 0 + +#define VK_MAX_DRIVER_NAME_SIZE 256U +#define VK_MAX_DRIVER_INFO_SIZE 256U + +typedef enum VkDriverId { + VK_DRIVER_ID_AMD_PROPRIETARY = 1, + VK_DRIVER_ID_AMD_OPEN_SOURCE = 2, + VK_DRIVER_ID_MESA_RADV = 3, + VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8, + VK_DRIVER_ID_ARM_PROPRIETARY = 9, + VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10, + VK_DRIVER_ID_GGP_PROPRIETARY = 11, + VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12, + VK_DRIVER_ID_MESA_LLVMPIPE = 13, + VK_DRIVER_ID_MOLTENVK = 14, + VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, + VK_DRIVER_ID_JUICE_PROPRIETARY = 16, + VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17, + VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, + VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, + VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, + VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY, + VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY, + VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER, + VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY, + VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY, + VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF +} VkDriverId; + +typedef enum VkShaderFloatControlsIndependence { + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF +} VkShaderFloatControlsIndependence; + +typedef enum VkSamplerReductionMode { + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0, + VK_SAMPLER_REDUCTION_MODE_MIN = 1, + VK_SAMPLER_REDUCTION_MODE_MAX = 2, + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, + VK_SAMPLER_REDUCTION_MODE_MIN_EXT = VK_SAMPLER_REDUCTION_MODE_MIN, + VK_SAMPLER_REDUCTION_MODE_MAX_EXT = VK_SAMPLER_REDUCTION_MODE_MAX, + VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerReductionMode; + +typedef enum VkSemaphoreType { + VK_SEMAPHORE_TYPE_BINARY = 0, + VK_SEMAPHORE_TYPE_TIMELINE = 1, + VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY, + VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE, + VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreType; + +typedef enum VkResolveModeFlagBits { + VK_RESOLVE_MODE_NONE = 0, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001, + VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002, + VK_RESOLVE_MODE_MIN_BIT = 0x00000004, + VK_RESOLVE_MODE_MAX_BIT = 0x00000008, + VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT, + VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT, + VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT, + VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkResolveModeFlagBits; +typedef VkFlags VkResolveModeFlags; + +typedef enum VkDescriptorBindingFlagBits { + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008, + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, + VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorBindingFlagBits; +typedef VkFlags VkDescriptorBindingFlags; + +typedef enum VkSemaphoreWaitFlagBits { + VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001, + VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT, + VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreWaitFlagBits; +typedef VkFlags VkSemaphoreWaitFlags; +typedef struct VkPhysicalDeviceVulkan11Features { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; + VkBool32 protectedMemory; + VkBool32 samplerYcbcrConversion; + VkBool32 shaderDrawParameters; +} VkPhysicalDeviceVulkan11Features; + +typedef struct VkPhysicalDeviceVulkan11Properties { + VkStructureType sType; + void* pNext; + uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint8_t deviceLUID[VK_LUID_SIZE]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; + uint32_t subgroupSize; + VkShaderStageFlags subgroupSupportedStages; + VkSubgroupFeatureFlags subgroupSupportedOperations; + VkBool32 subgroupQuadOperationsInAllStages; + VkPointClippingBehavior pointClippingBehavior; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; + VkBool32 protectedNoFault; + uint32_t maxPerSetDescriptors; + VkDeviceSize maxMemoryAllocationSize; +} VkPhysicalDeviceVulkan11Properties; + +typedef struct VkPhysicalDeviceVulkan12Features { + VkStructureType sType; + void* pNext; + VkBool32 samplerMirrorClampToEdge; + VkBool32 drawIndirectCount; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; + VkBool32 descriptorIndexing; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; + VkBool32 samplerFilterMinmax; + VkBool32 scalarBlockLayout; + VkBool32 imagelessFramebuffer; + VkBool32 uniformBufferStandardLayout; + VkBool32 shaderSubgroupExtendedTypes; + VkBool32 separateDepthStencilLayouts; + VkBool32 hostQueryReset; + VkBool32 timelineSemaphore; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; + VkBool32 shaderOutputViewportIndex; + VkBool32 shaderOutputLayer; + VkBool32 subgroupBroadcastDynamicId; +} VkPhysicalDeviceVulkan12Features; + +typedef struct VkConformanceVersion { + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t patch; +} VkConformanceVersion; + +typedef struct VkPhysicalDeviceVulkan12Properties { + VkStructureType sType; + void* pNext; + VkDriverId driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; + VkConformanceVersion conformanceVersion; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; + uint64_t maxTimelineSemaphoreValueDifference; + VkSampleCountFlags framebufferIntegerColorSampleCounts; +} VkPhysicalDeviceVulkan12Properties; + +typedef struct VkImageFormatListCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkImageFormatListCreateInfo; + +typedef struct VkAttachmentDescription2 { + VkStructureType sType; + const void* pNext; + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription2; + +typedef struct VkAttachmentReference2 { + VkStructureType sType; + const void* pNext; + uint32_t attachment; + VkImageLayout layout; + VkImageAspectFlags aspectMask; +} VkAttachmentReference2; + +typedef struct VkSubpassDescription2 { + VkStructureType sType; + const void* pNext; + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t viewMask; + uint32_t inputAttachmentCount; + const VkAttachmentReference2* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference2* pColorAttachments; + const VkAttachmentReference2* pResolveAttachments; + const VkAttachmentReference2* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription2; + +typedef struct VkSubpassDependency2 { + VkStructureType sType; + const void* pNext; + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; + int32_t viewOffset; +} VkSubpassDependency2; + +typedef struct VkRenderPassCreateInfo2 { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription2* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription2* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency2* pDependencies; + uint32_t correlatedViewMaskCount; + const uint32_t* pCorrelatedViewMasks; +} VkRenderPassCreateInfo2; + +typedef struct VkSubpassBeginInfo { + VkStructureType sType; + const void* pNext; + VkSubpassContents contents; +} VkSubpassBeginInfo; + +typedef struct VkSubpassEndInfo { + VkStructureType sType; + const void* pNext; +} VkSubpassEndInfo; + +typedef struct VkPhysicalDevice8BitStorageFeatures { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; +} VkPhysicalDevice8BitStorageFeatures; + +typedef struct VkPhysicalDeviceDriverProperties { + VkStructureType sType; + void* pNext; + VkDriverId driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; + VkConformanceVersion conformanceVersion; +} VkPhysicalDeviceDriverProperties; + +typedef struct VkPhysicalDeviceShaderAtomicInt64Features { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; +} VkPhysicalDeviceShaderAtomicInt64Features; + +typedef struct VkPhysicalDeviceShaderFloat16Int8Features { + VkStructureType sType; + void* pNext; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; +} VkPhysicalDeviceShaderFloat16Int8Features; + +typedef struct VkPhysicalDeviceFloatControlsProperties { + VkStructureType sType; + void* pNext; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; +} VkPhysicalDeviceFloatControlsProperties; + +typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t bindingCount; + const VkDescriptorBindingFlags* pBindingFlags; +} VkDescriptorSetLayoutBindingFlagsCreateInfo; + +typedef struct VkPhysicalDeviceDescriptorIndexingFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; +} VkPhysicalDeviceDescriptorIndexingFeatures; + +typedef struct VkPhysicalDeviceDescriptorIndexingProperties { + VkStructureType sType; + void* pNext; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; +} VkPhysicalDeviceDescriptorIndexingProperties; + +typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo { + VkStructureType sType; + const void* pNext; + uint32_t descriptorSetCount; + const uint32_t* pDescriptorCounts; +} VkDescriptorSetVariableDescriptorCountAllocateInfo; + +typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport { + VkStructureType sType; + void* pNext; + uint32_t maxVariableDescriptorCount; +} VkDescriptorSetVariableDescriptorCountLayoutSupport; + +typedef struct VkSubpassDescriptionDepthStencilResolve { + VkStructureType sType; + const void* pNext; + VkResolveModeFlagBits depthResolveMode; + VkResolveModeFlagBits stencilResolveMode; + const VkAttachmentReference2* pDepthStencilResolveAttachment; +} VkSubpassDescriptionDepthStencilResolve; + +typedef struct VkPhysicalDeviceDepthStencilResolveProperties { + VkStructureType sType; + void* pNext; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; +} VkPhysicalDeviceDepthStencilResolveProperties; + +typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 scalarBlockLayout; +} VkPhysicalDeviceScalarBlockLayoutFeatures; + +typedef struct VkImageStencilUsageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageUsageFlags stencilUsage; +} VkImageStencilUsageCreateInfo; + +typedef struct VkSamplerReductionModeCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerReductionMode reductionMode; +} VkSamplerReductionModeCreateInfo; + +typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { + VkStructureType sType; + void* pNext; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; +} VkPhysicalDeviceSamplerFilterMinmaxProperties; + +typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { + VkStructureType sType; + void* pNext; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; +} VkPhysicalDeviceVulkanMemoryModelFeatures; + +typedef struct VkPhysicalDeviceImagelessFramebufferFeatures { + VkStructureType sType; + void* pNext; + VkBool32 imagelessFramebuffer; +} VkPhysicalDeviceImagelessFramebufferFeatures; + +typedef struct VkFramebufferAttachmentImageInfo { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageUsageFlags usage; + uint32_t width; + uint32_t height; + uint32_t layerCount; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkFramebufferAttachmentImageInfo; + +typedef struct VkFramebufferAttachmentsCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos; +} VkFramebufferAttachmentsCreateInfo; + +typedef struct VkRenderPassAttachmentBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t attachmentCount; + const VkImageView* pAttachments; +} VkRenderPassAttachmentBeginInfo; + +typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 uniformBufferStandardLayout; +} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; + +typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupExtendedTypes; +} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; + +typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures { + VkStructureType sType; + void* pNext; + VkBool32 separateDepthStencilLayouts; +} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures; + +typedef struct VkAttachmentReferenceStencilLayout { + VkStructureType sType; + void* pNext; + VkImageLayout stencilLayout; +} VkAttachmentReferenceStencilLayout; + +typedef struct VkAttachmentDescriptionStencilLayout { + VkStructureType sType; + void* pNext; + VkImageLayout stencilInitialLayout; + VkImageLayout stencilFinalLayout; +} VkAttachmentDescriptionStencilLayout; + +typedef struct VkPhysicalDeviceHostQueryResetFeatures { + VkStructureType sType; + void* pNext; + VkBool32 hostQueryReset; +} VkPhysicalDeviceHostQueryResetFeatures; + +typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { + VkStructureType sType; + void* pNext; + VkBool32 timelineSemaphore; +} VkPhysicalDeviceTimelineSemaphoreFeatures; + +typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { + VkStructureType sType; + void* pNext; + uint64_t maxTimelineSemaphoreValueDifference; +} VkPhysicalDeviceTimelineSemaphoreProperties; + +typedef struct VkSemaphoreTypeCreateInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreType semaphoreType; + uint64_t initialValue; +} VkSemaphoreTypeCreateInfo; + +typedef struct VkTimelineSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreValueCount; + const uint64_t* pWaitSemaphoreValues; + uint32_t signalSemaphoreValueCount; + const uint64_t* pSignalSemaphoreValues; +} VkTimelineSemaphoreSubmitInfo; + +typedef struct VkSemaphoreWaitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreWaitFlags flags; + uint32_t semaphoreCount; + const VkSemaphore* pSemaphores; + const uint64_t* pValues; +} VkSemaphoreWaitInfo; + +typedef struct VkSemaphoreSignalInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; +} VkSemaphoreSignalInfo; + +typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { + VkStructureType sType; + void* pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferDeviceAddressFeatures; + +typedef struct VkBufferDeviceAddressInfo { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferDeviceAddressInfo; + +typedef struct VkBufferOpaqueCaptureAddressCreateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkBufferOpaqueCaptureAddressCreateInfo; + +typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkMemoryOpaqueCaptureAddressAllocateInfo; + +typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; +} VkDeviceMemoryOpaqueCaptureAddressInfo; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); +typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2( + VkDevice device, + const VkRenderPassCreateInfo2* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfo* pSubpassBeginInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2( + VkCommandBuffer commandBuffer, + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2( + VkCommandBuffer commandBuffer, + const VkSubpassEndInfo* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkResetQueryPool( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue( + VkDevice device, + VkSemaphore semaphore, + uint64_t* pValue); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores( + VkDevice device, + const VkSemaphoreWaitInfo* pWaitInfo, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore( + VkDevice device, + const VkSemaphoreSignalInfo* pSignalInfo); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( + VkDevice device, + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); +#endif + + #define VK_KHR_surface 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) #define VK_KHR_SURFACE_SPEC_VERSION 25 #define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" +typedef enum VkPresentModeKHR { + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, + VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, + VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPresentModeKHR; + typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, @@ -4772,25 +6040,9 @@ typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000, VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, - VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1), VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF } VkColorSpaceKHR; -typedef enum VkPresentModeKHR { - VK_PRESENT_MODE_IMMEDIATE_KHR = 0, - VK_PRESENT_MODE_MAILBOX_KHR = 1, - VK_PRESENT_MODE_FIFO_KHR = 2, - VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, - VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, - VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, - VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR, - VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_RELAXED_KHR, - VK_PRESENT_MODE_RANGE_SIZE_KHR = (VK_PRESENT_MODE_FIFO_RELAXED_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1), - VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPresentModeKHR; - typedef enum VkSurfaceTransformFlagBitsKHR { VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, @@ -4803,7 +6055,6 @@ typedef enum VkSurfaceTransformFlagBitsKHR { VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSurfaceTransformFlagBitsKHR; -typedef VkFlags VkSurfaceTransformFlagsKHR; typedef enum VkCompositeAlphaFlagBitsKHR { VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, @@ -4813,6 +6064,7 @@ typedef enum VkCompositeAlphaFlagBitsKHR { VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkCompositeAlphaFlagBitsKHR; typedef VkFlags VkCompositeAlphaFlagsKHR; +typedef VkFlags VkSurfaceTransformFlagsKHR; typedef struct VkSurfaceCapabilitiesKHR { uint32_t minImageCount; uint32_t maxImageCount; @@ -4946,7 +6198,7 @@ typedef struct VkAcquireNextImageInfoKHR { typedef struct VkDeviceGroupPresentCapabilitiesKHR { VkStructureType sType; - const void* pNext; + void* pNext; uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE]; VkDeviceGroupPresentModeFlagsKHR modes; } VkDeviceGroupPresentCapabilitiesKHR; @@ -5030,8 +6282,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR( #define VK_KHR_display 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) -#define VK_KHR_DISPLAY_SPEC_VERSION 21 +#define VK_KHR_DISPLAY_SPEC_VERSION 23 #define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display" +typedef VkFlags VkDisplayModeCreateFlagsKHR; typedef enum VkDisplayPlaneAlphaFlagBitsKHR { VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, @@ -5041,28 +6294,12 @@ typedef enum VkDisplayPlaneAlphaFlagBitsKHR { VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkDisplayPlaneAlphaFlagBitsKHR; typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; -typedef VkFlags VkDisplayModeCreateFlagsKHR; typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; -typedef struct VkDisplayPropertiesKHR { - VkDisplayKHR display; - const char* displayName; - VkExtent2D physicalDimensions; - VkExtent2D physicalResolution; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkBool32 planeReorderPossible; - VkBool32 persistentContent; -} VkDisplayPropertiesKHR; - typedef struct VkDisplayModeParametersKHR { VkExtent2D visibleRegion; uint32_t refreshRate; } VkDisplayModeParametersKHR; -typedef struct VkDisplayModePropertiesKHR { - VkDisplayModeKHR displayMode; - VkDisplayModeParametersKHR parameters; -} VkDisplayModePropertiesKHR; - typedef struct VkDisplayModeCreateInfoKHR { VkStructureType sType; const void* pNext; @@ -5070,6 +6307,11 @@ typedef struct VkDisplayModeCreateInfoKHR { VkDisplayModeParametersKHR parameters; } VkDisplayModeCreateInfoKHR; +typedef struct VkDisplayModePropertiesKHR { + VkDisplayModeKHR displayMode; + VkDisplayModeParametersKHR parameters; +} VkDisplayModePropertiesKHR; + typedef struct VkDisplayPlaneCapabilitiesKHR { VkDisplayPlaneAlphaFlagsKHR supportedAlpha; VkOffset2D minSrcPosition; @@ -5087,6 +6329,16 @@ typedef struct VkDisplayPlanePropertiesKHR { uint32_t currentStackIndex; } VkDisplayPlanePropertiesKHR; +typedef struct VkDisplayPropertiesKHR { + VkDisplayKHR display; + const char* displayName; + VkExtent2D physicalDimensions; + VkExtent2D physicalResolution; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkBool32 planeReorderPossible; + VkBool32 persistentContent; +} VkDisplayPropertiesKHR; + typedef struct VkDisplaySurfaceCreateInfoKHR { VkStructureType sType; const void* pNext; @@ -5153,7 +6405,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( #define VK_KHR_display_swapchain 1 -#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 9 +#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 10 #define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain" typedef struct VkDisplayPresentInfoKHR { VkStructureType sType; @@ -5176,7 +6428,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( #define VK_KHR_sampler_mirror_clamp_to_edge 1 -#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 3 #define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" @@ -5192,7 +6444,7 @@ typedef VkPhysicalDeviceMultiviewProperties VkPhysicalDeviceMultiviewPropertiesK #define VK_KHR_get_physical_device_properties2 1 -#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 1 +#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 2 #define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2" typedef VkPhysicalDeviceFeatures2 VkPhysicalDeviceFeatures2KHR; @@ -5257,7 +6509,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR( #define VK_KHR_device_group 1 -#define VK_KHR_DEVICE_GROUP_SPEC_VERSION 3 +#define VK_KHR_DEVICE_GROUP_SPEC_VERSION 4 #define VK_KHR_DEVICE_GROUP_EXTENSION_NAME "VK_KHR_device_group" typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR; @@ -5535,12 +6787,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( #define VK_KHR_shader_float16_int8 1 #define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1 #define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8" -typedef struct VkPhysicalDeviceFloat16Int8FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderFloat16; - VkBool32 shaderInt8; -} VkPhysicalDeviceFloat16Int8FeaturesKHR; +typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceShaderFloat16Int8FeaturesKHR; + +typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceFloat16Int8FeaturesKHR; @@ -5552,7 +6801,7 @@ typedef VkPhysicalDevice16BitStorageFeatures VkPhysicalDevice16BitStorageFeature #define VK_KHR_incremental_present 1 -#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1 +#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 2 #define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" typedef struct VkRectLayerKHR { VkOffset2D offset; @@ -5614,144 +6863,58 @@ VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( #define VK_KHR_imageless_framebuffer 1 #define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1 #define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer" -typedef struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 imagelessFramebuffer; -} VkPhysicalDeviceImagelessFramebufferFeaturesKHR; +typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR; -typedef struct VkFramebufferAttachmentImageInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageCreateFlags flags; - VkImageUsageFlags usage; - uint32_t width; - uint32_t height; - uint32_t layerCount; - uint32_t viewFormatCount; - const VkFormat* pViewFormats; -} VkFramebufferAttachmentImageInfoKHR; +typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR; -typedef struct VkFramebufferAttachmentsCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t attachmentImageInfoCount; - const VkFramebufferAttachmentImageInfoKHR* pAttachmentImageInfos; -} VkFramebufferAttachmentsCreateInfoKHR; +typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR; -typedef struct VkRenderPassAttachmentBeginInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t attachmentCount; - const VkImageView* pAttachments; -} VkRenderPassAttachmentBeginInfoKHR; +typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR; #define VK_KHR_create_renderpass2 1 #define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 #define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2" -typedef struct VkAttachmentDescription2KHR { - VkStructureType sType; - const void* pNext; - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription2KHR; +typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR; -typedef struct VkAttachmentReference2KHR { - VkStructureType sType; - const void* pNext; - uint32_t attachment; - VkImageLayout layout; - VkImageAspectFlags aspectMask; -} VkAttachmentReference2KHR; +typedef VkAttachmentDescription2 VkAttachmentDescription2KHR; -typedef struct VkSubpassDescription2KHR { - VkStructureType sType; - const void* pNext; - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t viewMask; - uint32_t inputAttachmentCount; - const VkAttachmentReference2KHR* pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference2KHR* pColorAttachments; - const VkAttachmentReference2KHR* pResolveAttachments; - const VkAttachmentReference2KHR* pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t* pPreserveAttachments; -} VkSubpassDescription2KHR; +typedef VkAttachmentReference2 VkAttachmentReference2KHR; -typedef struct VkSubpassDependency2KHR { - VkStructureType sType; - const void* pNext; - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; - int32_t viewOffset; -} VkSubpassDependency2KHR; +typedef VkSubpassDescription2 VkSubpassDescription2KHR; -typedef struct VkRenderPassCreateInfo2KHR { - VkStructureType sType; - const void* pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription2KHR* pAttachments; - uint32_t subpassCount; - const VkSubpassDescription2KHR* pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency2KHR* pDependencies; - uint32_t correlatedViewMaskCount; - const uint32_t* pCorrelatedViewMasks; -} VkRenderPassCreateInfo2KHR; +typedef VkSubpassDependency2 VkSubpassDependency2KHR; -typedef struct VkSubpassBeginInfoKHR { - VkStructureType sType; - const void* pNext; - VkSubpassContents contents; -} VkSubpassBeginInfoKHR; +typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR; -typedef struct VkSubpassEndInfoKHR { - VkStructureType sType; - const void* pNext; -} VkSubpassEndInfoKHR; +typedef VkSubpassEndInfo VkSubpassEndInfoKHR; -typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo); -typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR( VkDevice device, - const VkRenderPassCreateInfo2KHR* pCreateInfo, + const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR( VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, - const VkSubpassBeginInfoKHR* pSubpassBeginInfo); + const VkSubpassBeginInfo* pSubpassBeginInfo); VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR( VkCommandBuffer commandBuffer, - const VkSubpassBeginInfoKHR* pSubpassBeginInfo, - const VkSubpassEndInfoKHR* pSubpassEndInfo); + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo); VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR( VkCommandBuffer commandBuffer, - const VkSubpassEndInfoKHR* pSubpassEndInfo); + const VkSubpassEndInfo* pSubpassEndInfo); #endif @@ -5843,6 +7006,146 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR( #endif +#define VK_KHR_performance_query 1 +#define VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION 1 +#define VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME "VK_KHR_performance_query" + +typedef enum VkPerformanceCounterUnitKHR { + VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR = 0, + VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR = 1, + VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR = 2, + VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR = 3, + VK_PERFORMANCE_COUNTER_UNIT_BYTES_PER_SECOND_KHR = 4, + VK_PERFORMANCE_COUNTER_UNIT_KELVIN_KHR = 5, + VK_PERFORMANCE_COUNTER_UNIT_WATTS_KHR = 6, + VK_PERFORMANCE_COUNTER_UNIT_VOLTS_KHR = 7, + VK_PERFORMANCE_COUNTER_UNIT_AMPS_KHR = 8, + VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR = 9, + VK_PERFORMANCE_COUNTER_UNIT_CYCLES_KHR = 10, + VK_PERFORMANCE_COUNTER_UNIT_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterUnitKHR; + +typedef enum VkPerformanceCounterScopeKHR { + VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0, + VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1, + VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2, + VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR, + VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR, + VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR, + VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterScopeKHR; + +typedef enum VkPerformanceCounterStorageKHR { + VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR = 0, + VK_PERFORMANCE_COUNTER_STORAGE_INT64_KHR = 1, + VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR = 2, + VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR = 3, + VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR = 4, + VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR = 5, + VK_PERFORMANCE_COUNTER_STORAGE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterStorageKHR; + +typedef enum VkPerformanceCounterDescriptionFlagBitsKHR { + VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR = 0x00000001, + VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR = 0x00000002, + VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR, + VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR, + VK_PERFORMANCE_COUNTER_DESCRIPTION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterDescriptionFlagBitsKHR; +typedef VkFlags VkPerformanceCounterDescriptionFlagsKHR; + +typedef enum VkAcquireProfilingLockFlagBitsKHR { + VK_ACQUIRE_PROFILING_LOCK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAcquireProfilingLockFlagBitsKHR; +typedef VkFlags VkAcquireProfilingLockFlagsKHR; +typedef struct VkPhysicalDevicePerformanceQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 performanceCounterQueryPools; + VkBool32 performanceCounterMultipleQueryPools; +} VkPhysicalDevicePerformanceQueryFeaturesKHR; + +typedef struct VkPhysicalDevicePerformanceQueryPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 allowCommandBufferQueryCopies; +} VkPhysicalDevicePerformanceQueryPropertiesKHR; + +typedef struct VkPerformanceCounterKHR { + VkStructureType sType; + void* pNext; + VkPerformanceCounterUnitKHR unit; + VkPerformanceCounterScopeKHR scope; + VkPerformanceCounterStorageKHR storage; + uint8_t uuid[VK_UUID_SIZE]; +} VkPerformanceCounterKHR; + +typedef struct VkPerformanceCounterDescriptionKHR { + VkStructureType sType; + void* pNext; + VkPerformanceCounterDescriptionFlagsKHR flags; + char name[VK_MAX_DESCRIPTION_SIZE]; + char category[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkPerformanceCounterDescriptionKHR; + +typedef struct VkQueryPoolPerformanceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t queueFamilyIndex; + uint32_t counterIndexCount; + const uint32_t* pCounterIndices; +} VkQueryPoolPerformanceCreateInfoKHR; + +typedef union VkPerformanceCounterResultKHR { + int32_t int32; + int64_t int64; + uint32_t uint32; + uint64_t uint64; + float float32; + double float64; +} VkPerformanceCounterResultKHR; + +typedef struct VkAcquireProfilingLockInfoKHR { + VkStructureType sType; + const void* pNext; + VkAcquireProfilingLockFlagsKHR flags; + uint64_t timeout; +} VkAcquireProfilingLockInfoKHR; + +typedef struct VkPerformanceQuerySubmitInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t counterPassIndex; +} VkPerformanceQuerySubmitInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterKHR* pCounters, VkPerformanceCounterDescriptionKHR* pCounterDescriptions); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)(VkPhysicalDevice physicalDevice, const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, uint32_t* pNumPasses); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireProfilingLockKHR)(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkReleaseProfilingLockKHR)(VkDevice device); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + uint32_t* pCounterCount, + VkPerformanceCounterKHR* pCounters, + VkPerformanceCounterDescriptionKHR* pCounterDescriptions); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( + VkPhysicalDevice physicalDevice, + const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, + uint32_t* pNumPasses); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireProfilingLockKHR( + VkDevice device, + const VkAcquireProfilingLockInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR( + VkDevice device); +#endif + + #define VK_KHR_maintenance2 1 #define VK_KHR_MAINTENANCE2_SPEC_VERSION 1 #define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2" @@ -6000,6 +7303,8 @@ typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequirementsInfo2KHR; typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR; +typedef VkMemoryRequirements2 VkMemoryRequirements2KHR; + typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR; typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); @@ -6028,19 +7333,14 @@ VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR( #define VK_KHR_image_format_list 1 #define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1 #define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list" -typedef struct VkImageFormatListCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t viewFormatCount; - const VkFormat* pViewFormats; -} VkImageFormatListCreateInfoKHR; +typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR; #define VK_KHR_sampler_ycbcr_conversion 1 typedef VkSamplerYcbcrConversion VkSamplerYcbcrConversionKHR; -#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 1 +#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 14 #define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion" typedef VkSamplerYcbcrModelConversion VkSamplerYcbcrModelConversionKHR; @@ -6144,129 +7444,71 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR( #endif +#define VK_KHR_shader_subgroup_extended_types 1 +#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1 +#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types" +typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR; + + + #define VK_KHR_8bit_storage 1 #define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1 #define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage" -typedef struct VkPhysicalDevice8BitStorageFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 storageBuffer8BitAccess; - VkBool32 uniformAndStorageBuffer8BitAccess; - VkBool32 storagePushConstant8; -} VkPhysicalDevice8BitStorageFeaturesKHR; +typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR; #define VK_KHR_shader_atomic_int64 1 #define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1 #define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64" -typedef struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR { +typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; + + + +#define VK_KHR_shader_clock 1 +#define VK_KHR_SHADER_CLOCK_SPEC_VERSION 1 +#define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock" +typedef struct VkPhysicalDeviceShaderClockFeaturesKHR { VkStructureType sType; void* pNext; - VkBool32 shaderBufferInt64Atomics; - VkBool32 shaderSharedInt64Atomics; -} VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; + VkBool32 shaderSubgroupClock; + VkBool32 shaderDeviceClock; +} VkPhysicalDeviceShaderClockFeaturesKHR; #define VK_KHR_driver_properties 1 -#define VK_MAX_DRIVER_NAME_SIZE_KHR 256 -#define VK_MAX_DRIVER_INFO_SIZE_KHR 256 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 #define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" +#define VK_MAX_DRIVER_NAME_SIZE_KHR VK_MAX_DRIVER_NAME_SIZE +#define VK_MAX_DRIVER_INFO_SIZE_KHR VK_MAX_DRIVER_INFO_SIZE +typedef VkDriverId VkDriverIdKHR; -typedef enum VkDriverIdKHR { - VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1, - VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2, - VK_DRIVER_ID_MESA_RADV_KHR = 3, - VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4, - VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5, - VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6, - VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7, - VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8, - VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9, - VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = 10, - VK_DRIVER_ID_GGP_PROPRIETARY_KHR = 11, - VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = 12, - VK_DRIVER_ID_BEGIN_RANGE_KHR = VK_DRIVER_ID_AMD_PROPRIETARY_KHR, - VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR, - VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1), - VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF -} VkDriverIdKHR; -typedef struct VkConformanceVersionKHR { - uint8_t major; - uint8_t minor; - uint8_t subminor; - uint8_t patch; -} VkConformanceVersionKHR; +typedef VkConformanceVersion VkConformanceVersionKHR; -typedef struct VkPhysicalDeviceDriverPropertiesKHR { - VkStructureType sType; - void* pNext; - VkDriverIdKHR driverID; - char driverName[VK_MAX_DRIVER_NAME_SIZE_KHR]; - char driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR]; - VkConformanceVersionKHR conformanceVersion; -} VkPhysicalDeviceDriverPropertiesKHR; +typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR; #define VK_KHR_shader_float_controls 1 -#define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 1 +#define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4 #define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls" -typedef struct VkPhysicalDeviceFloatControlsPropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 separateDenormSettings; - VkBool32 separateRoundingModeSettings; - VkBool32 shaderSignedZeroInfNanPreserveFloat16; - VkBool32 shaderSignedZeroInfNanPreserveFloat32; - VkBool32 shaderSignedZeroInfNanPreserveFloat64; - VkBool32 shaderDenormPreserveFloat16; - VkBool32 shaderDenormPreserveFloat32; - VkBool32 shaderDenormPreserveFloat64; - VkBool32 shaderDenormFlushToZeroFloat16; - VkBool32 shaderDenormFlushToZeroFloat32; - VkBool32 shaderDenormFlushToZeroFloat64; - VkBool32 shaderRoundingModeRTEFloat16; - VkBool32 shaderRoundingModeRTEFloat32; - VkBool32 shaderRoundingModeRTEFloat64; - VkBool32 shaderRoundingModeRTZFloat16; - VkBool32 shaderRoundingModeRTZFloat32; - VkBool32 shaderRoundingModeRTZFloat64; -} VkPhysicalDeviceFloatControlsPropertiesKHR; +typedef VkShaderFloatControlsIndependence VkShaderFloatControlsIndependenceKHR; + +typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR; #define VK_KHR_depth_stencil_resolve 1 #define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1 #define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve" +typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR; -typedef enum VkResolveModeFlagBitsKHR { - VK_RESOLVE_MODE_NONE_KHR = 0, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = 0x00000001, - VK_RESOLVE_MODE_AVERAGE_BIT_KHR = 0x00000002, - VK_RESOLVE_MODE_MIN_BIT_KHR = 0x00000004, - VK_RESOLVE_MODE_MAX_BIT_KHR = 0x00000008, - VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkResolveModeFlagBitsKHR; -typedef VkFlags VkResolveModeFlagsKHR; -typedef struct VkSubpassDescriptionDepthStencilResolveKHR { - VkStructureType sType; - const void* pNext; - VkResolveModeFlagBitsKHR depthResolveMode; - VkResolveModeFlagBitsKHR stencilResolveMode; - const VkAttachmentReference2KHR* pDepthStencilResolveAttachment; -} VkSubpassDescriptionDepthStencilResolveKHR; +typedef VkResolveModeFlags VkResolveModeFlagsKHR; -typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR { - VkStructureType sType; - void* pNext; - VkResolveModeFlagsKHR supportedDepthResolveModes; - VkResolveModeFlagsKHR supportedStencilResolveModes; - VkBool32 independentResolveNone; - VkBool32 independentResolve; -} VkPhysicalDeviceDepthStencilResolvePropertiesKHR; +typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR; + +typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR; @@ -6275,19 +7517,150 @@ typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR { #define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" +#define VK_KHR_timeline_semaphore 1 +#define VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION 2 +#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore" +typedef VkSemaphoreType VkSemaphoreTypeKHR; + +typedef VkSemaphoreWaitFlagBits VkSemaphoreWaitFlagBitsKHR; + +typedef VkSemaphoreWaitFlags VkSemaphoreWaitFlagsKHR; + +typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR; + +typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR; + +typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR; + +typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR; + +typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR; + +typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValueKHR)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); +typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR( + VkDevice device, + VkSemaphore semaphore, + uint64_t* pValue); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR( + VkDevice device, + const VkSemaphoreWaitInfo* pWaitInfo, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR( + VkDevice device, + const VkSemaphoreSignalInfo* pSignalInfo); +#endif + + #define VK_KHR_vulkan_memory_model 1 #define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3 #define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model" -typedef struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR { +typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; + + + +#define VK_KHR_shader_terminate_invocation 1 +#define VK_KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION 1 +#define VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME "VK_KHR_shader_terminate_invocation" +typedef struct VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR { VkStructureType sType; void* pNext; - VkBool32 vulkanMemoryModel; - VkBool32 vulkanMemoryModelDeviceScope; - VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; -} VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; + VkBool32 shaderTerminateInvocation; +} VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; +#define VK_KHR_fragment_shading_rate 1 +#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 1 +#define VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME "VK_KHR_fragment_shading_rate" + +typedef enum VkFragmentShadingRateCombinerOpKHR { + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR = 0, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR = 1, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR = 2, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR = 3, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR = 4, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_ENUM_KHR = 0x7FFFFFFF +} VkFragmentShadingRateCombinerOpKHR; +typedef struct VkFragmentShadingRateAttachmentInfoKHR { + VkStructureType sType; + const void* pNext; + const VkAttachmentReference2* pFragmentShadingRateAttachment; + VkExtent2D shadingRateAttachmentTexelSize; +} VkFragmentShadingRateAttachmentInfoKHR; + +typedef struct VkPipelineFragmentShadingRateStateCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkExtent2D fragmentSize; + VkFragmentShadingRateCombinerOpKHR combinerOps[2]; +} VkPipelineFragmentShadingRateStateCreateInfoKHR; + +typedef struct VkPhysicalDeviceFragmentShadingRateFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 pipelineFragmentShadingRate; + VkBool32 primitiveFragmentShadingRate; + VkBool32 attachmentFragmentShadingRate; +} VkPhysicalDeviceFragmentShadingRateFeaturesKHR; + +typedef struct VkPhysicalDeviceFragmentShadingRatePropertiesKHR { + VkStructureType sType; + void* pNext; + VkExtent2D minFragmentShadingRateAttachmentTexelSize; + VkExtent2D maxFragmentShadingRateAttachmentTexelSize; + uint32_t maxFragmentShadingRateAttachmentTexelSizeAspectRatio; + VkBool32 primitiveFragmentShadingRateWithMultipleViewports; + VkBool32 layeredShadingRateAttachments; + VkBool32 fragmentShadingRateNonTrivialCombinerOps; + VkExtent2D maxFragmentSize; + uint32_t maxFragmentSizeAspectRatio; + uint32_t maxFragmentShadingRateCoverageSamples; + VkSampleCountFlagBits maxFragmentShadingRateRasterizationSamples; + VkBool32 fragmentShadingRateWithShaderDepthStencilWrites; + VkBool32 fragmentShadingRateWithSampleMask; + VkBool32 fragmentShadingRateWithShaderSampleMask; + VkBool32 fragmentShadingRateWithConservativeRasterization; + VkBool32 fragmentShadingRateWithFragmentShaderInterlock; + VkBool32 fragmentShadingRateWithCustomSampleLocations; + VkBool32 fragmentShadingRateStrictMultiplyCombiner; +} VkPhysicalDeviceFragmentShadingRatePropertiesKHR; + +typedef struct VkPhysicalDeviceFragmentShadingRateKHR { + VkStructureType sType; + void* pNext; + VkSampleCountFlags sampleCounts; + VkExtent2D fragmentSize; +} VkPhysicalDeviceFragmentShadingRateKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pFragmentShadingRateCount, VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); +typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateKHR)(VkCommandBuffer commandBuffer, const VkExtent2D* pFragmentSize, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceFragmentShadingRatesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pFragmentShadingRateCount, + VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateKHR( + VkCommandBuffer commandBuffer, + const VkExtent2D* pFragmentSize, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); +#endif + + +#define VK_KHR_spirv_1_4 1 +#define VK_KHR_SPIRV_1_4_SPEC_VERSION 1 +#define VK_KHR_SPIRV_1_4_EXTENSION_NAME "VK_KHR_spirv_1_4" + + #define VK_KHR_surface_protected_capabilities 1 #define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION 1 #define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME "VK_KHR_surface_protected_capabilities" @@ -6299,20 +7672,690 @@ typedef struct VkSurfaceProtectedCapabilitiesKHR { +#define VK_KHR_separate_depth_stencil_layouts 1 +#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION 1 +#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts" +typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR; + +typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR; + +typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR; + + + +#define VK_KHR_present_wait 1 +#define VK_KHR_PRESENT_WAIT_SPEC_VERSION 1 +#define VK_KHR_PRESENT_WAIT_EXTENSION_NAME "VK_KHR_present_wait" +typedef struct VkPhysicalDevicePresentWaitFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 presentWait; +} VkPhysicalDevicePresentWaitFeaturesKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresentKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresentKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t presentId, + uint64_t timeout); +#endif + + #define VK_KHR_uniform_buffer_standard_layout 1 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout" -typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR { +typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR; + + + +#define VK_KHR_buffer_device_address 1 +#define VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 1 +#define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address" +typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR; + +typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR; + +typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR; + +typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR; + +typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR; + +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR( + VkDevice device, + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); +#endif + + +#define VK_KHR_deferred_host_operations 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeferredOperationKHR) +#define VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION 4 +#define VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME "VK_KHR_deferred_host_operations" +typedef VkResult (VKAPI_PTR *PFN_vkCreateDeferredOperationKHR)(VkDevice device, const VkAllocationCallbacks* pAllocator, VkDeferredOperationKHR* pDeferredOperation); +typedef void (VKAPI_PTR *PFN_vkDestroyDeferredOperationKHR)(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks* pAllocator); +typedef uint32_t (VKAPI_PTR *PFN_vkGetDeferredOperationMaxConcurrencyKHR)(VkDevice device, VkDeferredOperationKHR operation); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeferredOperationResultKHR)(VkDevice device, VkDeferredOperationKHR operation); +typedef VkResult (VKAPI_PTR *PFN_vkDeferredOperationJoinKHR)(VkDevice device, VkDeferredOperationKHR operation); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDeferredOperationKHR( + VkDevice device, + const VkAllocationCallbacks* pAllocator, + VkDeferredOperationKHR* pDeferredOperation); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDeferredOperationKHR( + VkDevice device, + VkDeferredOperationKHR operation, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR uint32_t VKAPI_CALL vkGetDeferredOperationMaxConcurrencyKHR( + VkDevice device, + VkDeferredOperationKHR operation); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeferredOperationResultKHR( + VkDevice device, + VkDeferredOperationKHR operation); + +VKAPI_ATTR VkResult VKAPI_CALL vkDeferredOperationJoinKHR( + VkDevice device, + VkDeferredOperationKHR operation); +#endif + + +#define VK_KHR_pipeline_executable_properties 1 +#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION 1 +#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME "VK_KHR_pipeline_executable_properties" + +typedef enum VkPipelineExecutableStatisticFormatKHR { + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR = 0, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR = 1, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR = 2, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR = 3, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPipelineExecutableStatisticFormatKHR; +typedef struct VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR { VkStructureType sType; void* pNext; - VkBool32 uniformBufferStandardLayout; -} VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR; + VkBool32 pipelineExecutableInfo; +} VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR; +typedef struct VkPipelineInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipeline pipeline; +} VkPipelineInfoKHR; + +typedef struct VkPipelineExecutablePropertiesKHR { + VkStructureType sType; + void* pNext; + VkShaderStageFlags stages; + char name[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; + uint32_t subgroupSize; +} VkPipelineExecutablePropertiesKHR; + +typedef struct VkPipelineExecutableInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipeline pipeline; + uint32_t executableIndex; +} VkPipelineExecutableInfoKHR; + +typedef union VkPipelineExecutableStatisticValueKHR { + VkBool32 b32; + int64_t i64; + uint64_t u64; + double f64; +} VkPipelineExecutableStatisticValueKHR; + +typedef struct VkPipelineExecutableStatisticKHR { + VkStructureType sType; + void* pNext; + char name[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; + VkPipelineExecutableStatisticFormatKHR format; + VkPipelineExecutableStatisticValueKHR value; +} VkPipelineExecutableStatisticKHR; + +typedef struct VkPipelineExecutableInternalRepresentationKHR { + VkStructureType sType; + void* pNext; + char name[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; + VkBool32 isText; + size_t dataSize; + void* pData; +} VkPipelineExecutableInternalRepresentationKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutablePropertiesKHR)(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableStatisticsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableInternalRepresentationsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutablePropertiesKHR( + VkDevice device, + const VkPipelineInfoKHR* pPipelineInfo, + uint32_t* pExecutableCount, + VkPipelineExecutablePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableStatisticsKHR( + VkDevice device, + const VkPipelineExecutableInfoKHR* pExecutableInfo, + uint32_t* pStatisticCount, + VkPipelineExecutableStatisticKHR* pStatistics); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR( + VkDevice device, + const VkPipelineExecutableInfoKHR* pExecutableInfo, + uint32_t* pInternalRepresentationCount, + VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); +#endif + + +#define VK_KHR_pipeline_library 1 +#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1 +#define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library" +typedef struct VkPipelineLibraryCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t libraryCount; + const VkPipeline* pLibraries; +} VkPipelineLibraryCreateInfoKHR; + + + +#define VK_KHR_shader_non_semantic_info 1 +#define VK_KHR_SHADER_NON_SEMANTIC_INFO_SPEC_VERSION 1 +#define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info" + + +#define VK_KHR_present_id 1 +#define VK_KHR_PRESENT_ID_SPEC_VERSION 1 +#define VK_KHR_PRESENT_ID_EXTENSION_NAME "VK_KHR_present_id" +typedef struct VkPresentIdKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const uint64_t* pPresentIds; +} VkPresentIdKHR; + +typedef struct VkPhysicalDevicePresentIdFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 presentId; +} VkPhysicalDevicePresentIdFeaturesKHR; + + + +#define VK_KHR_synchronization2 1 +typedef uint64_t VkFlags64; +#define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1 +#define VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME "VK_KHR_synchronization2" +typedef VkFlags64 VkPipelineStageFlags2KHR; + +// Flag bits for VkPipelineStageFlagBits2KHR +typedef VkFlags64 VkPipelineStageFlagBits2KHR; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; +#endif +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; +static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; + +typedef VkFlags64 VkAccessFlags2KHR; + +// Flag bits for VkAccessFlagBits2KHR +typedef VkFlags64 VkAccessFlagBits2KHR; +static const VkAccessFlagBits2KHR VK_ACCESS_2_NONE_KHR = 0ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; +#endif +static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; +static const VkAccessFlagBits2KHR VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; + + +typedef enum VkSubmitFlagBitsKHR { + VK_SUBMIT_PROTECTED_BIT_KHR = 0x00000001, + VK_SUBMIT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkSubmitFlagBitsKHR; +typedef VkFlags VkSubmitFlagsKHR; +typedef struct VkMemoryBarrier2KHR { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2KHR srcStageMask; + VkAccessFlags2KHR srcAccessMask; + VkPipelineStageFlags2KHR dstStageMask; + VkAccessFlags2KHR dstAccessMask; +} VkMemoryBarrier2KHR; + +typedef struct VkBufferMemoryBarrier2KHR { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2KHR srcStageMask; + VkAccessFlags2KHR srcAccessMask; + VkPipelineStageFlags2KHR dstStageMask; + VkAccessFlags2KHR dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier2KHR; + +typedef struct VkImageMemoryBarrier2KHR { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2KHR srcStageMask; + VkAccessFlags2KHR srcAccessMask; + VkPipelineStageFlags2KHR dstStageMask; + VkAccessFlags2KHR dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier2KHR; + +typedef struct VkDependencyInfoKHR { + VkStructureType sType; + const void* pNext; + VkDependencyFlags dependencyFlags; + uint32_t memoryBarrierCount; + const VkMemoryBarrier2KHR* pMemoryBarriers; + uint32_t bufferMemoryBarrierCount; + const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers; + uint32_t imageMemoryBarrierCount; + const VkImageMemoryBarrier2KHR* pImageMemoryBarriers; +} VkDependencyInfoKHR; + +typedef struct VkSemaphoreSubmitInfoKHR { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; + VkPipelineStageFlags2KHR stageMask; + uint32_t deviceIndex; +} VkSemaphoreSubmitInfoKHR; + +typedef struct VkCommandBufferSubmitInfoKHR { + VkStructureType sType; + const void* pNext; + VkCommandBuffer commandBuffer; + uint32_t deviceMask; +} VkCommandBufferSubmitInfoKHR; + +typedef struct VkSubmitInfo2KHR { + VkStructureType sType; + const void* pNext; + VkSubmitFlagsKHR flags; + uint32_t waitSemaphoreInfoCount; + const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos; + uint32_t commandBufferInfoCount; + const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos; + uint32_t signalSemaphoreInfoCount; + const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos; +} VkSubmitInfo2KHR; + +typedef struct VkPhysicalDeviceSynchronization2FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 synchronization2; +} VkPhysicalDeviceSynchronization2FeaturesKHR; + +typedef struct VkQueueFamilyCheckpointProperties2NV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2KHR checkpointExecutionStageMask; +} VkQueueFamilyCheckpointProperties2NV; + +typedef struct VkCheckpointData2NV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2KHR stage; + void* pCheckpointMarker; +} VkCheckpointData2NV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); +typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR( + VkCommandBuffer commandBuffer, + VkEvent event, + const VkDependencyInfoKHR* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags2KHR stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + const VkDependencyInfoKHR* pDependencyInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR( + VkCommandBuffer commandBuffer, + const VkDependencyInfoKHR* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2KHR stage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo2KHR* pSubmits, + VkFence fence); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2KHR stage, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + uint32_t marker); + +VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointData2NV( + VkQueue queue, + uint32_t* pCheckpointDataCount, + VkCheckpointData2NV* pCheckpointData); +#endif + + +#define VK_KHR_shader_subgroup_uniform_control_flow 1 +#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_SPEC_VERSION 1 +#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME "VK_KHR_shader_subgroup_uniform_control_flow" +typedef struct VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupUniformControlFlow; +} VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR; + + + +#define VK_KHR_zero_initialize_workgroup_memory 1 +#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION 1 +#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME "VK_KHR_zero_initialize_workgroup_memory" +typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderZeroInitializeWorkgroupMemory; +} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; + + + +#define VK_KHR_workgroup_memory_explicit_layout 1 +#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_SPEC_VERSION 1 +#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME "VK_KHR_workgroup_memory_explicit_layout" +typedef struct VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 workgroupMemoryExplicitLayout; + VkBool32 workgroupMemoryExplicitLayoutScalarBlockLayout; + VkBool32 workgroupMemoryExplicitLayout8BitAccess; + VkBool32 workgroupMemoryExplicitLayout16BitAccess; +} VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR; + + + +#define VK_KHR_copy_commands2 1 +#define VK_KHR_COPY_COMMANDS_2_SPEC_VERSION 1 +#define VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME "VK_KHR_copy_commands2" +typedef struct VkBufferCopy2KHR { + VkStructureType sType; + const void* pNext; + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy2KHR; + +typedef struct VkCopyBufferInfo2KHR { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferCopy2KHR* pRegions; +} VkCopyBufferInfo2KHR; + +typedef struct VkImageCopy2KHR { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy2KHR; + +typedef struct VkCopyImageInfo2KHR { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2KHR* pRegions; +} VkCopyImageInfo2KHR; + +typedef struct VkBufferImageCopy2KHR { + VkStructureType sType; + const void* pNext; + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy2KHR; + +typedef struct VkCopyBufferToImageInfo2KHR { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkBufferImageCopy2KHR* pRegions; +} VkCopyBufferToImageInfo2KHR; + +typedef struct VkCopyImageToBufferInfo2KHR { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferImageCopy2KHR* pRegions; +} VkCopyImageToBufferInfo2KHR; + +typedef struct VkImageBlit2KHR { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit2KHR; + +typedef struct VkBlitImageInfo2KHR { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageBlit2KHR* pRegions; + VkFilter filter; +} VkBlitImageInfo2KHR; + +typedef struct VkImageResolve2KHR { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve2KHR; + +typedef struct VkResolveImageInfo2KHR { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageResolve2KHR* pRegions; +} VkResolveImageInfo2KHR; + +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2KHR* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2KHR* pResolveImageInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2KHR* pCopyBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2KHR* pCopyImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR( + VkCommandBuffer commandBuffer, + const VkBlitImageInfo2KHR* pBlitImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR( + VkCommandBuffer commandBuffer, + const VkResolveImageInfo2KHR* pResolveImageInfo); +#endif #define VK_EXT_debug_report 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) -#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 9 +#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 10 #define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" typedef enum VkDebugReportObjectTypeEXT { @@ -6347,19 +8390,17 @@ typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, - VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31, - VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, + VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT = 1000029000, + VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT = 1000029001, + VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000150000, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1), VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugReportObjectTypeEXT; @@ -6440,9 +8481,6 @@ VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( typedef enum VkRasterizationOrderAMD { VK_RASTERIZATION_ORDER_STRICT_AMD = 0, VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, - VK_RASTERIZATION_ORDER_BEGIN_RANGE_AMD = VK_RASTERIZATION_ORDER_STRICT_AMD, - VK_RASTERIZATION_ORDER_END_RANGE_AMD = VK_RASTERIZATION_ORDER_RELAXED_AMD, - VK_RASTERIZATION_ORDER_RANGE_SIZE_AMD = (VK_RASTERIZATION_ORDER_RELAXED_AMD - VK_RASTERIZATION_ORDER_STRICT_AMD + 1), VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF } VkRasterizationOrderAMD; typedef struct VkPipelineRasterizationStateRasterizationOrderAMD { @@ -6635,8 +8673,79 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT( #endif +#define VK_NVX_binary_import 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuModuleNVX) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuFunctionNVX) +#define VK_NVX_BINARY_IMPORT_SPEC_VERSION 1 +#define VK_NVX_BINARY_IMPORT_EXTENSION_NAME "VK_NVX_binary_import" +typedef struct VkCuModuleCreateInfoNVX { + VkStructureType sType; + const void* pNext; + size_t dataSize; + const void* pData; +} VkCuModuleCreateInfoNVX; + +typedef struct VkCuFunctionCreateInfoNVX { + VkStructureType sType; + const void* pNext; + VkCuModuleNVX module; + const char* pName; +} VkCuFunctionCreateInfoNVX; + +typedef struct VkCuLaunchInfoNVX { + VkStructureType sType; + const void* pNext; + VkCuFunctionNVX function; + uint32_t gridDimX; + uint32_t gridDimY; + uint32_t gridDimZ; + uint32_t blockDimX; + uint32_t blockDimY; + uint32_t blockDimZ; + uint32_t sharedMemBytes; + size_t paramCount; + const void* const * pParams; + size_t extraCount; + const void* const * pExtras; +} VkCuLaunchInfoNVX; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateCuModuleNVX)(VkDevice device, const VkCuModuleCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuModuleNVX* pModule); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCuFunctionNVX)(VkDevice device, const VkCuFunctionCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuFunctionNVX* pFunction); +typedef void (VKAPI_PTR *PFN_vkDestroyCuModuleNVX)(VkDevice device, VkCuModuleNVX module, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDestroyCuFunctionNVX)(VkDevice device, VkCuFunctionNVX function, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdCuLaunchKernelNVX)(VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX* pLaunchInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuModuleNVX( + VkDevice device, + const VkCuModuleCreateInfoNVX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCuModuleNVX* pModule); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuFunctionNVX( + VkDevice device, + const VkCuFunctionCreateInfoNVX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCuFunctionNVX* pFunction); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCuModuleNVX( + VkDevice device, + VkCuModuleNVX module, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCuFunctionNVX( + VkDevice device, + VkCuFunctionNVX function, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdCuLaunchKernelNVX( + VkCommandBuffer commandBuffer, + const VkCuLaunchInfoNVX* pLaunchInfo); +#endif + + #define VK_NVX_image_view_handle 1 -#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 1 +#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 2 #define VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME "VK_NVX_image_view_handle" typedef struct VkImageViewHandleInfoNVX { VkStructureType sType; @@ -6646,17 +8755,30 @@ typedef struct VkImageViewHandleInfoNVX { VkSampler sampler; } VkImageViewHandleInfoNVX; +typedef struct VkImageViewAddressPropertiesNVX { + VkStructureType sType; + void* pNext; + VkDeviceAddress deviceAddress; + VkDeviceSize size; +} VkImageViewAddressPropertiesNVX; + typedef uint32_t (VKAPI_PTR *PFN_vkGetImageViewHandleNVX)(VkDevice device, const VkImageViewHandleInfoNVX* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetImageViewAddressNVX)(VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX* pProperties); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR uint32_t VKAPI_CALL vkGetImageViewHandleNVX( VkDevice device, const VkImageViewHandleInfoNVX* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewAddressNVX( + VkDevice device, + VkImageView imageView, + VkImageViewAddressPropertiesNVX* pProperties); #endif #define VK_AMD_draw_indirect_count 1 -#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 +#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 2 #define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count" typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); @@ -6716,9 +8838,6 @@ typedef enum VkShaderInfoTypeAMD { VK_SHADER_INFO_TYPE_STATISTICS_AMD = 0, VK_SHADER_INFO_TYPE_BINARY_AMD = 1, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD = 2, - VK_SHADER_INFO_TYPE_BEGIN_RANGE_AMD = VK_SHADER_INFO_TYPE_STATISTICS_AMD, - VK_SHADER_INFO_TYPE_END_RANGE_AMD = VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, - VK_SHADER_INFO_TYPE_RANGE_SIZE_AMD = (VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD - VK_SHADER_INFO_TYPE_STATISTICS_AMD + 1), VK_SHADER_INFO_TYPE_MAX_ENUM_AMD = 0x7FFFFFFF } VkShaderInfoTypeAMD; typedef struct VkShaderResourceUsageAMD { @@ -6833,15 +8952,12 @@ typedef struct VkExportMemoryAllocateInfoNV { #define VK_EXT_validation_flags 1 -#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 1 +#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 2 #define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags" typedef enum VkValidationCheckEXT { VK_VALIDATION_CHECK_ALL_EXT = 0, VK_VALIDATION_CHECK_SHADERS_EXT = 1, - VK_VALIDATION_CHECK_BEGIN_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT, - VK_VALIDATION_CHECK_END_RANGE_EXT = VK_VALIDATION_CHECK_SHADERS_EXT, - VK_VALIDATION_CHECK_RANGE_SIZE_EXT = (VK_VALIDATION_CHECK_SHADERS_EXT - VK_VALIDATION_CHECK_ALL_EXT + 1), VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationCheckEXT; typedef struct VkValidationFlagsEXT { @@ -6863,6 +8979,17 @@ typedef struct VkValidationFlagsEXT { #define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote" +#define VK_EXT_texture_compression_astc_hdr 1 +#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION 1 +#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr" +typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 textureCompressionASTC_HDR; +} VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; + + + #define VK_EXT_astc_decode_mode 1 #define VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION 1 #define VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME "VK_EXT_astc_decode_mode" @@ -6881,7 +9008,7 @@ typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT { #define VK_EXT_conditional_rendering 1 -#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 1 +#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 2 #define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" typedef enum VkConditionalRenderingFlagBitsEXT { @@ -6923,229 +9050,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT( #endif -#define VK_NVX_device_generated_commands 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX) -#define VK_NVX_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 -#define VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NVX_device_generated_commands" - -typedef enum VkIndirectCommandsTokenTypeNVX { - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX = 0, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX = 1, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX = 2, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX = 3, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX = 4, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX = 5, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX = 6, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX = 7, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_BEGIN_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_END_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_RANGE_SIZE_NVX = (VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX + 1), - VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF -} VkIndirectCommandsTokenTypeNVX; - -typedef enum VkObjectEntryTypeNVX { - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX = 0, - VK_OBJECT_ENTRY_TYPE_PIPELINE_NVX = 1, - VK_OBJECT_ENTRY_TYPE_INDEX_BUFFER_NVX = 2, - VK_OBJECT_ENTRY_TYPE_VERTEX_BUFFER_NVX = 3, - VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX = 4, - VK_OBJECT_ENTRY_TYPE_BEGIN_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX, - VK_OBJECT_ENTRY_TYPE_END_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX, - VK_OBJECT_ENTRY_TYPE_RANGE_SIZE_NVX = (VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX + 1), - VK_OBJECT_ENTRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF -} VkObjectEntryTypeNVX; - -typedef enum VkIndirectCommandsLayoutUsageFlagBitsNVX { - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX = 0x00000001, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX = 0x00000002, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX = 0x00000004, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX = 0x00000008, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF -} VkIndirectCommandsLayoutUsageFlagBitsNVX; -typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX; - -typedef enum VkObjectEntryUsageFlagBitsNVX { - VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX = 0x00000001, - VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX = 0x00000002, - VK_OBJECT_ENTRY_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF -} VkObjectEntryUsageFlagBitsNVX; -typedef VkFlags VkObjectEntryUsageFlagsNVX; -typedef struct VkDeviceGeneratedCommandsFeaturesNVX { - VkStructureType sType; - const void* pNext; - VkBool32 computeBindingPointSupport; -} VkDeviceGeneratedCommandsFeaturesNVX; - -typedef struct VkDeviceGeneratedCommandsLimitsNVX { - VkStructureType sType; - const void* pNext; - uint32_t maxIndirectCommandsLayoutTokenCount; - uint32_t maxObjectEntryCounts; - uint32_t minSequenceCountBufferOffsetAlignment; - uint32_t minSequenceIndexBufferOffsetAlignment; - uint32_t minCommandsTokenBufferOffsetAlignment; -} VkDeviceGeneratedCommandsLimitsNVX; - -typedef struct VkIndirectCommandsTokenNVX { - VkIndirectCommandsTokenTypeNVX tokenType; - VkBuffer buffer; - VkDeviceSize offset; -} VkIndirectCommandsTokenNVX; - -typedef struct VkIndirectCommandsLayoutTokenNVX { - VkIndirectCommandsTokenTypeNVX tokenType; - uint32_t bindingUnit; - uint32_t dynamicCount; - uint32_t divisor; -} VkIndirectCommandsLayoutTokenNVX; - -typedef struct VkIndirectCommandsLayoutCreateInfoNVX { - VkStructureType sType; - const void* pNext; - VkPipelineBindPoint pipelineBindPoint; - VkIndirectCommandsLayoutUsageFlagsNVX flags; - uint32_t tokenCount; - const VkIndirectCommandsLayoutTokenNVX* pTokens; -} VkIndirectCommandsLayoutCreateInfoNVX; - -typedef struct VkCmdProcessCommandsInfoNVX { - VkStructureType sType; - const void* pNext; - VkObjectTableNVX objectTable; - VkIndirectCommandsLayoutNVX indirectCommandsLayout; - uint32_t indirectCommandsTokenCount; - const VkIndirectCommandsTokenNVX* pIndirectCommandsTokens; - uint32_t maxSequencesCount; - VkCommandBuffer targetCommandBuffer; - VkBuffer sequencesCountBuffer; - VkDeviceSize sequencesCountOffset; - VkBuffer sequencesIndexBuffer; - VkDeviceSize sequencesIndexOffset; -} VkCmdProcessCommandsInfoNVX; - -typedef struct VkCmdReserveSpaceForCommandsInfoNVX { - VkStructureType sType; - const void* pNext; - VkObjectTableNVX objectTable; - VkIndirectCommandsLayoutNVX indirectCommandsLayout; - uint32_t maxSequencesCount; -} VkCmdReserveSpaceForCommandsInfoNVX; - -typedef struct VkObjectTableCreateInfoNVX { - VkStructureType sType; - const void* pNext; - uint32_t objectCount; - const VkObjectEntryTypeNVX* pObjectEntryTypes; - const uint32_t* pObjectEntryCounts; - const VkObjectEntryUsageFlagsNVX* pObjectEntryUsageFlags; - uint32_t maxUniformBuffersPerDescriptor; - uint32_t maxStorageBuffersPerDescriptor; - uint32_t maxStorageImagesPerDescriptor; - uint32_t maxSampledImagesPerDescriptor; - uint32_t maxPipelineLayouts; -} VkObjectTableCreateInfoNVX; - -typedef struct VkObjectTableEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; -} VkObjectTableEntryNVX; - -typedef struct VkObjectTablePipelineEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipeline pipeline; -} VkObjectTablePipelineEntryNVX; - -typedef struct VkObjectTableDescriptorSetEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipelineLayout pipelineLayout; - VkDescriptorSet descriptorSet; -} VkObjectTableDescriptorSetEntryNVX; - -typedef struct VkObjectTableVertexBufferEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkBuffer buffer; -} VkObjectTableVertexBufferEntryNVX; - -typedef struct VkObjectTableIndexBufferEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkBuffer buffer; - VkIndexType indexType; -} VkObjectTableIndexBufferEntryNVX; - -typedef struct VkObjectTablePushConstantEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipelineLayout pipelineLayout; - VkShaderStageFlags stageFlags; -} VkObjectTablePushConstantEntryNVX; - -typedef void (VKAPI_PTR *PFN_vkCmdProcessCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); -typedef void (VKAPI_PTR *PFN_vkCmdReserveSpaceForCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNVX)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNVX)(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateObjectTableNVX)(VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkObjectTableNVX* pObjectTable); -typedef void (VKAPI_PTR *PFN_vkDestroyObjectTableNVX)(VkDevice device, VkObjectTableNVX objectTable, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkRegisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectTableEntryNVX* const* ppObjectTableEntries, const uint32_t* pObjectIndices); -typedef VkResult (VKAPI_PTR *PFN_vkUnregisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectEntryTypeNVX* pObjectEntryTypes, const uint32_t* pObjectIndices); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)(VkPhysicalDevice physicalDevice, VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, VkDeviceGeneratedCommandsLimitsNVX* pLimits); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdProcessCommandsNVX( - VkCommandBuffer commandBuffer, - const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdReserveSpaceForCommandsNVX( - VkCommandBuffer commandBuffer, - const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNVX( - VkDevice device, - const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNVX( - VkDevice device, - VkIndirectCommandsLayoutNVX indirectCommandsLayout, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateObjectTableNVX( - VkDevice device, - const VkObjectTableCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkObjectTableNVX* pObjectTable); - -VKAPI_ATTR void VKAPI_CALL vkDestroyObjectTableNVX( - VkDevice device, - VkObjectTableNVX objectTable, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkRegisterObjectsNVX( - VkDevice device, - VkObjectTableNVX objectTable, - uint32_t objectCount, - const VkObjectTableEntryNVX* const* ppObjectTableEntries, - const uint32_t* pObjectIndices); - -VKAPI_ATTR VkResult VKAPI_CALL vkUnregisterObjectsNVX( - VkDevice device, - VkObjectTableNVX objectTable, - uint32_t objectCount, - const VkObjectEntryTypeNVX* pObjectEntryTypes, - const uint32_t* pObjectIndices); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX( - VkPhysicalDevice physicalDevice, - VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, - VkDeviceGeneratedCommandsLimitsNVX* pLimits); -#endif - - #define VK_NV_clip_space_w_scaling 1 #define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1 #define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling" @@ -7190,7 +9094,8 @@ VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( #define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter" typedef enum VkSurfaceCounterFlagBitsEXT { - VK_SURFACE_COUNTER_VBLANK_EXT = 0x00000001, + VK_SURFACE_COUNTER_VBLANK_BIT_EXT = 0x00000001, + VK_SURFACE_COUNTER_VBLANK_EXT = VK_SURFACE_COUNTER_VBLANK_BIT_EXT, VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkSurfaceCounterFlagBitsEXT; typedef VkFlags VkSurfaceCounterFlagsEXT; @@ -7228,25 +9133,16 @@ typedef enum VkDisplayPowerStateEXT { VK_DISPLAY_POWER_STATE_OFF_EXT = 0, VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1, VK_DISPLAY_POWER_STATE_ON_EXT = 2, - VK_DISPLAY_POWER_STATE_BEGIN_RANGE_EXT = VK_DISPLAY_POWER_STATE_OFF_EXT, - VK_DISPLAY_POWER_STATE_END_RANGE_EXT = VK_DISPLAY_POWER_STATE_ON_EXT, - VK_DISPLAY_POWER_STATE_RANGE_SIZE_EXT = (VK_DISPLAY_POWER_STATE_ON_EXT - VK_DISPLAY_POWER_STATE_OFF_EXT + 1), VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDisplayPowerStateEXT; typedef enum VkDeviceEventTypeEXT { VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0, - VK_DEVICE_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, - VK_DEVICE_EVENT_TYPE_END_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, - VK_DEVICE_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT + 1), VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDeviceEventTypeEXT; typedef enum VkDisplayEventTypeEXT { VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0, - VK_DISPLAY_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, - VK_DISPLAY_EVENT_TYPE_END_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, - VK_DISPLAY_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT + 1), VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDisplayEventTypeEXT; typedef struct VkDisplayPowerInfoEXT { @@ -7388,9 +9284,6 @@ typedef enum VkViewportCoordinateSwizzleNV { VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6, VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7, - VK_VIEWPORT_COORDINATE_SWIZZLE_BEGIN_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, - VK_VIEWPORT_COORDINATE_SWIZZLE_END_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV, - VK_VIEWPORT_COORDINATE_SWIZZLE_RANGE_SIZE_NV = (VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV + 1), VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF } VkViewportCoordinateSwizzleNV; typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; @@ -7418,9 +9311,6 @@ typedef struct VkPipelineViewportSwizzleStateCreateInfoNV { typedef enum VkDiscardRectangleModeEXT { VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0, VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1, - VK_DISCARD_RECTANGLE_MODE_BEGIN_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT, - VK_DISCARD_RECTANGLE_MODE_END_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT, - VK_DISCARD_RECTANGLE_MODE_RANGE_SIZE_EXT = (VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT - VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT + 1), VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDiscardRectangleModeEXT; typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; @@ -7458,9 +9348,6 @@ typedef enum VkConservativeRasterizationModeEXT { VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0, VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1, VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2, - VK_CONSERVATIVE_RASTERIZATION_MODE_BEGIN_RANGE_EXT = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, - VK_CONSERVATIVE_RASTERIZATION_MODE_END_RANGE_EXT = VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, - VK_CONSERVATIVE_RASTERIZATION_MODE_RANGE_SIZE_EXT = (VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT - VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT + 1), VK_CONSERVATIVE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF } VkConservativeRasterizationModeEXT; typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT; @@ -7513,7 +9400,7 @@ typedef struct VkPipelineRasterizationDepthClipStateCreateInfoEXT { #define VK_EXT_hdr_metadata 1 -#define VK_EXT_HDR_METADATA_SPEC_VERSION 1 +#define VK_EXT_HDR_METADATA_SPEC_VERSION 2 #define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata" typedef struct VkXYColorEXT { float x; @@ -7552,15 +9439,14 @@ VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT( #define VK_EXT_queue_family_foreign 1 #define VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION 1 #define VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME "VK_EXT_queue_family_foreign" -#define VK_QUEUE_FAMILY_FOREIGN_EXT (~0U-2) +#define VK_QUEUE_FAMILY_FOREIGN_EXT (~2U) #define VK_EXT_debug_utils 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT) -#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 1 +#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 2 #define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils" typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT; -typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001, @@ -7569,7 +9455,6 @@ typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000, VK_DEBUG_UTILS_MESSAGE_SEVERITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugUtilsMessageSeverityFlagBitsEXT; -typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; typedef enum VkDebugUtilsMessageTypeFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001, @@ -7578,6 +9463,15 @@ typedef enum VkDebugUtilsMessageTypeFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugUtilsMessageTypeFlagBitsEXT; typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT; +typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; +typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; +typedef struct VkDebugUtilsLabelEXT { + VkStructureType sType; + const void* pNext; + const char* pLabelName; + float color[4]; +} VkDebugUtilsLabelEXT; + typedef struct VkDebugUtilsObjectNameInfoEXT { VkStructureType sType; const void* pNext; @@ -7586,23 +9480,6 @@ typedef struct VkDebugUtilsObjectNameInfoEXT { const char* pObjectName; } VkDebugUtilsObjectNameInfoEXT; -typedef struct VkDebugUtilsObjectTagInfoEXT { - VkStructureType sType; - const void* pNext; - VkObjectType objectType; - uint64_t objectHandle; - uint64_t tagName; - size_t tagSize; - const void* pTag; -} VkDebugUtilsObjectTagInfoEXT; - -typedef struct VkDebugUtilsLabelEXT { - VkStructureType sType; - const void* pNext; - const char* pLabelName; - float color[4]; -} VkDebugUtilsLabelEXT; - typedef struct VkDebugUtilsMessengerCallbackDataEXT { VkStructureType sType; const void* pNext; @@ -7634,6 +9511,16 @@ typedef struct VkDebugUtilsMessengerCreateInfoEXT { void* pUserData; } VkDebugUtilsMessengerCreateInfoEXT; +typedef struct VkDebugUtilsObjectTagInfoEXT { + VkStructureType sType; + const void* pNext; + VkObjectType objectType; + uint64_t objectHandle; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkDebugUtilsObjectTagInfoEXT; + typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectNameEXT)(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo); typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectTagEXT)(VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo); typedef void (VKAPI_PTR *PFN_vkQueueBeginDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); @@ -7697,30 +9584,13 @@ VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT( #define VK_EXT_sampler_filter_minmax 1 -#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 1 +#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 2 #define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax" +typedef VkSamplerReductionMode VkSamplerReductionModeEXT; -typedef enum VkSamplerReductionModeEXT { - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0, - VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1, - VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2, - VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, - VK_SAMPLER_REDUCTION_MODE_END_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_MAX_EXT, - VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE_EXT = (VK_SAMPLER_REDUCTION_MODE_MAX_EXT - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT + 1), - VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkSamplerReductionModeEXT; -typedef struct VkSamplerReductionModeCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkSamplerReductionModeEXT reductionMode; -} VkSamplerReductionModeCreateInfoEXT; +typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT; -typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; -} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; +typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; @@ -7861,9 +9731,6 @@ typedef enum VkBlendOverlapEXT { VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0, VK_BLEND_OVERLAP_DISJOINT_EXT = 1, VK_BLEND_OVERLAP_CONJOINT_EXT = 2, - VK_BLEND_OVERLAP_BEGIN_RANGE_EXT = VK_BLEND_OVERLAP_UNCORRELATED_EXT, - VK_BLEND_OVERLAP_END_RANGE_EXT = VK_BLEND_OVERLAP_CONJOINT_EXT, - VK_BLEND_OVERLAP_RANGE_SIZE_EXT = (VK_BLEND_OVERLAP_CONJOINT_EXT - VK_BLEND_OVERLAP_UNCORRELATED_EXT + 1), VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF } VkBlendOverlapEXT; typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT { @@ -7916,9 +9783,6 @@ typedef enum VkCoverageModulationModeNV { VK_COVERAGE_MODULATION_MODE_RGB_NV = 1, VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2, VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3, - VK_COVERAGE_MODULATION_MODE_BEGIN_RANGE_NV = VK_COVERAGE_MODULATION_MODE_NONE_NV, - VK_COVERAGE_MODULATION_MODE_END_RANGE_NV = VK_COVERAGE_MODULATION_MODE_RGBA_NV, - VK_COVERAGE_MODULATION_MODE_RANGE_SIZE_NV = (VK_COVERAGE_MODULATION_MODE_RGBA_NV - VK_COVERAGE_MODULATION_MODE_NONE_NV + 1), VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF } VkCoverageModulationModeNV; typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; @@ -8025,9 +9889,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) typedef enum VkValidationCacheHeaderVersionEXT { VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1, - VK_VALIDATION_CACHE_HEADER_VERSION_BEGIN_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, - VK_VALIDATION_CACHE_HEADER_VERSION_END_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, - VK_VALIDATION_CACHE_HEADER_VERSION_RANGE_SIZE_EXT = (VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT - VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT + 1), VK_VALIDATION_CACHE_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationCacheHeaderVersionEXT; typedef VkFlags VkValidationCacheCreateFlagsEXT; @@ -8079,87 +9940,19 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( #define VK_EXT_descriptor_indexing 1 #define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2 #define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing" +typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT; -typedef enum VkDescriptorBindingFlagBitsEXT { - VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001, - VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002, - VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004, - VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008, - VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDescriptorBindingFlagBitsEXT; -typedef VkFlags VkDescriptorBindingFlagsEXT; -typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t bindingCount; - const VkDescriptorBindingFlagsEXT* pBindingFlags; -} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; +typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT; -typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderInputAttachmentArrayDynamicIndexing; - VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; - VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; - VkBool32 shaderUniformBufferArrayNonUniformIndexing; - VkBool32 shaderSampledImageArrayNonUniformIndexing; - VkBool32 shaderStorageBufferArrayNonUniformIndexing; - VkBool32 shaderStorageImageArrayNonUniformIndexing; - VkBool32 shaderInputAttachmentArrayNonUniformIndexing; - VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; - VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; - VkBool32 descriptorBindingUniformBufferUpdateAfterBind; - VkBool32 descriptorBindingSampledImageUpdateAfterBind; - VkBool32 descriptorBindingStorageImageUpdateAfterBind; - VkBool32 descriptorBindingStorageBufferUpdateAfterBind; - VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingUpdateUnusedWhilePending; - VkBool32 descriptorBindingPartiallyBound; - VkBool32 descriptorBindingVariableDescriptorCount; - VkBool32 runtimeDescriptorArray; -} VkPhysicalDeviceDescriptorIndexingFeaturesEXT; +typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; -typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxUpdateAfterBindDescriptorsInAllPools; - VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; - VkBool32 shaderSampledImageArrayNonUniformIndexingNative; - VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; - VkBool32 shaderStorageImageArrayNonUniformIndexingNative; - VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; - VkBool32 robustBufferAccessUpdateAfterBind; - VkBool32 quadDivergentImplicitLod; - uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; - uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; - uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; - uint32_t maxPerStageUpdateAfterBindResources; - uint32_t maxDescriptorSetUpdateAfterBindSamplers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindSampledImages; - uint32_t maxDescriptorSetUpdateAfterBindStorageImages; - uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; -} VkPhysicalDeviceDescriptorIndexingPropertiesEXT; +typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT; -typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t descriptorSetCount; - const uint32_t* pDescriptorCounts; -} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; +typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT; -typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT { - VkStructureType sType; - void* pNext; - uint32_t maxVariableDescriptorCount; -} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; +typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; + +typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; @@ -8185,9 +9978,6 @@ typedef enum VkShadingRatePaletteEntryNV { VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9, VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10, VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11, - VK_SHADING_RATE_PALETTE_ENTRY_BEGIN_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV, - VK_SHADING_RATE_PALETTE_ENTRY_END_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, - VK_SHADING_RATE_PALETTE_ENTRY_RANGE_SIZE_NV = (VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV - VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV + 1), VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF } VkShadingRatePaletteEntryNV; @@ -8196,9 +9986,6 @@ typedef enum VkCoarseSampleOrderTypeNV { VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1, VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2, VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3, - VK_COARSE_SAMPLE_ORDER_TYPE_BEGIN_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, - VK_COARSE_SAMPLE_ORDER_TYPE_END_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV, - VK_COARSE_SAMPLE_ORDER_TYPE_RANGE_SIZE_NV = (VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV - VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV + 1), VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF } VkCoarseSampleOrderTypeNV; typedef struct VkShadingRatePaletteNV { @@ -8278,88 +10065,120 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV( VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) #define VK_NV_RAY_TRACING_SPEC_VERSION 3 #define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing" -#define VK_SHADER_UNUSED_NV (~0U) +#define VK_SHADER_UNUSED_KHR (~0U) +#define VK_SHADER_UNUSED_NV VK_SHADER_UNUSED_KHR -typedef enum VkRayTracingShaderGroupTypeNV { - VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = 0, - VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = 1, - VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = 2, - VK_RAY_TRACING_SHADER_GROUP_TYPE_BEGIN_RANGE_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV, - VK_RAY_TRACING_SHADER_GROUP_TYPE_END_RANGE_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV, - VK_RAY_TRACING_SHADER_GROUP_TYPE_RANGE_SIZE_NV = (VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV - VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV + 1), - VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkRayTracingShaderGroupTypeNV; +typedef enum VkRayTracingShaderGroupTypeKHR { + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR = 0, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR = 1, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR = 2, + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkRayTracingShaderGroupTypeKHR; +typedef VkRayTracingShaderGroupTypeKHR VkRayTracingShaderGroupTypeNV; -typedef enum VkGeometryTypeNV { - VK_GEOMETRY_TYPE_TRIANGLES_NV = 0, - VK_GEOMETRY_TYPE_AABBS_NV = 1, - VK_GEOMETRY_TYPE_BEGIN_RANGE_NV = VK_GEOMETRY_TYPE_TRIANGLES_NV, - VK_GEOMETRY_TYPE_END_RANGE_NV = VK_GEOMETRY_TYPE_AABBS_NV, - VK_GEOMETRY_TYPE_RANGE_SIZE_NV = (VK_GEOMETRY_TYPE_AABBS_NV - VK_GEOMETRY_TYPE_TRIANGLES_NV + 1), - VK_GEOMETRY_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkGeometryTypeNV; -typedef enum VkAccelerationStructureTypeNV { - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = 0, - VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = 1, - VK_ACCELERATION_STRUCTURE_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV, - VK_ACCELERATION_STRUCTURE_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV, - VK_ACCELERATION_STRUCTURE_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV + 1), - VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkAccelerationStructureTypeNV; +typedef enum VkGeometryTypeKHR { + VK_GEOMETRY_TYPE_TRIANGLES_KHR = 0, + VK_GEOMETRY_TYPE_AABBS_KHR = 1, + VK_GEOMETRY_TYPE_INSTANCES_KHR = 2, + VK_GEOMETRY_TYPE_TRIANGLES_NV = VK_GEOMETRY_TYPE_TRIANGLES_KHR, + VK_GEOMETRY_TYPE_AABBS_NV = VK_GEOMETRY_TYPE_AABBS_KHR, + VK_GEOMETRY_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryTypeKHR; +typedef VkGeometryTypeKHR VkGeometryTypeNV; + + +typedef enum VkAccelerationStructureTypeKHR { + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1, + VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR = 2, + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureTypeKHR; +typedef VkAccelerationStructureTypeKHR VkAccelerationStructureTypeNV; + + +typedef enum VkCopyAccelerationStructureModeKHR { + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR = 0, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR = 1, + VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR = 2, + VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR = 3, + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR, + VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkCopyAccelerationStructureModeKHR; +typedef VkCopyAccelerationStructureModeKHR VkCopyAccelerationStructureModeNV; -typedef enum VkCopyAccelerationStructureModeNV { - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = 0, - VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = 1, - VK_COPY_ACCELERATION_STRUCTURE_MODE_BEGIN_RANGE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV, - VK_COPY_ACCELERATION_STRUCTURE_MODE_END_RANGE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV, - VK_COPY_ACCELERATION_STRUCTURE_MODE_RANGE_SIZE_NV = (VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV + 1), - VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_NV = 0x7FFFFFFF -} VkCopyAccelerationStructureModeNV; typedef enum VkAccelerationStructureMemoryRequirementsTypeNV { VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0, VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1, VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = 2, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV + 1), VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_MAX_ENUM_NV = 0x7FFFFFFF } VkAccelerationStructureMemoryRequirementsTypeNV; -typedef enum VkGeometryFlagBitsNV { - VK_GEOMETRY_OPAQUE_BIT_NV = 0x00000001, - VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = 0x00000002, - VK_GEOMETRY_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkGeometryFlagBitsNV; -typedef VkFlags VkGeometryFlagsNV; +typedef enum VkGeometryFlagBitsKHR { + VK_GEOMETRY_OPAQUE_BIT_KHR = 0x00000001, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR = 0x00000002, + VK_GEOMETRY_OPAQUE_BIT_NV = VK_GEOMETRY_OPAQUE_BIT_KHR, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, + VK_GEOMETRY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryFlagBitsKHR; +typedef VkFlags VkGeometryFlagsKHR; +typedef VkGeometryFlagsKHR VkGeometryFlagsNV; -typedef enum VkGeometryInstanceFlagBitsNV { - VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = 0x00000001, - VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = 0x00000002, - VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = 0x00000004, - VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = 0x00000008, - VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkGeometryInstanceFlagBitsNV; -typedef VkFlags VkGeometryInstanceFlagsNV; +typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV; + + +typedef enum VkGeometryInstanceFlagBitsKHR { + VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001, + VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR, + VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryInstanceFlagBitsKHR; +typedef VkFlags VkGeometryInstanceFlagsKHR; +typedef VkGeometryInstanceFlagsKHR VkGeometryInstanceFlagsNV; + +typedef VkGeometryInstanceFlagBitsKHR VkGeometryInstanceFlagBitsNV; + + +typedef enum VkBuildAccelerationStructureFlagBitsKHR { + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR = 0x00000001, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR = 0x00000002, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR = 0x00000004, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR = 0x00000008, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR = 0x00000010, + VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV = 0x00000020, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkBuildAccelerationStructureFlagBitsKHR; +typedef VkFlags VkBuildAccelerationStructureFlagsKHR; +typedef VkBuildAccelerationStructureFlagsKHR VkBuildAccelerationStructureFlagsNV; + +typedef VkBuildAccelerationStructureFlagBitsKHR VkBuildAccelerationStructureFlagBitsNV; -typedef enum VkBuildAccelerationStructureFlagBitsNV { - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = 0x00000001, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = 0x00000002, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = 0x00000004, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = 0x00000008, - VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = 0x00000010, - VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkBuildAccelerationStructureFlagBitsNV; -typedef VkFlags VkBuildAccelerationStructureFlagsNV; typedef struct VkRayTracingShaderGroupCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkRayTracingShaderGroupTypeNV type; - uint32_t generalShader; - uint32_t closestHitShader; - uint32_t anyHitShader; - uint32_t intersectionShader; + VkStructureType sType; + const void* pNext; + VkRayTracingShaderGroupTypeKHR type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; } VkRayTracingShaderGroupCreateInfoNV; typedef struct VkRayTracingPipelineCreateInfoNV { @@ -8407,11 +10226,11 @@ typedef struct VkGeometryDataNV { } VkGeometryDataNV; typedef struct VkGeometryNV { - VkStructureType sType; - const void* pNext; - VkGeometryTypeNV geometryType; - VkGeometryDataNV geometry; - VkGeometryFlagsNV flags; + VkStructureType sType; + const void* pNext; + VkGeometryTypeKHR geometryType; + VkGeometryDataNV geometry; + VkGeometryFlagsKHR flags; } VkGeometryNV; typedef struct VkAccelerationStructureInfoNV { @@ -8468,14 +10287,43 @@ typedef struct VkPhysicalDeviceRayTracingPropertiesNV { uint32_t maxDescriptorSetAccelerationStructures; } VkPhysicalDeviceRayTracingPropertiesNV; +typedef struct VkTransformMatrixKHR { + float matrix[3][4]; +} VkTransformMatrixKHR; + +typedef VkTransformMatrixKHR VkTransformMatrixNV; + +typedef struct VkAabbPositionsKHR { + float minX; + float minY; + float minZ; + float maxX; + float maxY; + float maxZ; +} VkAabbPositionsKHR; + +typedef VkAabbPositionsKHR VkAabbPositionsNV; + +typedef struct VkAccelerationStructureInstanceKHR { + VkTransformMatrixKHR transform; + uint32_t instanceCustomIndex:24; + uint32_t mask:8; + uint32_t instanceShaderBindingTableRecordOffset:24; + VkGeometryInstanceFlagsKHR flags:8; + uint64_t accelerationStructureReference; +} VkAccelerationStructureInstanceKHR; + +typedef VkAccelerationStructureInstanceKHR VkAccelerationStructureInstanceNV; + typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator); typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); -typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeNV mode); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeKHR mode); typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNV)(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth); typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesNV)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesNV)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData); typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); @@ -8518,7 +10366,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNV( VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, - VkCopyAccelerationStructureModeNV mode); + VkCopyAccelerationStructureModeKHR mode); VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV( VkCommandBuffer commandBuffer, @@ -8545,6 +10393,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV( const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( VkDevice device, VkPipeline pipeline, @@ -8575,7 +10431,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNV( #define VK_NV_representative_fragment_test 1 -#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1 +#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 2 #define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test" typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV { VkStructureType sType; @@ -8592,7 +10448,7 @@ typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV { #define VK_EXT_filter_cubic 1 -#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 2 +#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 3 #define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic" typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT { VkStructureType sType; @@ -8604,11 +10460,16 @@ typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { VkStructureType sType; void* pNext; VkBool32 filterCubic; - VkBool32 filterCubicMinmax ; + VkBool32 filterCubicMinmax; } VkFilterCubicImageViewImageFormatPropertiesEXT; +#define VK_QCOM_render_pass_shader_resolve 1 +#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_SPEC_VERSION 4 +#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME "VK_QCOM_render_pass_shader_resolve" + + #define VK_EXT_global_priority 1 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" @@ -8618,9 +10479,6 @@ typedef enum VkQueueGlobalPriorityEXT { VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256, VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512, VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024, - VK_QUEUE_GLOBAL_PRIORITY_BEGIN_RANGE_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT, - VK_QUEUE_GLOBAL_PRIORITY_END_RANGE_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT, - VK_QUEUE_GLOBAL_PRIORITY_RANGE_SIZE_EXT = (VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT + 1), VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_EXT = 0x7FFFFFFF } VkQueueGlobalPriorityEXT; typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT { @@ -8679,8 +10537,24 @@ VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD( #endif +#define VK_AMD_pipeline_compiler_control 1 +#define VK_AMD_PIPELINE_COMPILER_CONTROL_SPEC_VERSION 1 +#define VK_AMD_PIPELINE_COMPILER_CONTROL_EXTENSION_NAME "VK_AMD_pipeline_compiler_control" + +typedef enum VkPipelineCompilerControlFlagBitsAMD { + VK_PIPELINE_COMPILER_CONTROL_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF +} VkPipelineCompilerControlFlagBitsAMD; +typedef VkFlags VkPipelineCompilerControlFlagsAMD; +typedef struct VkPipelineCompilerControlCreateInfoAMD { + VkStructureType sType; + const void* pNext; + VkPipelineCompilerControlFlagsAMD compilerControlFlags; +} VkPipelineCompilerControlCreateInfoAMD; + + + #define VK_EXT_calibrated_timestamps 1 -#define VK_EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION 1 +#define VK_EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION 2 #define VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME "VK_EXT_calibrated_timestamps" typedef enum VkTimeDomainEXT { @@ -8688,9 +10562,6 @@ typedef enum VkTimeDomainEXT { VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT = 1, VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT = 2, VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT = 3, - VK_TIME_DOMAIN_BEGIN_RANGE_EXT = VK_TIME_DOMAIN_DEVICE_EXT, - VK_TIME_DOMAIN_END_RANGE_EXT = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT, - VK_TIME_DOMAIN_RANGE_SIZE_EXT = (VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT - VK_TIME_DOMAIN_DEVICE_EXT + 1), VK_TIME_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF } VkTimeDomainEXT; typedef struct VkCalibratedTimestampInfoEXT { @@ -8718,7 +10589,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsEXT( #define VK_AMD_shader_core_properties 1 -#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 2 #define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties" typedef struct VkPhysicalDeviceShaderCorePropertiesAMD { VkStructureType sType; @@ -8749,9 +10620,6 @@ typedef enum VkMemoryOverallocationBehaviorAMD { VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0, VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1, VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_BEGIN_RANGE_AMD = VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_END_RANGE_AMD = VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_RANGE_SIZE_AMD = (VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD - VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD + 1), VK_MEMORY_OVERALLOCATION_BEHAVIOR_MAX_ENUM_AMD = 0x7FFFFFFF } VkMemoryOverallocationBehaviorAMD; typedef struct VkDeviceMemoryOverallocationCreateInfoAMD { @@ -8908,7 +10776,7 @@ typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV { #define VK_NV_shader_image_footprint 1 -#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 1 +#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 2 #define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint" typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV { VkStructureType sType; @@ -8977,52 +10845,40 @@ VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV( #define VK_INTEL_shader_integer_functions2 1 -#define VK_INTEL_SHADER_INTEGER_FUNCTIONS2_SPEC_VERSION 1 -#define VK_INTEL_SHADER_INTEGER_FUNCTIONS2_EXTENSION_NAME "VK_INTEL_shader_integer_functions2" -typedef struct VkPhysicalDeviceShaderIntegerFunctions2INTEL { +#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_SPEC_VERSION 1 +#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME "VK_INTEL_shader_integer_functions2" +typedef struct VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL { VkStructureType sType; void* pNext; VkBool32 shaderIntegerFunctions2; -} VkPhysicalDeviceShaderIntegerFunctions2INTEL; +} VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL; #define VK_INTEL_performance_query 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPerformanceConfigurationINTEL) -#define VK_INTEL_PERFORMANCE_QUERY_SPEC_VERSION 1 +#define VK_INTEL_PERFORMANCE_QUERY_SPEC_VERSION 2 #define VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME "VK_INTEL_performance_query" typedef enum VkPerformanceConfigurationTypeINTEL { VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL = 0, - VK_PERFORMANCE_CONFIGURATION_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL, - VK_PERFORMANCE_CONFIGURATION_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL, - VK_PERFORMANCE_CONFIGURATION_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL - VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL + 1), VK_PERFORMANCE_CONFIGURATION_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceConfigurationTypeINTEL; typedef enum VkQueryPoolSamplingModeINTEL { VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL = 0, - VK_QUERY_POOL_SAMPLING_MODE_BEGIN_RANGE_INTEL = VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL, - VK_QUERY_POOL_SAMPLING_MODE_END_RANGE_INTEL = VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL, - VK_QUERY_POOL_SAMPLING_MODE_RANGE_SIZE_INTEL = (VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL - VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL + 1), VK_QUERY_POOL_SAMPLING_MODE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkQueryPoolSamplingModeINTEL; typedef enum VkPerformanceOverrideTypeINTEL { VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL = 0, VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL = 1, - VK_PERFORMANCE_OVERRIDE_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL, - VK_PERFORMANCE_OVERRIDE_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL, - VK_PERFORMANCE_OVERRIDE_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL - VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL + 1), VK_PERFORMANCE_OVERRIDE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceOverrideTypeINTEL; typedef enum VkPerformanceParameterTypeINTEL { VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL = 0, VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL = 1, - VK_PERFORMANCE_PARAMETER_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL, - VK_PERFORMANCE_PARAMETER_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL, - VK_PERFORMANCE_PARAMETER_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL - VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL + 1), VK_PERFORMANCE_PARAMETER_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceParameterTypeINTEL; @@ -9032,9 +10888,6 @@ typedef enum VkPerformanceValueTypeINTEL { VK_PERFORMANCE_VALUE_TYPE_FLOAT_INTEL = 2, VK_PERFORMANCE_VALUE_TYPE_BOOL_INTEL = 3, VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL = 4, - VK_PERFORMANCE_VALUE_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL, - VK_PERFORMANCE_VALUE_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL, - VK_PERFORMANCE_VALUE_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL - VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL + 1), VK_PERFORMANCE_VALUE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceValueTypeINTEL; typedef union VkPerformanceValueDataINTEL { @@ -9056,11 +10909,13 @@ typedef struct VkInitializePerformanceApiInfoINTEL { void* pUserData; } VkInitializePerformanceApiInfoINTEL; -typedef struct VkQueryPoolCreateInfoINTEL { +typedef struct VkQueryPoolPerformanceQueryCreateInfoINTEL { VkStructureType sType; const void* pNext; VkQueryPoolSamplingModeINTEL performanceCountersSampling; -} VkQueryPoolCreateInfoINTEL; +} VkQueryPoolPerformanceQueryCreateInfoINTEL; + +typedef VkQueryPoolPerformanceQueryCreateInfoINTEL VkQueryPoolCreateInfoINTEL; typedef struct VkPerformanceMarkerInfoINTEL { VkStructureType sType; @@ -9207,11 +11062,7 @@ typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT { #define VK_EXT_scalar_block_layout 1 #define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 #define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" -typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 scalarBlockLayout; -} VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; +typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; @@ -9225,6 +11076,73 @@ typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT { #define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string" +#define VK_EXT_subgroup_size_control 1 +#define VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION 2 +#define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control" +typedef struct VkPhysicalDeviceSubgroupSizeControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; +} VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; + +typedef struct VkPhysicalDeviceSubgroupSizeControlPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; +} VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; + +typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT { + VkStructureType sType; + void* pNext; + uint32_t requiredSubgroupSize; +} VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; + + + +#define VK_AMD_shader_core_properties2 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_2_SPEC_VERSION 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME "VK_AMD_shader_core_properties2" + +typedef enum VkShaderCorePropertiesFlagBitsAMD { + VK_SHADER_CORE_PROPERTIES_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF +} VkShaderCorePropertiesFlagBitsAMD; +typedef VkFlags VkShaderCorePropertiesFlagsAMD; +typedef struct VkPhysicalDeviceShaderCoreProperties2AMD { + VkStructureType sType; + void* pNext; + VkShaderCorePropertiesFlagsAMD shaderCoreFeatures; + uint32_t activeComputeUnitCount; +} VkPhysicalDeviceShaderCoreProperties2AMD; + + + +#define VK_AMD_device_coherent_memory 1 +#define VK_AMD_DEVICE_COHERENT_MEMORY_SPEC_VERSION 1 +#define VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME "VK_AMD_device_coherent_memory" +typedef struct VkPhysicalDeviceCoherentMemoryFeaturesAMD { + VkStructureType sType; + void* pNext; + VkBool32 deviceCoherentMemory; +} VkPhysicalDeviceCoherentMemoryFeaturesAMD; + + + +#define VK_EXT_shader_image_atomic_int64 1 +#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_SPEC_VERSION 1 +#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_EXTENSION_NAME "VK_EXT_shader_image_atomic_int64" +typedef struct VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderImageInt64Atomics; + VkBool32 sparseImageInt64Atomics; +} VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT; + + + #define VK_EXT_memory_budget 1 #define VK_EXT_MEMORY_BUDGET_SPEC_VERSION 1 #define VK_EXT_MEMORY_BUDGET_EXTENSION_NAME "VK_EXT_memory_budget" @@ -9266,7 +11184,6 @@ typedef struct VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV { #define VK_EXT_buffer_device_address 1 -typedef uint64_t VkDeviceAddress; #define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2 #define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address" typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT { @@ -9279,11 +11196,7 @@ typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT { typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT; -typedef struct VkBufferDeviceAddressInfoEXT { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; -} VkBufferDeviceAddressInfoEXT; +typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT; typedef struct VkBufferDeviceAddressCreateInfoEXT { VkStructureType sType; @@ -9291,36 +11204,67 @@ typedef struct VkBufferDeviceAddressCreateInfoEXT { VkDeviceAddress deviceAddress; } VkBufferDeviceAddressCreateInfoEXT; -typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfoEXT* pInfo); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( VkDevice device, - const VkBufferDeviceAddressInfoEXT* pInfo); + const VkBufferDeviceAddressInfo* pInfo); +#endif + + +#define VK_EXT_tooling_info 1 +#define VK_EXT_TOOLING_INFO_SPEC_VERSION 1 +#define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info" + +typedef enum VkToolPurposeFlagBitsEXT { + VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = 0x00000001, + VK_TOOL_PURPOSE_PROFILING_BIT_EXT = 0x00000002, + VK_TOOL_PURPOSE_TRACING_BIT_EXT = 0x00000004, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = 0x00000008, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = 0x00000010, + VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, + VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, + VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkToolPurposeFlagBitsEXT; +typedef VkFlags VkToolPurposeFlagsEXT; +typedef struct VkPhysicalDeviceToolPropertiesEXT { + VkStructureType sType; + void* pNext; + char name[VK_MAX_EXTENSION_NAME_SIZE]; + char version[VK_MAX_EXTENSION_NAME_SIZE]; + VkToolPurposeFlagsEXT purposes; + char description[VK_MAX_DESCRIPTION_SIZE]; + char layer[VK_MAX_EXTENSION_NAME_SIZE]; +} VkPhysicalDeviceToolPropertiesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( + VkPhysicalDevice physicalDevice, + uint32_t* pToolCount, + VkPhysicalDeviceToolPropertiesEXT* pToolProperties); #endif #define VK_EXT_separate_stencil_usage 1 #define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1 #define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage" -typedef struct VkImageStencilUsageCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkImageUsageFlags stencilUsage; -} VkImageStencilUsageCreateInfoEXT; +typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT; #define VK_EXT_validation_features 1 -#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 1 +#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 5 #define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" typedef enum VkValidationFeatureEnableEXT { VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, - VK_VALIDATION_FEATURE_ENABLE_BEGIN_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT, - VK_VALIDATION_FEATURE_ENABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT, - VK_VALIDATION_FEATURE_ENABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT + 1), + VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2, + VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3, + VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT = 4, VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationFeatureEnableEXT; @@ -9332,9 +11276,7 @@ typedef enum VkValidationFeatureDisableEXT { VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, - VK_VALIDATION_FEATURE_DISABLE_BEGIN_RANGE_EXT = VK_VALIDATION_FEATURE_DISABLE_ALL_EXT, - VK_VALIDATION_FEATURE_DISABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT, - VK_VALIDATION_FEATURE_DISABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT - VK_VALIDATION_FEATURE_DISABLE_ALL_EXT + 1), + VK_VALIDATION_FEATURE_DISABLE_SHADER_VALIDATION_CACHE_EXT = 7, VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationFeatureDisableEXT; typedef struct VkValidationFeaturesEXT { @@ -9364,9 +11306,6 @@ typedef enum VkComponentTypeNV { VK_COMPONENT_TYPE_UINT16_NV = 8, VK_COMPONENT_TYPE_UINT32_NV = 9, VK_COMPONENT_TYPE_UINT64_NV = 10, - VK_COMPONENT_TYPE_BEGIN_RANGE_NV = VK_COMPONENT_TYPE_FLOAT16_NV, - VK_COMPONENT_TYPE_END_RANGE_NV = VK_COMPONENT_TYPE_UINT64_NV, - VK_COMPONENT_TYPE_RANGE_SIZE_NV = (VK_COMPONENT_TYPE_UINT64_NV - VK_COMPONENT_TYPE_FLOAT16_NV + 1), VK_COMPONENT_TYPE_MAX_ENUM_NV = 0x7FFFFFFF } VkComponentTypeNV; @@ -9375,9 +11314,6 @@ typedef enum VkScopeNV { VK_SCOPE_WORKGROUP_NV = 2, VK_SCOPE_SUBGROUP_NV = 3, VK_SCOPE_QUEUE_FAMILY_NV = 5, - VK_SCOPE_BEGIN_RANGE_NV = VK_SCOPE_DEVICE_NV, - VK_SCOPE_END_RANGE_NV = VK_SCOPE_QUEUE_FAMILY_NV, - VK_SCOPE_RANGE_SIZE_NV = (VK_SCOPE_QUEUE_FAMILY_NV - VK_SCOPE_DEVICE_NV + 1), VK_SCOPE_MAX_ENUM_NV = 0x7FFFFFFF } VkScopeNV; typedef struct VkCooperativeMatrixPropertiesNV { @@ -9423,9 +11359,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( typedef enum VkCoverageReductionModeNV { VK_COVERAGE_REDUCTION_MODE_MERGE_NV = 0, VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV = 1, - VK_COVERAGE_REDUCTION_MODE_BEGIN_RANGE_NV = VK_COVERAGE_REDUCTION_MODE_MERGE_NV, - VK_COVERAGE_REDUCTION_MODE_END_RANGE_NV = VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV, - VK_COVERAGE_REDUCTION_MODE_RANGE_SIZE_NV = (VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV - VK_COVERAGE_REDUCTION_MODE_MERGE_NV + 1), VK_COVERAGE_REDUCTION_MODE_MAX_ENUM_NV = 0x7FFFFFFF } VkCoverageReductionModeNV; typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV; @@ -9485,8 +11418,39 @@ typedef struct VkPhysicalDeviceYcbcrImageArraysFeaturesEXT { +#define VK_EXT_provoking_vertex 1 +#define VK_EXT_PROVOKING_VERTEX_SPEC_VERSION 1 +#define VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME "VK_EXT_provoking_vertex" + +typedef enum VkProvokingVertexModeEXT { + VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT = 0, + VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT = 1, + VK_PROVOKING_VERTEX_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkProvokingVertexModeEXT; +typedef struct VkPhysicalDeviceProvokingVertexFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 provokingVertexLast; + VkBool32 transformFeedbackPreservesProvokingVertex; +} VkPhysicalDeviceProvokingVertexFeaturesEXT; + +typedef struct VkPhysicalDeviceProvokingVertexPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 provokingVertexModePerPipeline; + VkBool32 transformFeedbackPreservesTriangleFanProvokingVertex; +} VkPhysicalDeviceProvokingVertexPropertiesEXT; + +typedef struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkProvokingVertexModeEXT provokingVertexMode; +} VkPipelineRasterizationProvokingVertexStateCreateInfoEXT; + + + #define VK_EXT_headless_surface 1 -#define VK_EXT_HEADLESS_SURFACE_SPEC_VERSION 0 +#define VK_EXT_HEADLESS_SURFACE_SPEC_VERSION 1 #define VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME "VK_EXT_headless_surface" typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT; typedef struct VkHeadlessSurfaceCreateInfoEXT { @@ -9506,14 +11470,79 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT( #endif +#define VK_EXT_line_rasterization 1 +#define VK_EXT_LINE_RASTERIZATION_SPEC_VERSION 1 +#define VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME "VK_EXT_line_rasterization" + +typedef enum VkLineRasterizationModeEXT { + VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT = 0, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = 1, + VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = 2, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = 3, + VK_LINE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkLineRasterizationModeEXT; +typedef struct VkPhysicalDeviceLineRasterizationFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 rectangularLines; + VkBool32 bresenhamLines; + VkBool32 smoothLines; + VkBool32 stippledRectangularLines; + VkBool32 stippledBresenhamLines; + VkBool32 stippledSmoothLines; +} VkPhysicalDeviceLineRasterizationFeaturesEXT; + +typedef struct VkPhysicalDeviceLineRasterizationPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t lineSubPixelPrecisionBits; +} VkPhysicalDeviceLineRasterizationPropertiesEXT; + +typedef struct VkPipelineRasterizationLineStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkLineRasterizationModeEXT lineRasterizationMode; + VkBool32 stippledLineEnable; + uint32_t lineStippleFactor; + uint16_t lineStipplePattern; +} VkPipelineRasterizationLineStateCreateInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleEXT)(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEXT( + VkCommandBuffer commandBuffer, + uint32_t lineStippleFactor, + uint16_t lineStipplePattern); +#endif + + +#define VK_EXT_shader_atomic_float 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_SPEC_VERSION 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME "VK_EXT_shader_atomic_float" +typedef struct VkPhysicalDeviceShaderAtomicFloatFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferFloat32Atomics; + VkBool32 shaderBufferFloat32AtomicAdd; + VkBool32 shaderBufferFloat64Atomics; + VkBool32 shaderBufferFloat64AtomicAdd; + VkBool32 shaderSharedFloat32Atomics; + VkBool32 shaderSharedFloat32AtomicAdd; + VkBool32 shaderSharedFloat64Atomics; + VkBool32 shaderSharedFloat64AtomicAdd; + VkBool32 shaderImageFloat32Atomics; + VkBool32 shaderImageFloat32AtomicAdd; + VkBool32 sparseImageFloat32Atomics; + VkBool32 sparseImageFloat32AtomicAdd; +} VkPhysicalDeviceShaderAtomicFloatFeaturesEXT; + + + #define VK_EXT_host_query_reset 1 #define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1 #define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset" -typedef struct VkPhysicalDeviceHostQueryResetFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 hostQueryReset; -} VkPhysicalDeviceHostQueryResetFeaturesEXT; +typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT; typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); @@ -9526,6 +11555,123 @@ VKAPI_ATTR void VKAPI_CALL vkResetQueryPoolEXT( #endif +#define VK_EXT_index_type_uint8 1 +#define VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION 1 +#define VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME "VK_EXT_index_type_uint8" +typedef struct VkPhysicalDeviceIndexTypeUint8FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 indexTypeUint8; +} VkPhysicalDeviceIndexTypeUint8FeaturesEXT; + + + +#define VK_EXT_extended_dynamic_state 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_SPEC_VERSION 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_extended_dynamic_state" +typedef struct VkPhysicalDeviceExtendedDynamicStateFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 extendedDynamicState; +} VkPhysicalDeviceExtendedDynamicStateFeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetCullModeEXT)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFaceEXT)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopologyEXT)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2EXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOpEXT)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOpEXT)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetCullModeEXT( + VkCommandBuffer commandBuffer, + VkCullModeFlags cullMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFaceEXT( + VkCommandBuffer commandBuffer, + VkFrontFace frontFace); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopologyEXT( + VkCommandBuffer commandBuffer, + VkPrimitiveTopology primitiveTopology); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCountEXT( + VkCommandBuffer commandBuffer, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCountEXT( + VkCommandBuffer commandBuffer, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2EXT( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes, + const VkDeviceSize* pStrides); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthWriteEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOpEXT( + VkCommandBuffer commandBuffer, + VkCompareOp depthCompareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthBoundsTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 stencilTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + VkStencilOp failOp, + VkStencilOp passOp, + VkStencilOp depthFailOp, + VkCompareOp compareOp); +#endif + + +#define VK_EXT_shader_atomic_float2 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME "VK_EXT_shader_atomic_float2" +typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferFloat16Atomics; + VkBool32 shaderBufferFloat16AtomicAdd; + VkBool32 shaderBufferFloat16AtomicMinMax; + VkBool32 shaderBufferFloat32AtomicMinMax; + VkBool32 shaderBufferFloat64AtomicMinMax; + VkBool32 shaderSharedFloat16Atomics; + VkBool32 shaderSharedFloat16AtomicAdd; + VkBool32 shaderSharedFloat16AtomicMinMax; + VkBool32 shaderSharedFloat32AtomicMinMax; + VkBool32 shaderSharedFloat64AtomicMinMax; + VkBool32 shaderImageFloat32AtomicMinMax; + VkBool32 sparseImageFloat32AtomicMinMax; +} VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT; + + + #define VK_EXT_shader_demote_to_helper_invocation 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation" @@ -9537,6 +11683,215 @@ typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT { +#define VK_NV_device_generated_commands 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNV) +#define VK_NV_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 +#define VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NV_device_generated_commands" + +typedef enum VkIndirectCommandsTokenTypeNV { + VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV = 0, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV = 1, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV = 2, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV = 3, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV = 4, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV = 5, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV = 6, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV = 7, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectCommandsTokenTypeNV; + +typedef enum VkIndirectStateFlagBitsNV { + VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV = 0x00000001, + VK_INDIRECT_STATE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectStateFlagBitsNV; +typedef VkFlags VkIndirectStateFlagsNV; + +typedef enum VkIndirectCommandsLayoutUsageFlagBitsNV { + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV = 0x00000001, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV = 0x00000002, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV = 0x00000004, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectCommandsLayoutUsageFlagBitsNV; +typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNV; +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxGraphicsShaderGroupCount; + uint32_t maxIndirectSequenceCount; + uint32_t maxIndirectCommandsTokenCount; + uint32_t maxIndirectCommandsStreamCount; + uint32_t maxIndirectCommandsTokenOffset; + uint32_t maxIndirectCommandsStreamStride; + uint32_t minSequencesCountBufferOffsetAlignment; + uint32_t minSequencesIndexBufferOffsetAlignment; + uint32_t minIndirectCommandsBufferOffsetAlignment; +} VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV; + +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 deviceGeneratedCommands; +} VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV; + +typedef struct VkGraphicsShaderGroupCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineTessellationStateCreateInfo* pTessellationState; +} VkGraphicsShaderGroupCreateInfoNV; + +typedef struct VkGraphicsPipelineShaderGroupsCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t groupCount; + const VkGraphicsShaderGroupCreateInfoNV* pGroups; + uint32_t pipelineCount; + const VkPipeline* pPipelines; +} VkGraphicsPipelineShaderGroupsCreateInfoNV; + +typedef struct VkBindShaderGroupIndirectCommandNV { + uint32_t groupIndex; +} VkBindShaderGroupIndirectCommandNV; + +typedef struct VkBindIndexBufferIndirectCommandNV { + VkDeviceAddress bufferAddress; + uint32_t size; + VkIndexType indexType; +} VkBindIndexBufferIndirectCommandNV; + +typedef struct VkBindVertexBufferIndirectCommandNV { + VkDeviceAddress bufferAddress; + uint32_t size; + uint32_t stride; +} VkBindVertexBufferIndirectCommandNV; + +typedef struct VkSetStateFlagsIndirectCommandNV { + uint32_t data; +} VkSetStateFlagsIndirectCommandNV; + +typedef struct VkIndirectCommandsStreamNV { + VkBuffer buffer; + VkDeviceSize offset; +} VkIndirectCommandsStreamNV; + +typedef struct VkIndirectCommandsLayoutTokenNV { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsTokenTypeNV tokenType; + uint32_t stream; + uint32_t offset; + uint32_t vertexBindingUnit; + VkBool32 vertexDynamicStride; + VkPipelineLayout pushconstantPipelineLayout; + VkShaderStageFlags pushconstantShaderStageFlags; + uint32_t pushconstantOffset; + uint32_t pushconstantSize; + VkIndirectStateFlagsNV indirectStateFlags; + uint32_t indexTypeCount; + const VkIndexType* pIndexTypes; + const uint32_t* pIndexTypeValues; +} VkIndirectCommandsLayoutTokenNV; + +typedef struct VkIndirectCommandsLayoutCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsLayoutUsageFlagsNV flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t tokenCount; + const VkIndirectCommandsLayoutTokenNV* pTokens; + uint32_t streamCount; + const uint32_t* pStreamStrides; +} VkIndirectCommandsLayoutCreateInfoNV; + +typedef struct VkGeneratedCommandsInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkPipeline pipeline; + VkIndirectCommandsLayoutNV indirectCommandsLayout; + uint32_t streamCount; + const VkIndirectCommandsStreamNV* pStreams; + uint32_t sequencesCount; + VkBuffer preprocessBuffer; + VkDeviceSize preprocessOffset; + VkDeviceSize preprocessSize; + VkBuffer sequencesCountBuffer; + VkDeviceSize sequencesCountOffset; + VkBuffer sequencesIndexBuffer; + VkDeviceSize sequencesIndexOffset; +} VkGeneratedCommandsInfoNV; + +typedef struct VkGeneratedCommandsMemoryRequirementsInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkPipeline pipeline; + VkIndirectCommandsLayoutNV indirectCommandsLayout; + uint32_t maxSequencesCount; +} VkGeneratedCommandsMemoryRequirementsInfoNV; + +typedef void (VKAPI_PTR *PFN_vkGetGeneratedCommandsMemoryRequirementsNV)(VkDevice device, const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdPreprocessGeneratedCommandsNV)(VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteGeneratedCommandsNV)(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipelineShaderGroupNV)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline, uint32_t groupIndex); +typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNV)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNV)(VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetGeneratedCommandsMemoryRequirementsNV( + VkDevice device, + const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkCmdPreprocessGeneratedCommandsNV( + VkCommandBuffer commandBuffer, + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteGeneratedCommandsNV( + VkCommandBuffer commandBuffer, + VkBool32 isPreprocessed, + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipelineShaderGroupNV( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline, + uint32_t groupIndex); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNV( + VkDevice device, + const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNV( + VkDevice device, + VkIndirectCommandsLayoutNV indirectCommandsLayout, + const VkAllocationCallbacks* pAllocator); +#endif + + +#define VK_NV_inherited_viewport_scissor 1 +#define VK_NV_INHERITED_VIEWPORT_SCISSOR_SPEC_VERSION 1 +#define VK_NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME "VK_NV_inherited_viewport_scissor" +typedef struct VkPhysicalDeviceInheritedViewportScissorFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 inheritedViewportScissor2D; +} VkPhysicalDeviceInheritedViewportScissorFeaturesNV; + +typedef struct VkCommandBufferInheritanceViewportScissorInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 viewportScissor2D; + uint32_t viewportDepthCount; + const VkViewport* pViewportDepths; +} VkCommandBufferInheritanceViewportScissorInfoNV; + + + #define VK_EXT_texel_buffer_alignment 1 #define VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION 1 #define VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME "VK_EXT_texel_buffer_alignment" @@ -9556,6 +11911,1209 @@ typedef struct VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT { } VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; + +#define VK_QCOM_render_pass_transform 1 +#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 2 +#define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform" +typedef struct VkRenderPassTransformBeginInfoQCOM { + VkStructureType sType; + void* pNext; + VkSurfaceTransformFlagBitsKHR transform; +} VkRenderPassTransformBeginInfoQCOM; + +typedef struct VkCommandBufferInheritanceRenderPassTransformInfoQCOM { + VkStructureType sType; + void* pNext; + VkSurfaceTransformFlagBitsKHR transform; + VkRect2D renderArea; +} VkCommandBufferInheritanceRenderPassTransformInfoQCOM; + + + +#define VK_EXT_device_memory_report 1 +#define VK_EXT_DEVICE_MEMORY_REPORT_SPEC_VERSION 2 +#define VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME "VK_EXT_device_memory_report" + +typedef enum VkDeviceMemoryReportEventTypeEXT { + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT = 0, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT = 1, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT = 2, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT = 3, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT = 4, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceMemoryReportEventTypeEXT; +typedef VkFlags VkDeviceMemoryReportFlagsEXT; +typedef struct VkPhysicalDeviceDeviceMemoryReportFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 deviceMemoryReport; +} VkPhysicalDeviceDeviceMemoryReportFeaturesEXT; + +typedef struct VkDeviceMemoryReportCallbackDataEXT { + VkStructureType sType; + void* pNext; + VkDeviceMemoryReportFlagsEXT flags; + VkDeviceMemoryReportEventTypeEXT type; + uint64_t memoryObjectId; + VkDeviceSize size; + VkObjectType objectType; + uint64_t objectHandle; + uint32_t heapIndex; +} VkDeviceMemoryReportCallbackDataEXT; + +typedef void (VKAPI_PTR *PFN_vkDeviceMemoryReportCallbackEXT)( + const VkDeviceMemoryReportCallbackDataEXT* pCallbackData, + void* pUserData); + +typedef struct VkDeviceDeviceMemoryReportCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceMemoryReportFlagsEXT flags; + PFN_vkDeviceMemoryReportCallbackEXT pfnUserCallback; + void* pUserData; +} VkDeviceDeviceMemoryReportCreateInfoEXT; + + + +#define VK_EXT_acquire_drm_display 1 +#define VK_EXT_ACQUIRE_DRM_DISPLAY_SPEC_VERSION 1 +#define VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_drm_display" +typedef VkResult (VKAPI_PTR *PFN_vkAcquireDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, VkDisplayKHR display); +typedef VkResult (VKAPI_PTR *PFN_vkGetDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId, VkDisplayKHR* display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireDrmDisplayEXT( + VkPhysicalDevice physicalDevice, + int32_t drmFd, + VkDisplayKHR display); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDrmDisplayEXT( + VkPhysicalDevice physicalDevice, + int32_t drmFd, + uint32_t connectorId, + VkDisplayKHR* display); +#endif + + +#define VK_EXT_robustness2 1 +#define VK_EXT_ROBUSTNESS_2_SPEC_VERSION 1 +#define VK_EXT_ROBUSTNESS_2_EXTENSION_NAME "VK_EXT_robustness2" +typedef struct VkPhysicalDeviceRobustness2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 robustBufferAccess2; + VkBool32 robustImageAccess2; + VkBool32 nullDescriptor; +} VkPhysicalDeviceRobustness2FeaturesEXT; + +typedef struct VkPhysicalDeviceRobustness2PropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize robustStorageBufferAccessSizeAlignment; + VkDeviceSize robustUniformBufferAccessSizeAlignment; +} VkPhysicalDeviceRobustness2PropertiesEXT; + + + +#define VK_EXT_custom_border_color 1 +#define VK_EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION 12 +#define VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME "VK_EXT_custom_border_color" +typedef struct VkSamplerCustomBorderColorCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkClearColorValue customBorderColor; + VkFormat format; +} VkSamplerCustomBorderColorCreateInfoEXT; + +typedef struct VkPhysicalDeviceCustomBorderColorPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxCustomBorderColorSamplers; +} VkPhysicalDeviceCustomBorderColorPropertiesEXT; + +typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 customBorderColors; + VkBool32 customBorderColorWithoutFormat; +} VkPhysicalDeviceCustomBorderColorFeaturesEXT; + + + +#define VK_GOOGLE_user_type 1 +#define VK_GOOGLE_USER_TYPE_SPEC_VERSION 1 +#define VK_GOOGLE_USER_TYPE_EXTENSION_NAME "VK_GOOGLE_user_type" + + +#define VK_EXT_private_data 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlotEXT) +#define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1 +#define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data" + +typedef enum VkPrivateDataSlotCreateFlagBitsEXT { + VK_PRIVATE_DATA_SLOT_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPrivateDataSlotCreateFlagBitsEXT; +typedef VkFlags VkPrivateDataSlotCreateFlagsEXT; +typedef struct VkPhysicalDevicePrivateDataFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 privateData; +} VkPhysicalDevicePrivateDataFeaturesEXT; + +typedef struct VkDevicePrivateDataCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t privateDataSlotRequestCount; +} VkDevicePrivateDataCreateInfoEXT; + +typedef struct VkPrivateDataSlotCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPrivateDataSlotCreateFlagsEXT flags; +} VkPrivateDataSlotCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlotEXT* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlotEXT privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( + VkDevice device, + const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlotEXT* pPrivateDataSlot); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( + VkDevice device, + VkPrivateDataSlotEXT privateDataSlot, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlotEXT privateDataSlot, + uint64_t data); + +VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlotEXT privateDataSlot, + uint64_t* pData); +#endif + + +#define VK_EXT_pipeline_creation_cache_control 1 +#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3 +#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control" +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; + + + +#define VK_NV_device_diagnostics_config 1 +#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION 1 +#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME "VK_NV_device_diagnostics_config" + +typedef enum VkDeviceDiagnosticsConfigFlagBitsNV { + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV = 0x00000001, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV = 0x00000002, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV = 0x00000004, + VK_DEVICE_DIAGNOSTICS_CONFIG_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkDeviceDiagnosticsConfigFlagBitsNV; +typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV; +typedef struct VkPhysicalDeviceDiagnosticsConfigFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 diagnosticsConfig; +} VkPhysicalDeviceDiagnosticsConfigFeaturesNV; + +typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceDiagnosticsConfigFlagsNV flags; +} VkDeviceDiagnosticsConfigCreateInfoNV; + + + +#define VK_QCOM_render_pass_store_ops 1 +#define VK_QCOM_RENDER_PASS_STORE_OPS_SPEC_VERSION 2 +#define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" + + +#define VK_NV_fragment_shading_rate_enums 1 +#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums" + +typedef enum VkFragmentShadingRateTypeNV { + VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV = 0, + VK_FRAGMENT_SHADING_RATE_TYPE_ENUMS_NV = 1, + VK_FRAGMENT_SHADING_RATE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkFragmentShadingRateTypeNV; + +typedef enum VkFragmentShadingRateNV { + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV = 0, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV = 1, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV = 4, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV = 5, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV = 6, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV = 9, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV = 10, + VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV = 11, + VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV = 12, + VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV = 13, + VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV = 14, + VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV = 15, + VK_FRAGMENT_SHADING_RATE_MAX_ENUM_NV = 0x7FFFFFFF +} VkFragmentShadingRateNV; +typedef struct VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 fragmentShadingRateEnums; + VkBool32 supersampleFragmentShadingRates; + VkBool32 noInvocationFragmentShadingRates; +} VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV; + +typedef struct VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV { + VkStructureType sType; + void* pNext; + VkSampleCountFlagBits maxFragmentShadingRateInvocationCount; +} VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV; + +typedef struct VkPipelineFragmentShadingRateEnumStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkFragmentShadingRateTypeNV shadingRateType; + VkFragmentShadingRateNV shadingRate; + VkFragmentShadingRateCombinerOpKHR combinerOps[2]; +} VkPipelineFragmentShadingRateEnumStateCreateInfoNV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateEnumNV)(VkCommandBuffer commandBuffer, VkFragmentShadingRateNV shadingRate, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateEnumNV( + VkCommandBuffer commandBuffer, + VkFragmentShadingRateNV shadingRate, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); +#endif + + +#define VK_NV_ray_tracing_motion_blur 1 +#define VK_NV_RAY_TRACING_MOTION_BLUR_SPEC_VERSION 1 +#define VK_NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME "VK_NV_ray_tracing_motion_blur" + +typedef enum VkAccelerationStructureMotionInstanceTypeNV { + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_STATIC_NV = 0, + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MATRIX_MOTION_NV = 1, + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_SRT_MOTION_NV = 2, + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkAccelerationStructureMotionInstanceTypeNV; +typedef VkFlags VkAccelerationStructureMotionInfoFlagsNV; +typedef VkFlags VkAccelerationStructureMotionInstanceFlagsNV; +typedef union VkDeviceOrHostAddressConstKHR { + VkDeviceAddress deviceAddress; + const void* hostAddress; +} VkDeviceOrHostAddressConstKHR; + +typedef struct VkAccelerationStructureGeometryMotionTrianglesDataNV { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR vertexData; +} VkAccelerationStructureGeometryMotionTrianglesDataNV; + +typedef struct VkAccelerationStructureMotionInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t maxInstances; + VkAccelerationStructureMotionInfoFlagsNV flags; +} VkAccelerationStructureMotionInfoNV; + +typedef struct VkAccelerationStructureMatrixMotionInstanceNV { + VkTransformMatrixKHR transformT0; + VkTransformMatrixKHR transformT1; + uint32_t instanceCustomIndex:24; + uint32_t mask:8; + uint32_t instanceShaderBindingTableRecordOffset:24; + VkGeometryInstanceFlagsKHR flags:8; + uint64_t accelerationStructureReference; +} VkAccelerationStructureMatrixMotionInstanceNV; + +typedef struct VkSRTDataNV { + float sx; + float a; + float b; + float pvx; + float sy; + float c; + float pvy; + float sz; + float pvz; + float qx; + float qy; + float qz; + float qw; + float tx; + float ty; + float tz; +} VkSRTDataNV; + +typedef struct VkAccelerationStructureSRTMotionInstanceNV { + VkSRTDataNV transformT0; + VkSRTDataNV transformT1; + uint32_t instanceCustomIndex:24; + uint32_t mask:8; + uint32_t instanceShaderBindingTableRecordOffset:24; + VkGeometryInstanceFlagsKHR flags:8; + uint64_t accelerationStructureReference; +} VkAccelerationStructureSRTMotionInstanceNV; + +typedef union VkAccelerationStructureMotionInstanceDataNV { + VkAccelerationStructureInstanceKHR staticInstance; + VkAccelerationStructureMatrixMotionInstanceNV matrixMotionInstance; + VkAccelerationStructureSRTMotionInstanceNV srtMotionInstance; +} VkAccelerationStructureMotionInstanceDataNV; + +typedef struct VkAccelerationStructureMotionInstanceNV { + VkAccelerationStructureMotionInstanceTypeNV type; + VkAccelerationStructureMotionInstanceFlagsNV flags; + VkAccelerationStructureMotionInstanceDataNV data; +} VkAccelerationStructureMotionInstanceNV; + +typedef struct VkPhysicalDeviceRayTracingMotionBlurFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingMotionBlur; + VkBool32 rayTracingMotionBlurPipelineTraceRaysIndirect; +} VkPhysicalDeviceRayTracingMotionBlurFeaturesNV; + + + +#define VK_EXT_ycbcr_2plane_444_formats 1 +#define VK_EXT_YCBCR_2PLANE_444_FORMATS_SPEC_VERSION 1 +#define VK_EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME "VK_EXT_ycbcr_2plane_444_formats" +typedef struct VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 ycbcr2plane444Formats; +} VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT; + + + +#define VK_EXT_fragment_density_map2 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_2_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME "VK_EXT_fragment_density_map2" +typedef struct VkPhysicalDeviceFragmentDensityMap2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMapDeferred; +} VkPhysicalDeviceFragmentDensityMap2FeaturesEXT; + +typedef struct VkPhysicalDeviceFragmentDensityMap2PropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 subsampledLoads; + VkBool32 subsampledCoarseReconstructionEarlyAccess; + uint32_t maxSubsampledArrayLayers; + uint32_t maxDescriptorSetSubsampledSamplers; +} VkPhysicalDeviceFragmentDensityMap2PropertiesEXT; + + + +#define VK_QCOM_rotated_copy_commands 1 +#define VK_QCOM_ROTATED_COPY_COMMANDS_SPEC_VERSION 1 +#define VK_QCOM_ROTATED_COPY_COMMANDS_EXTENSION_NAME "VK_QCOM_rotated_copy_commands" +typedef struct VkCopyCommandTransformInfoQCOM { + VkStructureType sType; + const void* pNext; + VkSurfaceTransformFlagBitsKHR transform; +} VkCopyCommandTransformInfoQCOM; + + + +#define VK_EXT_image_robustness 1 +#define VK_EXT_IMAGE_ROBUSTNESS_SPEC_VERSION 1 +#define VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_image_robustness" +typedef struct VkPhysicalDeviceImageRobustnessFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; +} VkPhysicalDeviceImageRobustnessFeaturesEXT; + + + +#define VK_EXT_4444_formats 1 +#define VK_EXT_4444_FORMATS_SPEC_VERSION 1 +#define VK_EXT_4444_FORMATS_EXTENSION_NAME "VK_EXT_4444_formats" +typedef struct VkPhysicalDevice4444FormatsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 formatA4R4G4B4; + VkBool32 formatA4B4G4R4; +} VkPhysicalDevice4444FormatsFeaturesEXT; + + + +#define VK_NV_acquire_winrt_display 1 +#define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1 +#define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display" +typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); +typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV( + VkPhysicalDevice physicalDevice, + uint32_t deviceRelativeId, + VkDisplayKHR* pDisplay); +#endif + + +#define VK_VALVE_mutable_descriptor_type 1 +#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION 1 +#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_VALVE_mutable_descriptor_type" +typedef struct VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 mutableDescriptorType; +} VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE; + +typedef struct VkMutableDescriptorTypeListVALVE { + uint32_t descriptorTypeCount; + const VkDescriptorType* pDescriptorTypes; +} VkMutableDescriptorTypeListVALVE; + +typedef struct VkMutableDescriptorTypeCreateInfoVALVE { + VkStructureType sType; + const void* pNext; + uint32_t mutableDescriptorTypeListCount; + const VkMutableDescriptorTypeListVALVE* pMutableDescriptorTypeLists; +} VkMutableDescriptorTypeCreateInfoVALVE; + + + +#define VK_EXT_vertex_input_dynamic_state 1 +#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_SPEC_VERSION 2 +#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_vertex_input_dynamic_state" +typedef struct VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 vertexInputDynamicState; +} VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT; + +typedef struct VkVertexInputBindingDescription2EXT { + VkStructureType sType; + void* pNext; + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; + uint32_t divisor; +} VkVertexInputBindingDescription2EXT; + +typedef struct VkVertexInputAttributeDescription2EXT { + VkStructureType sType; + void* pNext; + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription2EXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetVertexInputEXT)(VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount, const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount, const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetVertexInputEXT( + VkCommandBuffer commandBuffer, + uint32_t vertexBindingDescriptionCount, + const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, + uint32_t vertexAttributeDescriptionCount, + const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); +#endif + + +#define VK_EXT_physical_device_drm 1 +#define VK_EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION 1 +#define VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME "VK_EXT_physical_device_drm" +typedef struct VkPhysicalDeviceDrmPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 hasPrimary; + VkBool32 hasRender; + int64_t primaryMajor; + int64_t primaryMinor; + int64_t renderMajor; + int64_t renderMinor; +} VkPhysicalDeviceDrmPropertiesEXT; + + + +#define VK_HUAWEI_subpass_shading 1 +#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 2 +#define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading" +typedef struct VkSubpassShadingPipelineCreateInfoHUAWEI { + VkStructureType sType; + void* pNext; + VkRenderPass renderPass; + uint32_t subpass; +} VkSubpassShadingPipelineCreateInfoHUAWEI; + +typedef struct VkPhysicalDeviceSubpassShadingFeaturesHUAWEI { + VkStructureType sType; + void* pNext; + VkBool32 subpassShading; +} VkPhysicalDeviceSubpassShadingFeaturesHUAWEI; + +typedef struct VkPhysicalDeviceSubpassShadingPropertiesHUAWEI { + VkStructureType sType; + void* pNext; + uint32_t maxSubpassShadingWorkgroupSizeAspectRatio; +} VkPhysicalDeviceSubpassShadingPropertiesHUAWEI; + +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)(VkDevice device, VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize); +typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( + VkDevice device, + VkRenderPass renderpass, + VkExtent2D* pMaxWorkgroupSize); + +VKAPI_ATTR void VKAPI_CALL vkCmdSubpassShadingHUAWEI( + VkCommandBuffer commandBuffer); +#endif + + +#define VK_HUAWEI_invocation_mask 1 +#define VK_HUAWEI_INVOCATION_MASK_SPEC_VERSION 1 +#define VK_HUAWEI_INVOCATION_MASK_EXTENSION_NAME "VK_HUAWEI_invocation_mask" +typedef struct VkPhysicalDeviceInvocationMaskFeaturesHUAWEI { + VkStructureType sType; + void* pNext; + VkBool32 invocationMask; +} VkPhysicalDeviceInvocationMaskFeaturesHUAWEI; + +typedef void (VKAPI_PTR *PFN_vkCmdBindInvocationMaskHUAWEI)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindInvocationMaskHUAWEI( + VkCommandBuffer commandBuffer, + VkImageView imageView, + VkImageLayout imageLayout); +#endif + + +#define VK_NV_external_memory_rdma 1 +typedef void* VkRemoteAddressNV; +#define VK_NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME "VK_NV_external_memory_rdma" +typedef struct VkMemoryGetRemoteAddressInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetRemoteAddressInfoNV; + +typedef struct VkPhysicalDeviceExternalMemoryRDMAFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 externalMemoryRDMA; +} VkPhysicalDeviceExternalMemoryRDMAFeaturesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryRemoteAddressNV)(VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV( + VkDevice device, + const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, + VkRemoteAddressNV* pAddress); +#endif + + +#define VK_EXT_extended_dynamic_state2 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2" +typedef struct VkPhysicalDeviceExtendedDynamicState2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 extendedDynamicState2; + VkBool32 extendedDynamicState2LogicOp; + VkBool32 extendedDynamicState2PatchControlPoints; +} VkPhysicalDeviceExtendedDynamicState2FeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetPatchControlPointsEXT)(VkCommandBuffer commandBuffer, uint32_t patchControlPoints); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetLogicOpEXT)(VkCommandBuffer commandBuffer, VkLogicOp logicOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetPatchControlPointsEXT( + VkCommandBuffer commandBuffer, + uint32_t patchControlPoints); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthBiasEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEXT( + VkCommandBuffer commandBuffer, + VkLogicOp logicOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 primitiveRestartEnable); +#endif + + +#define VK_EXT_color_write_enable 1 +#define VK_EXT_COLOR_WRITE_ENABLE_SPEC_VERSION 1 +#define VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME "VK_EXT_color_write_enable" +typedef struct VkPhysicalDeviceColorWriteEnableFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 colorWriteEnable; +} VkPhysicalDeviceColorWriteEnableFeaturesEXT; + +typedef struct VkPipelineColorWriteCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t attachmentCount; + const VkBool32* pColorWriteEnables; +} VkPipelineColorWriteCreateInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteEnableEXT)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32* pColorWriteEnables); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteEnableEXT( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkBool32* pColorWriteEnables); +#endif + + +#define VK_EXT_global_priority_query 1 +#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT 16U +#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" +typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 globalPriorityQuery; +} VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + +typedef struct VkQueueFamilyGlobalPriorityPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t priorityCount; + VkQueueGlobalPriorityEXT priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_EXT]; +} VkQueueFamilyGlobalPriorityPropertiesEXT; + + + +#define VK_EXT_multi_draw 1 +#define VK_EXT_MULTI_DRAW_SPEC_VERSION 1 +#define VK_EXT_MULTI_DRAW_EXTENSION_NAME "VK_EXT_multi_draw" +typedef struct VkPhysicalDeviceMultiDrawFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 multiDraw; +} VkPhysicalDeviceMultiDrawFeaturesEXT; + +typedef struct VkPhysicalDeviceMultiDrawPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxMultiDrawCount; +} VkPhysicalDeviceMultiDrawPropertiesEXT; + +typedef struct VkMultiDrawInfoEXT { + uint32_t firstVertex; + uint32_t vertexCount; +} VkMultiDrawInfoEXT; + +typedef struct VkMultiDrawIndexedInfoEXT { + uint32_t firstIndex; + uint32_t indexCount; + int32_t vertexOffset; +} VkMultiDrawIndexedInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawInfoEXT* pVertexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiIndexedEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawIndexedInfoEXT* pIndexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride, const int32_t* pVertexOffset); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiEXT( + VkCommandBuffer commandBuffer, + uint32_t drawCount, + const VkMultiDrawInfoEXT* pVertexInfo, + uint32_t instanceCount, + uint32_t firstInstance, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( + VkCommandBuffer commandBuffer, + uint32_t drawCount, + const VkMultiDrawIndexedInfoEXT* pIndexInfo, + uint32_t instanceCount, + uint32_t firstInstance, + uint32_t stride, + const int32_t* pVertexOffset); +#endif + + +#define VK_EXT_load_store_op_none 1 +#define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1 +#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none" + + +#define VK_KHR_acceleration_structure 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) +#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 12 +#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" + +typedef enum VkBuildAccelerationStructureModeKHR { + VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR = 0, + VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR = 1, + VK_BUILD_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkBuildAccelerationStructureModeKHR; + +typedef enum VkAccelerationStructureBuildTypeKHR { + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR = 0, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR = 1, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR = 2, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureBuildTypeKHR; + +typedef enum VkAccelerationStructureCompatibilityKHR { + VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR = 0, + VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR = 1, + VK_ACCELERATION_STRUCTURE_COMPATIBILITY_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureCompatibilityKHR; + +typedef enum VkAccelerationStructureCreateFlagBitsKHR { + VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000001, + VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV = 0x00000004, + VK_ACCELERATION_STRUCTURE_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureCreateFlagBitsKHR; +typedef VkFlags VkAccelerationStructureCreateFlagsKHR; +typedef union VkDeviceOrHostAddressKHR { + VkDeviceAddress deviceAddress; + void* hostAddress; +} VkDeviceOrHostAddressKHR; + +typedef struct VkAccelerationStructureBuildRangeInfoKHR { + uint32_t primitiveCount; + uint32_t primitiveOffset; + uint32_t firstVertex; + uint32_t transformOffset; +} VkAccelerationStructureBuildRangeInfoKHR; + +typedef struct VkAccelerationStructureGeometryTrianglesDataKHR { + VkStructureType sType; + const void* pNext; + VkFormat vertexFormat; + VkDeviceOrHostAddressConstKHR vertexData; + VkDeviceSize vertexStride; + uint32_t maxVertex; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexData; + VkDeviceOrHostAddressConstKHR transformData; +} VkAccelerationStructureGeometryTrianglesDataKHR; + +typedef struct VkAccelerationStructureGeometryAabbsDataKHR { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR data; + VkDeviceSize stride; +} VkAccelerationStructureGeometryAabbsDataKHR; + +typedef struct VkAccelerationStructureGeometryInstancesDataKHR { + VkStructureType sType; + const void* pNext; + VkBool32 arrayOfPointers; + VkDeviceOrHostAddressConstKHR data; +} VkAccelerationStructureGeometryInstancesDataKHR; + +typedef union VkAccelerationStructureGeometryDataKHR { + VkAccelerationStructureGeometryTrianglesDataKHR triangles; + VkAccelerationStructureGeometryAabbsDataKHR aabbs; + VkAccelerationStructureGeometryInstancesDataKHR instances; +} VkAccelerationStructureGeometryDataKHR; + +typedef struct VkAccelerationStructureGeometryKHR { + VkStructureType sType; + const void* pNext; + VkGeometryTypeKHR geometryType; + VkAccelerationStructureGeometryDataKHR geometry; + VkGeometryFlagsKHR flags; +} VkAccelerationStructureGeometryKHR; + +typedef struct VkAccelerationStructureBuildGeometryInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureTypeKHR type; + VkBuildAccelerationStructureFlagsKHR flags; + VkBuildAccelerationStructureModeKHR mode; + VkAccelerationStructureKHR srcAccelerationStructure; + VkAccelerationStructureKHR dstAccelerationStructure; + uint32_t geometryCount; + const VkAccelerationStructureGeometryKHR* pGeometries; + const VkAccelerationStructureGeometryKHR* const* ppGeometries; + VkDeviceOrHostAddressKHR scratchData; +} VkAccelerationStructureBuildGeometryInfoKHR; + +typedef struct VkAccelerationStructureCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureCreateFlagsKHR createFlags; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; + VkAccelerationStructureTypeKHR type; + VkDeviceAddress deviceAddress; +} VkAccelerationStructureCreateInfoKHR; + +typedef struct VkWriteDescriptorSetAccelerationStructureKHR { + VkStructureType sType; + const void* pNext; + uint32_t accelerationStructureCount; + const VkAccelerationStructureKHR* pAccelerationStructures; +} VkWriteDescriptorSetAccelerationStructureKHR; + +typedef struct VkPhysicalDeviceAccelerationStructureFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 accelerationStructure; + VkBool32 accelerationStructureCaptureReplay; + VkBool32 accelerationStructureIndirectBuild; + VkBool32 accelerationStructureHostCommands; + VkBool32 descriptorBindingAccelerationStructureUpdateAfterBind; +} VkPhysicalDeviceAccelerationStructureFeaturesKHR; + +typedef struct VkPhysicalDeviceAccelerationStructurePropertiesKHR { + VkStructureType sType; + void* pNext; + uint64_t maxGeometryCount; + uint64_t maxInstanceCount; + uint64_t maxPrimitiveCount; + uint32_t maxPerStageDescriptorAccelerationStructures; + uint32_t maxPerStageDescriptorUpdateAfterBindAccelerationStructures; + uint32_t maxDescriptorSetAccelerationStructures; + uint32_t maxDescriptorSetUpdateAfterBindAccelerationStructures; + uint32_t minAccelerationStructureScratchOffsetAlignment; +} VkPhysicalDeviceAccelerationStructurePropertiesKHR; + +typedef struct VkAccelerationStructureDeviceAddressInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR accelerationStructure; +} VkAccelerationStructureDeviceAddressInfoKHR; + +typedef struct VkAccelerationStructureVersionInfoKHR { + VkStructureType sType; + const void* pNext; + const uint8_t* pVersionData; +} VkAccelerationStructureVersionInfoKHR; + +typedef struct VkCopyAccelerationStructureToMemoryInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR src; + VkDeviceOrHostAddressKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyAccelerationStructureToMemoryInfoKHR; + +typedef struct VkCopyMemoryToAccelerationStructureInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR src; + VkAccelerationStructureKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyMemoryToAccelerationStructureInfoKHR; + +typedef struct VkCopyAccelerationStructureInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR src; + VkAccelerationStructureKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyAccelerationStructureInfoKHR; + +typedef struct VkAccelerationStructureBuildSizesInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceSize accelerationStructureSize; + VkDeviceSize updateScratchSize; + VkDeviceSize buildScratchSize; +} VkAccelerationStructureBuildSizesInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureKHR)(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); +typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureKHR)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresIndirectKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkDeviceAddress* pIndirectDeviceAddresses, const uint32_t* pIndirectStrides, const uint32_t* const* ppMaxPrimitiveCounts); +typedef VkResult (VKAPI_PTR *PFN_vkBuildAccelerationStructuresKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); +typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureToMemoryKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkWriteAccelerationStructuresPropertiesKHR)(VkDevice device, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, size_t dataSize, void* pData, size_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureToMemoryKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetAccelerationStructureDeviceAddressKHR)(VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef void (VKAPI_PTR *PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)(VkDevice device, const VkAccelerationStructureVersionInfoKHR* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); +typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureBuildSizesKHR)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureKHR( + VkDevice device, + const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureKHR* pAccelerationStructure); + +VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureKHR( + VkDevice device, + VkAccelerationStructureKHR accelerationStructure, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresKHR( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresIndirectKHR( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkDeviceAddress* pIndirectDeviceAddresses, + const uint32_t* pIndirectStrides, + const uint32_t* const* ppMaxPrimitiveCounts); + +VKAPI_ATTR VkResult VKAPI_CALL vkBuildAccelerationStructuresKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureToMemoryKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToAccelerationStructureKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkWriteAccelerationStructuresPropertiesKHR( + VkDevice device, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + size_t dataSize, + void* pData, + size_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureToMemoryKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetAccelerationStructureDeviceAddressKHR( + VkDevice device, + const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesKHR( + VkCommandBuffer commandBuffer, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceAccelerationStructureCompatibilityKHR( + VkDevice device, + const VkAccelerationStructureVersionInfoKHR* pVersionInfo, + VkAccelerationStructureCompatibilityKHR* pCompatibility); + +VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureBuildSizesKHR( + VkDevice device, + VkAccelerationStructureBuildTypeKHR buildType, + const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, + const uint32_t* pMaxPrimitiveCounts, + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); +#endif + + +#define VK_KHR_ray_tracing_pipeline 1 +#define VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION 1 +#define VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME "VK_KHR_ray_tracing_pipeline" + +typedef enum VkShaderGroupShaderKHR { + VK_SHADER_GROUP_SHADER_GENERAL_KHR = 0, + VK_SHADER_GROUP_SHADER_CLOSEST_HIT_KHR = 1, + VK_SHADER_GROUP_SHADER_ANY_HIT_KHR = 2, + VK_SHADER_GROUP_SHADER_INTERSECTION_KHR = 3, + VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR = 0x7FFFFFFF +} VkShaderGroupShaderKHR; +typedef struct VkRayTracingShaderGroupCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkRayTracingShaderGroupTypeKHR type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; + const void* pShaderGroupCaptureReplayHandle; +} VkRayTracingShaderGroupCreateInfoKHR; + +typedef struct VkRayTracingPipelineInterfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t maxPipelineRayPayloadSize; + uint32_t maxPipelineRayHitAttributeSize; +} VkRayTracingPipelineInterfaceCreateInfoKHR; + +typedef struct VkRayTracingPipelineCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + uint32_t groupCount; + const VkRayTracingShaderGroupCreateInfoKHR* pGroups; + uint32_t maxPipelineRayRecursionDepth; + const VkPipelineLibraryCreateInfoKHR* pLibraryInfo; + const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface; + const VkPipelineDynamicStateCreateInfo* pDynamicState; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkRayTracingPipelineCreateInfoKHR; + +typedef struct VkPhysicalDeviceRayTracingPipelineFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingPipeline; + VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplay; + VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplayMixed; + VkBool32 rayTracingPipelineTraceRaysIndirect; + VkBool32 rayTraversalPrimitiveCulling; +} VkPhysicalDeviceRayTracingPipelineFeaturesKHR; + +typedef struct VkPhysicalDeviceRayTracingPipelinePropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t shaderGroupHandleSize; + uint32_t maxRayRecursionDepth; + uint32_t maxShaderGroupStride; + uint32_t shaderGroupBaseAlignment; + uint32_t shaderGroupHandleCaptureReplaySize; + uint32_t maxRayDispatchInvocationCount; + uint32_t shaderGroupHandleAlignment; + uint32_t maxRayHitAttributeSize; +} VkPhysicalDeviceRayTracingPipelinePropertiesKHR; + +typedef struct VkStridedDeviceAddressRegionKHR { + VkDeviceAddress deviceAddress; + VkDeviceSize stride; + VkDeviceSize size; +} VkStridedDeviceAddressRegionKHR; + +typedef struct VkTraceRaysIndirectCommandKHR { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkTraceRaysIndirectCommandKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, uint32_t width, uint32_t height, uint32_t depth); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirectKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, VkDeviceAddress indirectDeviceAddress); +typedef VkDeviceSize (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupStackSizeKHR)(VkDevice device, VkPipeline pipeline, uint32_t group, VkShaderGroupShaderKHR groupShader); +typedef void (VKAPI_PTR *PFN_vkCmdSetRayTracingPipelineStackSizeKHR)(VkCommandBuffer commandBuffer, uint32_t pipelineStackSize); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysKHR( + VkCommandBuffer commandBuffer, + const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, + uint32_t width, + uint32_t height, + uint32_t depth); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirectKHR( + VkCommandBuffer commandBuffer, + const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, + VkDeviceAddress indirectDeviceAddress); + +VKAPI_ATTR VkDeviceSize VKAPI_CALL vkGetRayTracingShaderGroupStackSizeKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t group, + VkShaderGroupShaderKHR groupShader); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRayTracingPipelineStackSizeKHR( + VkCommandBuffer commandBuffer, + uint32_t pipelineStackSize); +#endif + + +#define VK_KHR_ray_query 1 +#define VK_KHR_RAY_QUERY_SPEC_VERSION 1 +#define VK_KHR_RAY_QUERY_EXTENSION_NAME "VK_KHR_ray_query" +typedef struct VkPhysicalDeviceRayQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayQuery; +} VkPhysicalDeviceRayQueryFeaturesKHR; + + #ifdef __cplusplus } #endif diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_directfb.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_directfb.h new file mode 100644 index 000000000..8eaac6e48 --- /dev/null +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_directfb.h @@ -0,0 +1,54 @@ +#ifndef VULKAN_DIRECTFB_H_ +#define VULKAN_DIRECTFB_H_ 1 + +/* +** Copyright 2015-2021 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define VK_EXT_directfb_surface 1 +#define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1 +#define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface" +typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT; +typedef struct VkDirectFBSurfaceCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDirectFBSurfaceCreateFlagsEXT flags; + IDirectFB* dfb; + IDirectFBSurface* surface; +} VkDirectFBSurfaceCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT( + VkInstance instance, + const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + IDirectFB* dfb); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_fuchsia.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_fuchsia.h index 4c62a7c2f..d55871573 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_fuchsia.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_fuchsia.h @@ -1,24 +1,10 @@ #ifndef VULKAN_FUCHSIA_H_ #define VULKAN_FUCHSIA_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_FUCHSIA_imagepipe_surface 1 #define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1 @@ -49,6 +40,80 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA( VkSurfaceKHR* pSurface); #endif + +#define VK_FUCHSIA_external_memory 1 +#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory" +typedef struct VkImportMemoryZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + zx_handle_t handle; +} VkImportMemoryZirconHandleInfoFUCHSIA; + +typedef struct VkMemoryZirconHandlePropertiesFUCHSIA { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryZirconHandlePropertiesFUCHSIA; + +typedef struct VkMemoryGetZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetZirconHandleInfoFUCHSIA; + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)(VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandleFUCHSIA( + VkDevice device, + const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, + zx_handle_t* pZirconHandle); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + zx_handle_t zirconHandle, + VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties); +#endif + + +#define VK_FUCHSIA_external_semaphore 1 +#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 +#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore" +typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkSemaphoreImportFlags flags; + VkExternalSemaphoreHandleTypeFlagBits handleType; + zx_handle_t zirconHandle; +} VkImportSemaphoreZirconHandleInfoFUCHSIA; + +typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkSemaphoreGetZirconHandleInfoFUCHSIA; + +typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA( + VkDevice device, + const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA( + VkDevice device, + const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, + zx_handle_t* pZirconHandle); +#endif + #ifdef __cplusplus } #endif diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ggp.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ggp.h index 3d67c4b8c..9a6a582c5 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ggp.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ggp.h @@ -1,24 +1,10 @@ #ifndef VULKAN_GGP_H_ #define VULKAN_GGP_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_GGP_stream_descriptor_surface 1 #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1 diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ios.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ios.h index 1846df52d..6e7e6afea 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ios.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_ios.h @@ -1,24 +1,10 @@ #ifndef VULKAN_IOS_H_ #define VULKAN_IOS_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,9 +13,14 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_MVK_ios_surface 1 -#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2 +#define VK_MVK_IOS_SURFACE_SPEC_VERSION 3 #define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface" typedef VkFlags VkIOSSurfaceCreateFlagsMVK; typedef struct VkIOSSurfaceCreateInfoMVK { diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_macos.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_macos.h index dca623b04..c49b123d0 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_macos.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_macos.h @@ -1,24 +1,10 @@ #ifndef VULKAN_MACOS_H_ #define VULKAN_MACOS_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,9 +13,14 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_MVK_macos_surface 1 -#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2 +#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3 #define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; typedef struct VkMacOSSurfaceCreateInfoMVK { diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_metal.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_metal.h index 16505237d..5cf4a703a 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_metal.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_metal.h @@ -1,24 +1,10 @@ #ifndef VULKAN_METAL_H_ #define VULKAN_METAL_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_EXT_metal_surface 1 diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_mir.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_mir.h deleted file mode 100644 index 7d24ed27a..000000000 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_mir.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef VULKAN_MIR_H_ -#define VULKAN_MIR_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2015-2018 The Khronos Group Inc. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -/* -** This header is generated from the Khronos Vulkan XML API Registry. -** -*/ - - -#define VK_KHR_mir_surface 1 -#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4 -#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface" - -typedef VkFlags VkMirSurfaceCreateFlagsKHR; - -typedef struct VkMirSurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkMirSurfaceCreateFlagsKHR flags; - MirConnection* connection; - MirSurface* mirSurface; -} VkMirSurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); -typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( - VkInstance instance, - const VkMirSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - MirConnection* connection); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_screen.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_screen.h new file mode 100644 index 000000000..92ad9bfab --- /dev/null +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_screen.h @@ -0,0 +1,54 @@ +#ifndef VULKAN_SCREEN_H_ +#define VULKAN_SCREEN_H_ 1 + +/* +** Copyright 2015-2021 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define VK_QNX_screen_surface 1 +#define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1 +#define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface" +typedef VkFlags VkScreenSurfaceCreateFlagsQNX; +typedef struct VkScreenSurfaceCreateInfoQNX { + VkStructureType sType; + const void* pNext; + VkScreenSurfaceCreateFlagsQNX flags; + struct _screen_context* context; + struct _screen_window* window; +} VkScreenSurfaceCreateInfoQNX; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX( + VkInstance instance, + const VkScreenSurfaceCreateInfoQNX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + struct _screen_window* window); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_vi.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_vi.h index 50aa27dfb..9e0dcca20 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_vi.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_vi.h @@ -1,24 +1,10 @@ #ifndef VULKAN_VI_H_ #define VULKAN_VI_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_NN_vi_surface 1 #define VK_NN_VI_SURFACE_SPEC_VERSION 1 diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_wayland.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_wayland.h index 12a5f045c..2a329be9d 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_wayland.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_wayland.h @@ -1,24 +1,10 @@ #ifndef VULKAN_WAYLAND_H_ #define VULKAN_WAYLAND_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_KHR_wayland_surface 1 #define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_win32.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_win32.h index a61a7d885..1b680f0b1 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_win32.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_win32.h @@ -1,24 +1,10 @@ #ifndef VULKAN_WIN32_H_ #define VULKAN_WIN32_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_KHR_win32_surface 1 #define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6 @@ -246,7 +237,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV( #define VK_NV_win32_keyed_mutex 1 -#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1 +#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2 #define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex" typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { VkStructureType sType; @@ -263,7 +254,7 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { #define VK_EXT_full_screen_exclusive 1 -#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 3 +#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4 #define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive" typedef enum VkFullScreenExclusiveEXT { @@ -271,9 +262,6 @@ typedef enum VkFullScreenExclusiveEXT { VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1, VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2, VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3, - VK_FULL_SCREEN_EXCLUSIVE_BEGIN_RANGE_EXT = VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT, - VK_FULL_SCREEN_EXCLUSIVE_END_RANGE_EXT = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT, - VK_FULL_SCREEN_EXCLUSIVE_RANGE_SIZE_EXT = (VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT - VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT + 1), VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF } VkFullScreenExclusiveEXT; typedef struct VkSurfaceFullScreenExclusiveInfoEXT { diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xcb.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xcb.h index 7d6905d2d..5ba2ad850 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xcb.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xcb.h @@ -1,24 +1,10 @@ #ifndef VULKAN_XCB_H_ #define VULKAN_XCB_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_KHR_xcb_surface 1 #define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib.h index 7a05d297d..75c75dc2e 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib.h @@ -1,24 +1,10 @@ #ifndef VULKAN_XLIB_H_ #define VULKAN_XLIB_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_KHR_xlib_surface 1 #define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 diff --git a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib_xrandr.h b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib_xrandr.h index 3a2095308..fa2749342 100644 --- a/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib_xrandr.h +++ b/source/common/rendering/vulkan/thirdparty/vulkan/vulkan_xlib_xrandr.h @@ -1,24 +1,10 @@ #ifndef VULKAN_XLIB_XRANDR_H_ #define VULKAN_XLIB_XRANDR_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright 2015-2021 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,6 +13,11 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + #define VK_EXT_acquire_xlib_display 1 #define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1 diff --git a/source/common/scripting/backend/codegen.cpp b/source/common/scripting/backend/codegen.cpp index 5be4b48be..185c79d59 100644 --- a/source/common/scripting/backend/codegen.cpp +++ b/source/common/scripting/backend/codegen.cpp @@ -43,7 +43,7 @@ #include "texturemanager.h" #include "m_random.h" #include "v_font.h" -#include "templates.h" + extern FRandom pr_exrandom; FMemArena FxAlloc(65536); @@ -8896,7 +8896,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) ArgList.ShrinkToFit(); if (!staticcall) emitters.SetVirtualReg(selfemit.RegNum); - int resultcount = vmfunc->Proto->ReturnTypes.Size() == 0 ? 0 : std::max(AssignCount, 1); + int resultcount = vmfunc->Proto->ReturnTypes.Size() == 0 ? 0 : max(AssignCount, 1); assert((unsigned)resultcount <= vmfunc->Proto->ReturnTypes.Size()); for (int i = 0; i < resultcount; i++) diff --git a/source/common/scripting/core/symbols.cpp b/source/common/scripting/core/symbols.cpp index c6e38551f..be0b11e18 100644 --- a/source/common/scripting/core/symbols.cpp +++ b/source/common/scripting/core/symbols.cpp @@ -35,7 +35,7 @@ #include #include "dobject.h" -#include "templates.h" + #include "serializer.h" #include "types.h" #include "vm.h" @@ -345,7 +345,7 @@ PField *PSymbolTable::AddField(FName name, PType *type, uint32_t flags, unsigned // its fields. if (Align != nullptr) { - *Align = MAX(*Align, type->Align); + *Align = max(*Align, type->Align); } if (AddSymbol(field) == nullptr) diff --git a/source/common/scripting/core/types.cpp b/source/common/scripting/core/types.cpp index 260aff106..3fb97cb32 100644 --- a/source/common/scripting/core/types.cpp +++ b/source/common/scripting/core/types.cpp @@ -1702,7 +1702,7 @@ bool PArray::ReadValue(FSerializer &ar, const char *key, void *addr) const { bool readsomething = false; unsigned count = ar.ArraySize(); - unsigned loop = std::min(count, ElementCount); + unsigned loop = min(count, ElementCount); uint8_t *addrb = (uint8_t *)addr; for(unsigned i=0;iNumRegD, sfunc->NumRegF, sfunc->NumRegA, sfunc->NumRegS, sfunc->MaxParam); VMDumpConstants(dump, sfunc); diff --git a/source/common/scripting/frontend/zcc_parser.cpp b/source/common/scripting/frontend/zcc_parser.cpp index e176c646e..0d1928653 100644 --- a/source/common/scripting/frontend/zcc_parser.cpp +++ b/source/common/scripting/frontend/zcc_parser.cpp @@ -40,7 +40,7 @@ #include "version.h" #include "zcc_parser.h" #include "zcc_compile.h" -#include "templates.h" + TArray Includes; TArray IncludeLocs; diff --git a/source/common/scripting/interface/vmnatives.cpp b/source/common/scripting/interface/vmnatives.cpp index 6b1806b28..c326b2e1b 100644 --- a/source/common/scripting/interface/vmnatives.cpp +++ b/source/common/scripting/interface/vmnatives.cpp @@ -41,7 +41,7 @@ #include "c_cvars.h" #include "c_bind.h" #include "c_dispatch.h" -#include "templates.h" + #include "menu.h" #include "vm.h" #include "gstrings.h" @@ -80,7 +80,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, StatusbarToRealCoords, StatusbarTo if (numret > 1) ret[1].SetFloat(y); if (numret > 2) ret[2].SetFloat(w); if (numret > 3) ret[3].SetFloat(h); - return MIN(4, numret); + return min(4, numret); } void SBar_DrawTexture(DStatusBarCore* self, int texid, double x, double y, int flags, double alpha, double w, double h, double scaleX, double scaleY, int style, int color, int translation, double clipwidth) @@ -162,7 +162,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImageRotated, SBar_DrawImageRo void SBar_DrawTextureRotated(DStatusBarCore* self, int texid, double x, double y, int flags, double angle, double alpha, double scaleX, double scaleY, int style, int color, int translation) { if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); - self->DrawRotated(FSetTextureID(texid), x, y, flags, alpha, scaleX, scaleY, color, translation, style); + self->DrawRotated(FSetTextureID(texid), x, y, flags, angle, alpha, scaleX, scaleY, color, translation, (ERenderStyle)style); } DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawTextureRotated, SBar_DrawTextureRotated) @@ -228,7 +228,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, TransformRect, SBar_TransformRect) if (numret > 1) ret[1].SetFloat(y); if (numret > 2) ret[2].SetFloat(w); if (numret > 3) ret[3].SetFloat(h); - return MIN(4, numret); + return min(4, numret); } static void SBar_Fill(DStatusBarCore* self, int color, double x, double y, double w, double h, int flags) @@ -437,7 +437,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, GetSize, GetTextureSize) x = GetTextureSize(texid, &y); if (numret > 0) ret[0].SetInt(x); if (numret > 1) ret[1].SetInt(y); - return MIN(numret, 2); + return min(numret, 2); } //========================================================================== @@ -941,7 +941,7 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, GetKeysForCommand) self->GetKeysForCommand(cmd.GetChars(), &k1, &k2); if (numret > 0) ret[0].SetInt(k1); if (numret > 1) ret[1].SetInt(k2); - return MIN(numret, 2); + return min(numret, 2); } DEFINE_ACTION_FUNCTION(FKeyBindings, GetAllKeysForCommand) diff --git a/source/common/scripting/jit/jit_runtime.cpp b/source/common/scripting/jit/jit_runtime.cpp index b0a9dc488..a646ebf9b 100644 --- a/source/common/scripting/jit/jit_runtime.cpp +++ b/source/common/scripting/jit/jit_runtime.cpp @@ -56,7 +56,7 @@ static void *AllocJitMemory(size_t size) } else { - const size_t bytesToAllocate = std::max(size_t(1024 * 1024), size); + const size_t bytesToAllocate = max(size_t(1024 * 1024), size); size_t allocatedSize = 0; void *p = OSUtils::allocVirtualMemory(bytesToAllocate, &allocatedSize, OSUtils::kVMWritable | OSUtils::kVMExecutable); if (!p) @@ -803,7 +803,7 @@ static int CaptureStackTrace(int max_frames, void **out_frames) #elif defined(WIN32) // JIT isn't supported here, so just do nothing. - return 0;//return RtlCaptureStackBackTrace(0, MIN(max_frames, 32), out_frames, nullptr); + return 0;//return RtlCaptureStackBackTrace(0, min(max_frames, 32), out_frames, nullptr); #else return backtrace(out_frames, max_frames); #endif diff --git a/source/common/scripting/vm/vmframe.cpp b/source/common/scripting/vm/vmframe.cpp index 4b50f9b21..1fc82549d 100644 --- a/source/common/scripting/vm/vmframe.cpp +++ b/source/common/scripting/vm/vmframe.cpp @@ -37,7 +37,7 @@ #include "v_text.h" #include "stats.h" #include "c_dispatch.h" -#include "templates.h" + #include "vmintern.h" #include "types.h" #include "jit.h" @@ -746,7 +746,7 @@ ADD_STAT(VM) for (auto d : VMCycles) { added += d.TimeMS(); - peak = MAX(peak, d.TimeMS()); + peak = max(peak, d.TimeMS()); } for (auto d : VMCalls) addedc += d; memmove(&VMCycles[1], &VMCycles[0], 9 * sizeof(cycle_t)); diff --git a/source/common/statusbar/base_sbar.cpp b/source/common/statusbar/base_sbar.cpp index e63c21fb2..9ea4a6d26 100644 --- a/source/common/statusbar/base_sbar.cpp +++ b/source/common/statusbar/base_sbar.cpp @@ -35,7 +35,7 @@ #include -#include "templates.h" + #include "base_sbar.h" #include "printf.h" #include "v_draw.h" @@ -293,11 +293,11 @@ static void ST_CalcCleanFacs(int designwidth, int designheight, int realwidth, i } // Use whichever pair of cwidth/cheight or width/height that produces less difference // between CleanXfac and CleanYfac. - cx1 = MAX(cwidth / designwidth, 1); - cy1 = MAX(cheight / designheight, 1); - cx2 = MAX(realwidth / designwidth, 1); - cy2 = MAX(realheight / designheight, 1); - if (abs(cx1 - cy1) <= abs(cx2 - cy2) || MAX(cx1, cx2) >= 4) + cx1 = max(cwidth / designwidth, 1); + cy1 = max(cheight / designheight, 1); + cx2 = max(realwidth / designwidth, 1); + cy2 = max(realheight / designheight, 1); + if (abs(cx1 - cy1) <= abs(cx2 - cy2) || max(cx1, cx2) >= 4) { // e.g. 640x360 looks better with this. *cleanx = cx1; *cleany = cy1; @@ -489,7 +489,7 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag if (boxwidth <= 0 || (boxheight > 0 && scale2 < scale1)) scale1 = scale2; } - else scale1 = MIN(scale1, scale2); + else scale1 = min(scale1, scale2); boxwidth = texwidth * scale1; boxheight = texheight * scale1; diff --git a/source/common/textures/animtexture.cpp b/source/common/textures/animtexture.cpp index 8f8add3f7..039021641 100644 --- a/source/common/textures/animtexture.cpp +++ b/source/common/textures/animtexture.cpp @@ -34,7 +34,7 @@ #include "animtexture.h" #include "bitmap.h" #include "texturemanager.h" -#include "templates.h" + //========================================================================== // diff --git a/source/common/textures/bitmap.h b/source/common/textures/bitmap.h index 36d520771..88df40307 100644 --- a/source/common/textures/bitmap.h +++ b/source/common/textures/bitmap.h @@ -37,7 +37,7 @@ #define __BITMAP_H__ #include "basics.h" -#include "templates.h" + #include "palentry.h" struct FCopyInfo; @@ -460,7 +460,7 @@ struct bCopyAlpha struct bOverlay { static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = (s*a + d*(255-a))/255; } - static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = MAX(s,d); } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = max(s,d); } static __forceinline bool ProcessAlpha0() { return false; } }; @@ -473,21 +473,21 @@ struct bBlend struct bAdd { - static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = MIN((d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 255); } + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = min((d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 255); } static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; struct bSubtract { - static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = MAX((d*BLENDUNIT - s*i->alpha) >> BLENDBITS, 0); } + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = max((d*BLENDUNIT - s*i->alpha) >> BLENDBITS, 0); } static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; struct bReverseSubtract { - static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = MAX((-d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 0); } + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = max((-d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 0); } static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; diff --git a/source/common/textures/formats/fontchars.cpp b/source/common/textures/formats/fontchars.cpp index 44a72ca6e..a48600437 100644 --- a/source/common/textures/formats/fontchars.cpp +++ b/source/common/textures/formats/fontchars.cpp @@ -113,7 +113,7 @@ TArray FFontChar2::CreatePalettedPixels(int) if (runlen != 0) { uint8_t color = lump.ReadUInt8(); - color = MIN(color, max); + color = min(color, max); *dest_p = color; dest_p += dest_adv; x--; @@ -137,7 +137,7 @@ TArray FFontChar2::CreatePalettedPixels(int) { uint8_t color = lump.ReadUInt8(); setlen = (-code) + 1; - setval = MIN(color, max); + setval = min(color, max); } } } diff --git a/source/common/textures/formats/pngtexture.cpp b/source/common/textures/formats/pngtexture.cpp index bf1cc88cd..dd0976a8e 100644 --- a/source/common/textures/formats/pngtexture.cpp +++ b/source/common/textures/formats/pngtexture.cpp @@ -35,7 +35,7 @@ */ #include "files.h" -#include "templates.h" + #include "m_png.h" #include "bitmap.h" #include "imagehelpers.h" @@ -244,7 +244,7 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height, break; case MAKE_ID('P','L','T','E'): - PaletteSize = MIN (len / 3, 256); + PaletteSize = min (len / 3, 256); StartOfPalette = (uint32_t)lump.Tell(); lump.Seek(len, FileReader::SeekCur); break; @@ -762,7 +762,7 @@ FBitmap FPNGFileTexture::GetBgraBitmap(const PalEntry *remap, int *trans) lump->Seek (len, FileReader::SeekCur); else { - PaletteSize = std::min (len / 3, 256); + PaletteSize = min (len / 3, 256); for(int i = 0; i < PaletteSize; i++) { pe[i].r = lump->ReadUInt8(); diff --git a/source/common/textures/formats/tgatexture.cpp b/source/common/textures/formats/tgatexture.cpp index 80c7b04a8..d2e12e1aa 100644 --- a/source/common/textures/formats/tgatexture.cpp +++ b/source/common/textures/formats/tgatexture.cpp @@ -35,7 +35,7 @@ #include "files.h" #include "filesystem.h" -#include "templates.h" + #include "bitmap.h" #include "imagehelpers.h" #include "image.h" @@ -153,7 +153,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe { b&=~128; lump.Read(data, bytesperpixel); - for (int i=MIN(Size, (b+1)); i>0; i--) + for (int i=min(Size, (b+1)); i>0; i--) { buffer[0] = data[0]; if (bytesperpixel>=2) buffer[1] = data[1]; @@ -164,7 +164,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe } else { - lump.Read(buffer, MIN(Size, (b+1))*bytesperpixel); + lump.Read(buffer, min(Size, (b+1))*bytesperpixel); buffer += (b+1)*bytesperpixel; } Size -= b+1; diff --git a/source/common/textures/gametexture.cpp b/source/common/textures/gametexture.cpp index 29d1ee2dd..c5979a7a9 100644 --- a/source/common/textures/gametexture.cpp +++ b/source/common/textures/gametexture.cpp @@ -37,7 +37,7 @@ #include "printf.h" #include "files.h" #include "filesystem.h" -#include "templates.h" + #include "textures.h" #include "bitmap.h" #include "colormatcher.h" diff --git a/source/common/textures/hw_ihwtexture.cpp b/source/common/textures/hw_ihwtexture.cpp index aebf387d4..296bfd40d 100644 --- a/source/common/textures/hw_ihwtexture.cpp +++ b/source/common/textures/hw_ihwtexture.cpp @@ -34,7 +34,7 @@ */ #include "hw_ihwtexture.h" -#include "templates.h" +#include "basics.h" #include "tarray.h" #include "xs_Float.h" @@ -67,8 +67,8 @@ static void ResampleBoxPrecalc(TArray& boxes, int oldDim) const int src_p = int(dst * scale_factor_1); BoxPrecalc& precalc = boxes[dst]; - precalc.boxStart = clamp(int(src_p - scale_factor_1 / 2.0 + 1), 0, oldDim - 1); - precalc.boxEnd = clamp(MAX(precalc.boxStart + 1, int(src_p + scale_factor_2)), 0, oldDim - 1); + precalc.boxStart = std::clamp(int(src_p - scale_factor_1 / 2.0 + 1), 0, oldDim - 1); + precalc.boxEnd = std::clamp(std::max(precalc.boxStart + 1, int(src_p + scale_factor_2)), 0, oldDim - 1); } } diff --git a/source/common/textures/hw_material.cpp b/source/common/textures/hw_material.cpp index 3f149d728..944e311d1 100644 --- a/source/common/textures/hw_material.cpp +++ b/source/common/textures/hw_material.cpp @@ -30,7 +30,7 @@ #include "v_video.h" -CVAR(Bool, gl_customshader, true, 0); +CVAR(Bool, gl_customshader, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL); static IHardwareTexture* (*layercallback)(int layer, int translation); diff --git a/source/common/textures/imagetexture.cpp b/source/common/textures/imagetexture.cpp index 5ec15c7b5..261333c98 100644 --- a/source/common/textures/imagetexture.cpp +++ b/source/common/textures/imagetexture.cpp @@ -35,7 +35,7 @@ #include "files.h" #include "filesystem.h" -#include "templates.h" + #include "bitmap.h" #include "image.h" #include "textures.h" diff --git a/source/common/textures/m_png.cpp b/source/common/textures/m_png.cpp index e58742da4..8467a5d42 100644 --- a/source/common/textures/m_png.cpp +++ b/source/common/textures/m_png.cpp @@ -246,7 +246,7 @@ bool M_AppendPNGText (FileWriter *file, const char *keyword, const char *text) { struct { uint32_t len, id; char key[80]; } head; int len = (int)strlen (text); - int keylen = std::min ((int)strlen (keyword), 79); + int keylen = min ((int)strlen (keyword), 79); uint32_t crc; head.len = BigLong(len + keylen + 1); @@ -329,7 +329,7 @@ char *M_GetPNGText (PNGHandle *png, const char *keyword) if (strncmp (keyword, png->TextChunks[i], 80) == 0) { // Woo! A match was found! - keylen = std::min (80, strlen (keyword) + 1); + keylen = min (80, strlen (keyword) + 1); textlen = strlen (png->TextChunks[i] + keylen) + 1; char *str = new char[textlen]; strcpy (str, png->TextChunks[i] + keylen); @@ -351,7 +351,7 @@ bool M_GetPNGText (PNGHandle *png, const char *keyword, char *buffer, size_t buf if (strncmp (keyword, png->TextChunks[i], 80) == 0) { // Woo! A match was found! - keylen = std::min (80, strlen (keyword) + 1); + keylen = min (80, strlen (keyword) + 1); strncpy (buffer, png->TextChunks[i] + keylen, buffsize); return true; } @@ -566,7 +566,7 @@ bool M_ReadIDAT (FileReader &file, uint8_t *buffer, int width, int height, int p if (stream.avail_in == 0 && chunklen > 0) { stream.next_in = chunkbuffer; - stream.avail_in = (uInt)file.Read (chunkbuffer, std::min(chunklen,sizeof(chunkbuffer))); + stream.avail_in = (uInt)file.Read (chunkbuffer, min(chunklen,sizeof(chunkbuffer))); chunklen -= stream.avail_in; } diff --git a/source/common/textures/multipatchtexturebuilder.cpp b/source/common/textures/multipatchtexturebuilder.cpp index 000af17e2..6a49d87ae 100644 --- a/source/common/textures/multipatchtexturebuilder.cpp +++ b/source/common/textures/multipatchtexturebuilder.cpp @@ -572,7 +572,7 @@ void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPar else if (sc.Compare("alpha")) { sc.MustGetFloat(); - part.Alpha = clamp(int(sc.Float * BLENDUNIT), 0, BLENDUNIT); + part.Alpha = clamp(int(sc.Float * +BLENDUNIT), 0, BLENDUNIT); // bComplex is not set because it is only needed when the style is not OP_COPY. } else if (sc.Compare("style")) diff --git a/source/common/textures/texture.cpp b/source/common/textures/texture.cpp index 6d24f1154..5b88c3cef 100644 --- a/source/common/textures/texture.cpp +++ b/source/common/textures/texture.cpp @@ -37,7 +37,7 @@ #include "printf.h" #include "files.h" #include "filesystem.h" -#include "templates.h" + #include "textures.h" #include "bitmap.h" #include "colormatcher.h" @@ -387,7 +387,7 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) FContentIdBuilder builder; builder.id = 0; builder.imageID = GetImage()->GetId(); - builder.translation = MAX(0, translation); + builder.translation = max(0, translation); builder.expand = exx; result.mContentId = builder.id; } diff --git a/source/common/textures/texturemanager.cpp b/source/common/textures/texturemanager.cpp index c4fcfd841..65e267b84 100644 --- a/source/common/textures/texturemanager.cpp +++ b/source/common/textures/texturemanager.cpp @@ -37,7 +37,7 @@ #include "filesystem.h" #include "printf.h" #include "c_cvars.h" -#include "templates.h" + #include "gstrings.h" #include "textures.h" #include "texturemanager.h" diff --git a/source/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp b/source/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp index c981d35a6..080635177 100644 --- a/source/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp +++ b/source/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp @@ -1144,7 +1144,7 @@ uint32_t SmackerDecoder::GetAudioData(uint32_t trackIndex, int16_t *audioBuffer) SmackerAudioTrack *track = &audioTracks[trackIndex]; if (track->bytesReadThisFrame) { - memcpy(audioBuffer, track->buffer, std::min(track->bufferSize, track->bytesReadThisFrame)); + memcpy(audioBuffer, track->buffer, min(track->bufferSize, track->bytesReadThisFrame)); } return track->bytesReadThisFrame; diff --git a/source/common/thirdparty/rapidjson/document.h b/source/common/thirdparty/rapidjson/document.h index 19f5a6a5f..7612801b5 100644 --- a/source/common/thirdparty/rapidjson/document.h +++ b/source/common/thirdparty/rapidjson/document.h @@ -29,6 +29,7 @@ RAPIDJSON_DIAG_PUSH #ifdef _MSC_VER RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data +RAPIDJSON_DIAG_OFF(4996) // deprecation of std::iterator #endif #ifdef __clang__ diff --git a/source/common/utility/basics.h b/source/common/utility/basics.h index 703a84c30..29ee19593 100644 --- a/source/common/utility/basics.h +++ b/source/common/utility/basics.h @@ -105,3 +105,4 @@ enum EStateUseFlags using std::min; using std::max; +using std::clamp; diff --git a/source/common/utility/cmdlib.cpp b/source/common/utility/cmdlib.cpp index 9551cbf42..38b502822 100644 --- a/source/common/utility/cmdlib.cpp +++ b/source/common/utility/cmdlib.cpp @@ -1060,7 +1060,7 @@ void md5Update(FileReader& file, MD5Context& md5, unsigned len) while (len > 0) { - t = std::min(len, sizeof(readbuf)); + t = min(len, sizeof(readbuf)); len -= t; t = (long)file.Read(readbuf, t); md5.Update(readbuf, t); diff --git a/source/common/utility/files.cpp b/source/common/utility/files.cpp index e93262214..6f915a2ce 100644 --- a/source/common/utility/files.cpp +++ b/source/common/utility/files.cpp @@ -34,7 +34,7 @@ */ #include "files.h" -#include "templates.h" // just for 'clamp' + // just for 'clamp' #include "zstring.h" diff --git a/source/common/utility/files_decompress.cpp b/source/common/utility/files_decompress.cpp index c79d762e6..7d7d65442 100644 --- a/source/common/utility/files_decompress.cpp +++ b/source/common/utility/files_decompress.cpp @@ -42,7 +42,7 @@ #include #include "files.h" -#include "templates.h" + #include "zstring.h" #include "cmdlib.h" @@ -509,7 +509,7 @@ class DecompressorLZSS : public DecompressorBase // Partial overlap: Copy in 2 or 3 chunks. do { - unsigned int copy = std::min(len, pos+1); + unsigned int copy = min(len, pos+1); memcpy(Stream.InternalBuffer, copyStart, copy); Stream.InternalBuffer += copy; Stream.InternalOut += copy; @@ -575,7 +575,7 @@ public: break; } - unsigned int copy = std::min(Stream.InternalOut, AvailOut); + unsigned int copy = min(Stream.InternalOut, AvailOut); if(copy > 0) { memcpy(Out, Stream.WindowData, copy); diff --git a/source/common/utility/palette.cpp b/source/common/utility/palette.cpp index 3b6e71e55..28115a521 100644 --- a/source/common/utility/palette.cpp +++ b/source/common/utility/palette.cpp @@ -39,7 +39,7 @@ #include "files.h" #include "filesystem.h" #include "printf.h" -#include "templates.h" + #include "m_png.h" /****************************/ @@ -500,7 +500,7 @@ PalEntry averageColor(const uint32_t* data, int size, int maxout) g = g / size; b = b / size; - int maxv = MAX(MAX(r, g), b); + int maxv = max(max(r, g), b); if (maxv && maxout) { @@ -802,9 +802,9 @@ void UpdateSpecialColormap(PalEntry* BaseColors, unsigned int index, float r1, f BaseColors[c].g * 143 + BaseColors[c].b * 37) / 256.0; - PalEntry pe = PalEntry(std::min(255, int(r1 + intensity * r2)), - std::min(255, int(g1 + intensity * g2)), - std::min(255, int(b1 + intensity * b2))); + PalEntry pe = PalEntry(min(255, int(r1 + intensity * r2)), + min(255, int(g1 + intensity * g2)), + min(255, int(b1 + intensity * b2))); cm->Colormap[c] = BestColor((uint32_t*)BaseColors, pe.r, pe.g, pe.b); } @@ -813,9 +813,9 @@ void UpdateSpecialColormap(PalEntry* BaseColors, unsigned int index, float r1, f // This table is used by the texture composition code for (int i = 0; i < 256; i++) { - cm->GrayscaleToColor[i] = PalEntry(std::min(255, int(r1 + i * r2)), - std::min(255, int(g1 + i * g2)), - std::min(255, int(b1 + i * b2))); + cm->GrayscaleToColor[i] = PalEntry(min(255, int(r1 + i * r2)), + min(255, int(g1 + i * g2)), + min(255, int(b1 + i * b2))); } } @@ -911,7 +911,7 @@ int ReadPalette(int lumpnum, uint8_t* buffer) fr.Seek(len, FileReader::SeekCur); else { - int PaletteSize = MIN(len, 768); + int PaletteSize = min(len, 768); fr.Read(buffer, PaletteSize); return PaletteSize / 3; } @@ -930,7 +930,7 @@ int ReadPalette(int lumpnum, uint8_t* buffer) sc.MustGetString(); sc.MustGetNumber(); // version - ignore sc.MustGetNumber(); - int colors = MIN(256, sc.Number) * 3; + int colors = min(256, sc.Number) * 3; for (int i = 0; i < colors; i++) { sc.MustGetNumber(); @@ -944,7 +944,7 @@ int ReadPalette(int lumpnum, uint8_t* buffer) } else { - memcpy(buffer, lumpmem, MIN(768, lump.GetSize())); + memcpy(buffer, lumpmem, min(768, lump.GetSize())); return 256; } } diff --git a/source/common/utility/r_memory.cpp b/source/common/utility/r_memory.cpp index 99a75d0f7..383cdbeb4 100644 --- a/source/common/utility/r_memory.cpp +++ b/source/common/utility/r_memory.cpp @@ -21,7 +21,7 @@ */ #include -#include "templates.h" + #include "r_memory.h" #include diff --git a/source/common/utility/refcounted.h b/source/common/utility/refcounted.h index fd3e82aad..81ea3fc6d 100644 --- a/source/common/utility/refcounted.h +++ b/source/common/utility/refcounted.h @@ -2,16 +2,7 @@ // Simple lightweight reference counting pointer alternative for std::shared_ptr which stores the reference counter in the handled object itself. -// Base classes for handled objects -class NoVirtualRefCountedBase -{ -public: - void IncRef() { refCount++; } - void DecRef() { if (--refCount <= 0) delete this; } -private: - int refCount = 0; -}; - +// Base class for handled objects class RefCountedBase { public: diff --git a/source/common/utility/s_playlist.cpp b/source/common/utility/s_playlist.cpp index d284a3e90..d457d0137 100644 --- a/source/common/utility/s_playlist.cpp +++ b/source/common/utility/s_playlist.cpp @@ -37,7 +37,7 @@ #include "cmdlib.h" #include "s_playlist.h" -#include "templates.h" + #include "v_text.h" #include "files.h" diff --git a/source/common/utility/tarray.h b/source/common/utility/tarray.h index 4a9e7388b..4f5467921 100644 --- a/source/common/utility/tarray.h +++ b/source/common/utility/tarray.h @@ -63,14 +63,14 @@ #include "m_alloc.h" -template class TIterator : public std::iterator +template class TIterator { public: - typedef typename TIterator::value_type value_type; - typedef typename TIterator::difference_type difference_type; - typedef typename TIterator::pointer pointer; - typedef typename TIterator::reference reference; - typedef typename TIterator::iterator_category iterator_category; + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; TIterator(T* ptr = nullptr) { m_ptr = ptr; } @@ -105,6 +105,17 @@ protected: T* m_ptr; }; +// magic little helper. :) +template +class backwards +{ + T& _obj; +public: + backwards(T &obj) : _obj(obj) {} + auto begin() {return _obj.rbegin();} + auto end() {return _obj.rend();} +}; + // TArray ------------------------------------------------------------------- @@ -125,6 +136,8 @@ public: typedef TIterator iterator; typedef TIterator const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; typedef T value_type; iterator begin() @@ -153,7 +166,32 @@ public: return &Array[Count]; } - + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(cend()); + } + + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const + { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const + { + return const_reverse_iterator(cbegin()); + } + //////// // This is a dummy constructor that does nothing. The purpose of this @@ -636,6 +674,8 @@ public: typedef TIterator iterator; typedef TIterator const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; typedef T value_type; iterator begin() @@ -664,6 +704,32 @@ public: return &Array[Count]; } + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(cend()); + } + + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const + { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const + { + return const_reverse_iterator(cbegin()); + } + void Init(T *ptr, unsigned cnt) { Array = ptr; @@ -1579,7 +1645,7 @@ public: } BitArray(unsigned elem) - : bytes((elem + 7) / 8, true) + : bytes((elem + 7) / 8, true), size(elem) { } @@ -1637,6 +1703,11 @@ public: { memset(&bytes[0], 0, bytes.Size()); } + + TArray &Storage() + { + return bytes; + } }; @@ -1704,6 +1775,8 @@ public: typedef TIterator iterator; typedef TIterator const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; typedef T value_type; iterator begin() @@ -1732,6 +1805,32 @@ public: return &Array[Count]; } + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(cend()); + } + + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const + { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const + { + return const_reverse_iterator(cbegin()); + } + //////// TArrayView() = default; // intended to keep this type trivial. @@ -1807,3 +1906,203 @@ private: T *Array; unsigned int Count; }; + + +template class TSparseIterator +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + + TSparseIterator(unsigned char* ptr = nullptr, unsigned stride = 0) { m_Ptr = ptr; Stride = stride; } + + // Comparison operators + bool operator==(const TSparseIterator &other) const { return m_Ptr == other.m_Ptr; } + bool operator!=(const TSparseIterator &other) const { return m_Ptr != other.m_Ptr; } + bool operator< (const TSparseIterator &other) const { return m_Ptr < other.m_Ptr; } + bool operator<=(const TSparseIterator &other) const { return m_Ptr <= other.m_Ptr; } + bool operator> (const TSparseIterator &other) const { return m_Ptr > other.m_Ptr; } + bool operator>=(const TSparseIterator &other) const { return m_Ptr >= other.m_Ptr; } + + // Arithmetic operators + TSparseIterator &operator++() { m_Ptr += Stride; return *this; } + TSparseIterator operator++(int) { auto tmp = *this; ++*this; return tmp; } + TSparseIterator &operator--() { m_Ptr -= Stride; return *this; } + TSparseIterator operator--(int) { auto tmp = *this; --*this; return tmp; } + TSparseIterator &operator+=(difference_type offset) { m_Ptr += offset * Stride; return *this; } + TSparseIterator operator+(difference_type offset) const { return TSparseIterator(m_Ptr + offset * Stride, Stride); } + friend TSparseIterator operator+(difference_type offset, const TSparseIterator &other) { return TSparseIterator(offset*other.Stride + other.m_Ptr, other.Stride); } + TSparseIterator &operator-=(difference_type offset) { m_Ptr -= offset * Stride; return *this; } + TSparseIterator operator-(difference_type offset) const { return TSparseIterator(m_Ptr - offset * Stride, Stride); } + difference_type operator-(const TSparseIterator &other) const { return (m_Ptr - other.m_Ptr) / Stride; } + + // Random access operators + T& operator[](difference_type i) { return *(T*)(m_Ptr + i * Stride); } + const T& operator[](difference_type i) const { return *(T*)(m_Ptr + i * Stride); } + + T &operator*() const { return (T*)m_Ptr; } + T* operator->() { return (T*)m_Ptr; } + +protected: + unsigned char* m_Ptr; + unsigned Stride; +}; + +// A wrapper to externally stored data. +// Like the above but with a customizable stride +template +class TSparseArrayView +{ +public: + + typedef TSparseIterator iterator; + typedef TSparseIterator const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + typedef T value_type; + + iterator begin() + { + return iterator(Array, Stride); + } + const_iterator begin() const + { + return const_iterator(Array, Stride); + } + const_iterator cbegin() const + { + return const_iterator(Array, Stride); + } + + iterator end() + { + return iterator(Array + Count * Stride, Stride); + } + const_iterator end() const + { + return const_iterator(Array + Count * Stride, Stride); + } + const_iterator cend() const + { + return const_iterator(Array + Count * Stride, Stride); + } + + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(cend()); + } + + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const + { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const + { + return const_reverse_iterator(cbegin()); + } + + //////// + TSparseArrayView() = default; // intended to keep this type trivial. + TSparseArrayView(T *data, unsigned stride, unsigned count = 0) + { + Count = count; + Array = data; + Stride = stride; + } + TSparseArrayView(const TSparseArrayView &other) = default; + TSparseArrayView &operator= (const TSparseArrayView &other) = default; + + // Check equality of two arrays + bool operator==(const TArrayView &other) const + { + if (Count != other.Count) + { + return false; + } + for (unsigned int i = 0; i < Count; ++i) + { + if (Element(i) != other.Element(i)) + { + return false; + } + } + return true; + } + + T &Element(size_t index) + { + return (T*)Array[index*Stride]; + } + // Return a reference to an element + T &operator[] (size_t index) const + { + return Element(index); + } + // Returns a reference to the last element + T &Last() const + { + return Element(Count - 1); + } + + // returns address of first element + T *Data() const + { + return &Element(0); + } + + unsigned Size() const + { + return Count; + } + + unsigned int Find(const T& item) const + { + unsigned int i; + for (i = 0; i < Count; ++i) + { + if (Element(i) == item) + break; + } + return i; + } + + void Set(T *data, unsigned stride, unsigned count) + { + Array = reinterpret_cast(data); + Count = count; + Stride = stride; + } + + void Set(void *data, unsigned stride, unsigned count) + { + Array = reinterpret_cast(data); + Count = count; + Stride = stride; + } + + void Clear() + { + Count = 0; + Stride = 0; + Array = nullptr; + } +private: + unsigned char* Array; + unsigned int Count; + unsigned int Stride; +}; diff --git a/source/common/utility/templates.h b/source/common/utility/templates.h index 3f3e596f0..22b9f3d3f 100644 --- a/source/common/utility/templates.h +++ b/source/common/utility/templates.h @@ -93,54 +93,5 @@ const ClassType *BinarySearch (const ClassType *first, int max, return NULL; } -//========================================================================== -// -// MIN -// -// Returns the minimum of a and b. -//========================================================================== - -#ifdef MIN -#undef MIN -#endif - -template -inline -const T MIN (const T a, const T b) -{ - return a < b ? a : b; -} - -//========================================================================== -// -// MAX -// -// Returns the maximum of a and b. -//========================================================================== - -#ifdef MAX -#undef MAX -#endif - -template -inline -const T MAX (const T a, const T b) -{ - return a > b ? a : b; -} - -//========================================================================== -// -// clamp -// -// Clamps in to the range [min,max]. -//========================================================================== - -template -inline constexpr -T clamp (const T in, const X min, const Y max) -{ - return in <= (T) min ? (T) min : in >= (T) max ? (T) max : in; -} #endif //__TEMPLATES_H__ diff --git a/source/core/binaryangle.h b/source/core/binaryangle.h index 4b033c31a..8fdd77a8e 100644 --- a/source/core/binaryangle.h +++ b/source/core/binaryangle.h @@ -37,11 +37,11 @@ #pragma once #include +#include "basics.h" #include "m_fixed.h" #include "xs_Float.h" // needed for reliably overflowing float->int conversions. #include "serializer.h" #include "math/cmath.h" -#include "templates.h" class FSerializer; @@ -49,7 +49,10 @@ enum { BAMBITS = 21, BAMUNIT = 1 << BAMBITS, - SINSHIFT = 14 + SINTABLEBITS = 30, + SINTABLEUNIT = 1 << SINTABLEBITS, + BUILDSINBITS = 14, + BUILDSINSHIFT = SINTABLEBITS - BUILDSINBITS, }; //--------------------------------------------------------------------------- @@ -61,7 +64,12 @@ enum constexpr double BAngRadian = pi::pi() * (1. / 1024.); constexpr double BAngToDegree = 360. / 2048.; -extern int16_t sintable[2048]; +extern int sintable[2048]; + +inline constexpr double sinscale(const int shift) +{ + return shift >= -BUILDSINBITS ? uint64_t(1) << (BUILDSINBITS + shift) : 1. / (uint64_t(1) << abs(BUILDSINBITS + shift)); +} //--------------------------------------------------------------------------- // @@ -69,13 +77,13 @@ extern int16_t sintable[2048]; // //--------------------------------------------------------------------------- -inline int bsin(const int ang, const int shift = 0) +inline int bsin(const int ang, int shift = 0) { - return shift < 0 ? sintable[ang & 2047] >> abs(shift) : sintable[ang & 2047] << shift; + return (shift -= BUILDSINSHIFT) < 0 ? sintable[ang & 2047] >> abs(shift) : sintable[ang & 2047] << shift; } inline double bsinf(const double ang, const int shift = 0) { - return g_sin(ang * BAngRadian) * (shift >= -SINSHIFT ? uint64_t(1) << (SINSHIFT + shift) : 1. / (uint64_t(1) << abs(SINSHIFT + shift))); + return g_sin(ang * BAngRadian) * sinscale(shift); } @@ -85,13 +93,13 @@ inline double bsinf(const double ang, const int shift = 0) // //--------------------------------------------------------------------------- -inline int bcos(const int ang, const int shift = 0) +inline int bcos(const int ang, int shift = 0) { - return shift < 0 ? sintable[(ang + 512) & 2047] >> abs(shift) : sintable[(ang + 512) & 2047] << shift; + return (shift -= BUILDSINSHIFT) < 0 ? sintable[(ang + 512) & 2047] >> abs(shift) : sintable[(ang + 512) & 2047] << shift; } inline double bcosf(const double ang, const int shift = 0) { - return g_cos(ang * BAngRadian) * (shift >= -SINSHIFT ? uint64_t(1) << (SINSHIFT + shift) : 1. / (uint64_t(1) << abs(SINSHIFT + shift))); + return g_cos(ang * BAngRadian) * sinscale(shift); } @@ -115,20 +123,21 @@ class binangle friend binangle degang(double v); friend FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj, binangle *defval); + + constexpr int32_t tosigned() const { return value > INT32_MAX ? int64_t(value) - UINT32_MAX : value; } public: binangle() = default; binangle(const binangle &other) = default; // This class intentionally makes no allowances for implicit type conversions because those would render it ineffective. - constexpr int32_t tosigned() const { return value > INT32_MAX ? int64_t(value) - UINT32_MAX : value; } constexpr short asbuild() const { return value >> BAMBITS; } - constexpr double asbuildf() const { return value * (1. / BAMUNIT); } + constexpr double asbuildf() const { return value * (1. / +BAMUNIT); } constexpr fixed_t asq16() const { return value >> 5; } constexpr uint32_t asbam() const { return value; } constexpr double asrad() const { return value * (pi::pi() / 0x80000000u); } constexpr double asdeg() const { return AngleToFloat(value); } constexpr short signedbuild() const { return tosigned() >> BAMBITS; } - constexpr double signedbuildf() const { return tosigned() * (1. / BAMUNIT); } + constexpr double signedbuildf() const { return tosigned() * (1. / +BAMUNIT); } constexpr fixed_t signedq16() const { return tosigned() >> 5; } constexpr int32_t signedbam() const { return tosigned(); } constexpr double signedrad() const { return tosigned() * (pi::pi() / 0x80000000u); } @@ -174,31 +183,31 @@ public: constexpr binangle &operator<<= (const uint8_t shift) { - value <<= shift; + value = tosigned() << shift; return *this; } constexpr binangle &operator>>= (const uint8_t shift) { - value >>= shift; + value = tosigned() >> shift; return *this; } constexpr binangle operator<< (const uint8_t shift) const { - return binangle(value << shift); + return binangle(tosigned() << shift); } constexpr binangle operator>> (const uint8_t shift) const { - return binangle(value >> shift); + return binangle(tosigned() >> shift); } }; inline constexpr binangle bamang(uint32_t v) { return binangle(v); } inline constexpr binangle q16ang(uint32_t v) { return binangle(v << 5); } inline constexpr binangle buildang(uint32_t v) { return binangle(v << BAMBITS); } -inline binangle buildfang(double v) { return binangle(xs_CRoundToUInt(v * BAMUNIT)); } +inline binangle buildfang(double v) { return binangle(xs_ToFixed(BAMBITS, v)); } inline binangle radang(double v) { return binangle(xs_CRoundToUInt(v * (0x80000000u / pi::pi()))); } inline binangle degang(double v) { return binangle(FloatToAngle(v)); } @@ -217,7 +226,7 @@ inline FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj, inline double HorizToPitch(double horiz) { return atan2(horiz, 128) * (180. / pi::pi()); } inline double HorizToPitch(fixed_t q16horiz) { return atan2(q16horiz, IntToFixed(128)) * (180. / pi::pi()); } inline fixed_t PitchToHoriz(double pitch) { return xs_CRoundToInt(IntToFixed(128) * tan(pitch * (pi::pi() / 180.))); } -inline int32_t PitchToBAM(double pitch) { return xs_CRoundToInt(clamp(pitch * (1073741823.5 / 45.), -INT32_MAX, INT32_MAX)); } +inline int32_t PitchToBAM(double pitch) { return xs_CRoundToInt(clamp(pitch * (1073741823.5 / 45.), -INT32_MAX, INT32_MAX)); } inline constexpr double BAMToPitch(int32_t bam) { return bam * (45. / 1073741823.5); } @@ -396,3 +405,13 @@ inline constexpr binangle interpolatedangle(binangle oang, binangle ang, int con { return bamang(oang.asbam() + MulScale(((ang.asbam() + 0x80000000 - oang.asbam()) & 0xFFFFFFFF) - 0x80000000, smoothratio, scale)); } + +inline constexpr fixedhoriz interpolatedhorizon(fixedhoriz oval, fixedhoriz val, double const smoothratio, int const scale = 16) +{ + return q16horiz(oval.asq16() + MulScale((val - oval).asq16(), int(smoothratio), scale)); +} + +inline constexpr fixedhoriz interpolatedhorizon(fixedhoriz oval, fixedhoriz val, int const smoothratio, int const scale = 16) +{ + return q16horiz(oval.asq16() + MulScale((val - oval).asq16(), smoothratio, scale)); +} diff --git a/source/core/console/c_notifybuffer.cpp b/source/core/console/c_notifybuffer.cpp index e5947e93e..24507a7fd 100644 --- a/source/core/console/c_notifybuffer.cpp +++ b/source/core/console/c_notifybuffer.cpp @@ -65,7 +65,7 @@ CVAR(Bool, con_centernotify, false, CVAR_ARCHIVE) CVAR(Bool, con_pulsetext, false, CVAR_ARCHIVE) CVAR(Bool, con_notify_advanced, false, CVAR_ARCHIVE) -enum { NOTIFYFADETIME = 6 }; +const int NOTIFYFADETIME = 6; CUSTOM_CVAR(Int, con_notifylines, 4, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) { diff --git a/source/core/d_net.cpp b/source/core/d_net.cpp index 041eada4f..af8e3bc94 100644 --- a/source/core/d_net.cpp +++ b/source/core/d_net.cpp @@ -234,7 +234,7 @@ static struct TicSpecial { int i; - specialsize = std::max(specialsize * 2, needed + 30); + specialsize = max(specialsize * 2, needed + 30); DPrintf (DMSG_NOTIFY, "Expanding special size to %zu\n", specialsize); @@ -1164,7 +1164,7 @@ void NetUpdate (void) netbuffer[k++] = lowtic; } - numtics = std::max(0, lowtic - realstart); + numtics = max(0, lowtic - realstart); if (numtics > BACKUPTICS) I_Error ("NetUpdate: Node %d missed too many tics", i); @@ -1173,7 +1173,7 @@ void NetUpdate (void) case 0: default: resendto[i] = lowtic; break; - case 1: resendto[i] = std::max(0, lowtic - 1); break; + case 1: resendto[i] = max(0, lowtic - 1); break; case 2: resendto[i] = nettics[i]; break; } @@ -1998,15 +1998,15 @@ int Net_GetLatency(int *ld, int *ad) localdelay = ((localdelay / BACKUPTICS) * ticdup) * (1000 / GameTicRate); int severity = 0; - if (std::max(localdelay, arbitratordelay) > 200) + if (max(localdelay, arbitratordelay) > 200) { severity = 1; } - if (std::max(localdelay, arbitratordelay) > 400) + if (max(localdelay, arbitratordelay) > 400) { severity = 2; } - if (std::max(localdelay, arbitratordelay) >= ((BACKUPTICS / 2 - 1) * ticdup) * (1000 / GameTicRate)) + if (max(localdelay, arbitratordelay) >= ((BACKUPTICS / 2 - 1) * ticdup) * (1000 / GameTicRate)) { severity = 3; } diff --git a/source/core/g_mapinfo.cpp b/source/core/g_mapinfo.cpp index b59f28f75..87a977227 100644 --- a/source/core/g_mapinfo.cpp +++ b/source/core/g_mapinfo.cpp @@ -36,7 +36,7 @@ #include #include "mapinfo.h" #include "g_mapinfo.h" -#include "templates.h" + #include "filesystem.h" #include "cmdlib.h" #include "v_video.h" diff --git a/source/core/gameconfigfile.cpp b/source/core/gameconfigfile.cpp index f78b331f5..9be33eecf 100644 --- a/source/core/gameconfigfile.cpp +++ b/source/core/gameconfigfile.cpp @@ -224,6 +224,7 @@ void FGameConfigFile::DoAutoloadSetup (/*FIWadManager *iwad_man*/) CreateSectionAtStart("Duke.Duke.15.Autoload"); CreateSectionAtStart("Duke.Duke.13.Autoload"); CreateSectionAtStart("Duke.Duke.Autoload"); + CreateSectionAtStart("Duke.PParadise.Autoload"); CreateSectionAtStart("Duke.Autoload"); CreateSectionAtStart("Global.Autoload"); @@ -239,17 +240,7 @@ void FGameConfigFile::DoAutoloadSetup (/*FIWadManager *iwad_man*/) CreateStandardAutoExec("DukeNukem3D.DukeDC.AutoLoad", true); CreateStandardAutoExec("DukeNukem3D.NWinter.AutoLoad", true); CreateStandardAutoExec("DukeNukem3D.Vacation.AutoLoad", true); - - CreateStandardAutoExec("ShadowWarrior.AutoLoad", true); - CreateStandardAutoExec("Redneck.RidesAgain.AutoLoad", true); - CreateStandardAutoExec("Redneck.Redneck.AutoLoad", true); - CreateStandardAutoExec("WW2GI.AutoLoad", true); - CreateStandardAutoExec("Nam.AutoLoad", true); - CreateStandardAutoExec("DukeNukem3D.AutoLoad", true); - CreateStandardAutoExec("DukeNukem3D.DN3D.AutoLoad", true); - CreateStandardAutoExec("DukeNukem3D.DukeDC.AutoLoad", true); - CreateStandardAutoExec("DukeNukem3D.NWinter.AutoLoad", true); - CreateStandardAutoExec("DukeNukem3D.Vacation.AutoLoad", true); + CreateStandardAutoExec("DukeNukem3D.PParadise.AutoLoad", true); // Move search paths back to the top. MoveSectionToStart("SoundfontSearch.Directories"); diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 7bd8258d9..fe8b82ed1 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1036,6 +1036,7 @@ int RunGame() playername = userConfig.CommandName; } GameTicRate = 30; + InputScalePercentage = 0.14125; CheckUserMap(); palindexmap[0] = 255; @@ -1538,7 +1539,7 @@ DEFINE_ACTION_FUNCTION(_Screen, GetViewWindow) if (numret > 1) ret[1].SetInt(windowxy1.y); if (numret > 2) ret[2].SetInt(windowxy2.x - windowxy1.x + 1); if (numret > 3) ret[3].SetInt(windowxy2.y - windowxy1.y + 1); - return MIN(numret, 4); + return min(numret, 4); } DEFINE_ACTION_FUNCTION_NATIVE(_Raze, ShadeToLight, shadeToLight) diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index f28ec2906..4db5fd857 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -217,10 +217,7 @@ void S_PauseSound(bool notmusic, bool notsfx); void S_ResumeSound(bool notsfx); void S_SetSoundPaused(int state); -enum -{ - MaxSmoothRatio = FRACUNIT -}; +const int MaxSmoothRatio = FRACUNIT; FString G_GetDemoPath(); diff --git a/source/core/gamecvars.cpp b/source/core/gamecvars.cpp index 87df2e201..ca382e33b 100644 --- a/source/core/gamecvars.cpp +++ b/source/core/gamecvars.cpp @@ -80,17 +80,16 @@ CVARD(Bool, cl_syncinput, false, CVAR_ARCHIVE, "enable/disable synchronized inpu CVARD(Bool, cl_swsmoothsway, true, CVAR_ARCHIVE, "move SW weapon left and right smoothly while bobbing") CVARD(Bool, cl_showmagamt, false, CVAR_ARCHIVE, "show the amount of rounds left in the magazine of your weapon on the modern HUD") CVARD(Bool, cl_nomeleeblur, false, CVAR_ARCHIVE, "enable/disable blur effect with melee weapons in SW") -CVARD(Bool, cl_exhumedoldturn, false, CVAR_ARCHIVE, "enable/disable legacy turning speed for Powerslave/Exhumed") CVARD(Bool, cl_hudinterpolation, true, CVAR_ARCHIVE, "enable/disable HUD (weapon drawer) interpolation") CVARD(Bool, cl_bloodvanillarun, true, CVAR_ARCHIVE, "enable/disable Blood's vanilla run mode") CVARD(Bool, cl_bloodvanillabobbing, true, CVAR_ARCHIVE, "enable/disable Blood's vanilla bobbing while not using vanilla run mode") CVARD(Bool, cl_bloodvanillaexplosions, false, CVAR_ARCHIVE, "enable/disable Blood's vanilla explosion behavior") CVARD(Bool, cl_bloodvanillaenemies, false, CVAR_ARCHIVE, "enable/disable Blood's vanilla enemy behavior") CVARD(Bool, cl_bloodqavinterp, true, CVAR_ARCHIVE, "enable/disable Blood's QAV interpolation") -CVARD(Bool, cl_bloodqavforcedinterp, false, CVAR_ARCHIVE, "enable/disable Blood's QAV interpolation forcefully for QAVs that aren't defined as interpolatable") CVARD(Bool, cl_bloodweapinterp, false, CVAR_ARCHIVE, "enable/disable Blood's weapon interpolation. Depends on 'cl_bloodqavinterp'") CVARD(Bool, cl_bloodoldweapbalance, false, CVAR_ARCHIVE, "enable/disable legacy 1.0 weapon handling for Blood") CVARD(Bool, cl_loadingscreens, true, CVAR_ARCHIVE, "enable/disable loading screens for games") +CVARD(Bool, cl_preciseinputscaling, true, CVAR_ARCHIVE, "enable/disable precise scaling of unsynchronised input fraction") CUSTOM_CVARD(Int, cl_autoaim, 1, CVAR_ARCHIVE|CVAR_USERINFO, "enable/disable weapon autoaim") diff --git a/source/core/gamecvars.h b/source/core/gamecvars.h index acbe197eb..6a3533602 100644 --- a/source/core/gamecvars.h +++ b/source/core/gamecvars.h @@ -25,17 +25,16 @@ EXTERN_CVAR(Bool, cl_syncinput) EXTERN_CVAR(Bool, cl_swsmoothsway) EXTERN_CVAR(Bool, cl_showmagamt) EXTERN_CVAR(Bool, cl_nomeleeblur) -EXTERN_CVAR(Bool, cl_exhumedoldturn) EXTERN_CVAR(Bool, cl_hudinterpolation) EXTERN_CVAR(Bool, cl_bloodvanillarun) EXTERN_CVAR(Bool, cl_bloodvanillabobbing) EXTERN_CVAR(Bool, cl_bloodvanillaexplosions) EXTERN_CVAR(Bool, cl_bloodvanillaenemies) EXTERN_CVAR(Bool, cl_bloodqavinterp) -EXTERN_CVAR(Bool, cl_bloodqavforcedinterp) EXTERN_CVAR(Bool, cl_bloodweapinterp) EXTERN_CVAR(Bool, cl_bloodoldweapbalance) EXTERN_CVAR(Bool, cl_loadingscreens) +EXTERN_CVAR(Bool, cl_preciseinputscaling) EXTERN_CVAR(Bool, demorec_seeds_cvar) EXTERN_CVAR(Bool, demoplay_diffs) diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index c8cd23b40..c3954e173 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamestruct.h" #include "intvec.h" +TArray GlobalSectorList; //This is a shared list. Every client must leave it in the same state as it was when it started. //--------------------------------------------------------------------------- // @@ -33,7 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. int cameradist, cameraclock; -bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio) +bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, int *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio) { hitdata_t hitinfo; binangle daang; diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 00df8a3af..c02139ba6 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -4,11 +4,14 @@ #include "binaryangle.h" #include "build.h" +extern TArray GlobalSectorList; + extern int cameradist, cameraclock; void loaddefinitionsfile(const char* fn, bool cumulative = false, bool maingrp = false); -bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio); +bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, int *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio); + void PlanesAtPoint(const sectortype* sec, int dax, int day, float* ceilz, float* florz); inline void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz) // this is just for warning evasion. { @@ -151,3 +154,30 @@ inline int I_GetBuildTime() { return I_GetTime(120); } + +inline int32_t getangle(walltype* wal) +{ + return getangle( + wall[wal->point2].x - wal->x, + wall[wal->point2].y - wal->y); +} + +inline TArrayView sectors() +{ + return TArrayView(sector, numsectors); +} + +inline TArrayView walls() +{ + return TArrayView(wall, numwalls); +} + +inline TArrayView wallsofsector(sectortype* sec) +{ + return TArrayView(sec->firstWall(), sec->wallnum); +} + +inline TArrayView wallsofsector(int sec) +{ + return wallsofsector(§or[sec]); +} diff --git a/source/core/gameinput.cpp b/source/core/gameinput.cpp index 1cefe3b97..2a0ba5189 100644 --- a/source/core/gameinput.cpp +++ b/source/core/gameinput.cpp @@ -70,16 +70,31 @@ binangle getincanglebam(binangle a, binangle na) // //--------------------------------------------------------------------------- +/* +// Turbo turn time. +Blood: 24 * 30 = 720; +Duke: 120 / 8 * 30 = 450; +SW: 120 / 8 * 40 = 600; +Exhumed: N/A; +Average: 590.; +*/ + +enum +{ + BUILDTICRATE = 120, + TURBOTURNBASE = 590, +}; + static double turnheldtime; void updateTurnHeldAmt(double const scaleAdjust) { - turnheldtime += scaleAdjust * (120. / GameTicRate); + turnheldtime += getTicrateScale(BUILDTICRATE, scaleAdjust); } bool isTurboTurnTime() { - return turnheldtime >= 590. / GameTicRate; + return turnheldtime >= getTicrateScale(TURBOTURNBASE); } void resetTurnHeldAmt() @@ -98,47 +113,50 @@ void resetTurnHeldAmt() Blood: 92 / 4 * 2 * 30 = 1380; Duke: 15 * 2 * 2 * 30 = 1800; SW: 28 * 1.40625 * 40 = 1575; // Precisely, ((((28 * 12) + ((28 * 12) / 4)) * 3) / 32) * 40 -Average: 1585.; +Exhumed: 12 * 4 * 30 = 1440; +Average: 1548.75; // Normal speed. Blood: 92 / 4 * 30 = 690; Duke: 15 * 2 * 30 = 900; SW: 18 * 1.40625 * 40 = 1012.5; // Precisely, (((((12 + 6) * 12) + (((12 + 6) * 12) / 4)) * 3) / 32) * 40 -Average: 867.5; +Exhumed: 8 * 4 * 30 = 960; +Average: 890.625; // Preamble. -Blood: N/A; +Blood: N/A; +Exhumed: N/A; Duke: 5 * 2 * 30 = 300; SW: 3 * 1.40625 * 40 = 168.75; // Precisely, ((((3 * 12) + ((3 * 12) / 4)) * 3) / 32) * 40 Average: 234.375; -Ratio: 867.5 / 234.375 = (2776. / 750.); - -// Turbo turn time. -Blood: 24 * 30 = 720; -Duke: 128 / 8 * 30 = 450; -SW: 128 / 8 * 40 = 600; -Average: 590.; */ -void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlInfo* const hidInput, double const scaleAdjust, int const drink_amt, bool const allowstrafe, double const turnscale) +enum +{ + RUNNINGTURNBASE = 1549, + NORMALTURNBASE = 891, + PREAMBLEBASE = 234, +}; + +void processMovement(InputPacket* const currInput, InputPacket* const inputBuffer, ControlInfo* const hidInput, double const scaleAdjust, int const drink_amt, bool const allowstrafe, double const turnscale) { // set up variables int const running = !!(inputBuffer->actions & SB_RUN); int const keymove = gi->playerKeyMove() << running; - int const cntrlvelscale = g_gameType & GAMEFLAG_PSEXHUMED ? 8 : 1; - float const mousevelscale = keymove / 160.f; - double const hidspeed = ((running ? 1585. : 867.5) / GameTicRate) * BAngToDegree; + float const mousevelscale = keymove * (1.f / 160.f); + double const hidprescale = g_gameType & GAMEFLAG_PSEXHUMED ? 5. : 1.; + double const hidspeed = getTicrateScale(running ? RUNNINGTURNBASE : NORMALTURNBASE) * BAngToDegree; // process mouse and initial controller input. if (buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe) - currInput->svel -= xs_CRoundToInt((hidInput->mousemovex * mousevelscale) + (scaleAdjust * hidInput->dyaw * keymove * cntrlvelscale)); + currInput->svel -= xs_CRoundToInt(((hidInput->mousemovex * mousevelscale) + (scaleAdjust * hidInput->dyaw * keymove)) * hidprescale); else currInput->avel += float(hidInput->mouseturnx + (scaleAdjust * hidInput->dyaw * hidspeed * turnscale)); if (!(inputBuffer->actions & SB_AIMMODE)) currInput->horz -= hidInput->mouseturny; else - currInput->fvel -= xs_CRoundToInt(hidInput->mousemovey * mousevelscale); + currInput->fvel -= xs_CRoundToInt(hidInput->mousemovey * mousevelscale * hidprescale); if (invertmouse) currInput->horz = -currInput->horz; @@ -148,8 +166,8 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn // process remaining controller input. currInput->horz -= float(scaleAdjust * hidInput->dpitch * hidspeed); - currInput->svel += xs_CRoundToInt(scaleAdjust * hidInput->dx * keymove * cntrlvelscale); - currInput->fvel += xs_CRoundToInt(scaleAdjust * hidInput->dz * keymove * cntrlvelscale); + currInput->svel += xs_CRoundToInt(scaleAdjust * hidInput->dx * keymove * hidprescale); + currInput->fvel += xs_CRoundToInt(scaleAdjust * hidInput->dz * keymove * hidprescale); // process keyboard turning keys. if (buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe) @@ -165,24 +183,21 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn } else { - double turnamount = hidspeed * turnscale; - double preambleturn = turnamount * (750. / 2776.); + bool const turnleft = buttonMap.ButtonDown(gamefunc_Turn_Left) || (buttonMap.ButtonDown(gamefunc_Strafe_Left) && !allowstrafe); + bool const turnright = buttonMap.ButtonDown(gamefunc_Turn_Right) || (buttonMap.ButtonDown(gamefunc_Strafe_Right) && !allowstrafe); - // allow Exhumed to use its legacy values given the drastic difference from the other games. - if ((g_gameType & GAMEFLAG_PSEXHUMED) && cl_exhumedoldturn) + if (turnleft || turnright) { - preambleturn = turnamount = (running ? 12 : 8) * BAngToDegree; - } + double const turnamount = hidspeed * turnscale; + double const preambleturn = turnamount * (double(PREAMBLEBASE) / double(NORMALTURNBASE)); - if (buttonMap.ButtonDown(gamefunc_Turn_Left) || (buttonMap.ButtonDown(gamefunc_Strafe_Left) && !allowstrafe)) - { updateTurnHeldAmt(scaleAdjust); - currInput->avel -= float(scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn)); - } - else if (buttonMap.ButtonDown(gamefunc_Turn_Right) || (buttonMap.ButtonDown(gamefunc_Strafe_Right) && !allowstrafe)) - { - updateTurnHeldAmt(scaleAdjust); - currInput->avel += float(scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn)); + + if (turnleft) + currInput->avel -= float(scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn)); + + if (turnright) + currInput->avel += float(scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn)); } else { @@ -206,19 +221,13 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn if (buttonMap.ButtonDown(gamefunc_Move_Forward)) { currInput->fvel += keymove; - if (drink_amt & 1) - currInput->svel += keymove; - else - currInput->svel -= keymove; + currInput->svel += drink_amt & 1 ? keymove : -keymove; } if (buttonMap.ButtonDown(gamefunc_Move_Backward)) { currInput->fvel -= keymove; - if (drink_amt & 1) - currInput->svel -= keymove; - else - currInput->svel += keymove; + currInput->svel -= drink_amt & 1 ? keymove : -keymove; } } else @@ -244,60 +253,75 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn // //--------------------------------------------------------------------------- +/* +// Aim speed. +Duke: 6 * 30 = 180; +SW: (16 / 2) * 40 = 320; +Average: 250.; + +// Look speed. +Duke: 12 * 30 = 360; +SW: 16 * 40 = 640; +Average: 500.; + +// Return to centre speed. +Duke: (1 / 3) * 30 = 10; +SW: (1 / 4) * 40 = 10; +Average: 10.; +*/ + +enum +{ + AIMSPEED = 250, + LOOKSPEED = 500, + CNTRSPEED = 10, +}; + void PlayerHorizon::applyinput(float const horz, ESyncBits* actions, double const scaleAdjust) { // Process only if movewment isn't locked. if (!movementlocked()) { - // Store current horizon as true pitch. - double pitch = horiz.aspitch(); - - if (horz) + // Test if we have input to process. + if (horz || *actions & (SB_AIM_UP | SB_AIM_DOWN | SB_LOOK_UP | SB_LOOK_DOWN)) { - *actions &= ~SB_CENTERVIEW; - pitch += horz; + // Store current horizon as true pitch. + double pitch = horiz.aspitch(); + + // Process mouse input. + if (horz) + { + *actions &= ~SB_CENTERVIEW; + pitch += horz; + } + + // Process keyboard input. + auto doKbdInput = [&](ESyncBits_ const up, ESyncBits_ const down, double const rate, bool const lock) + { + if (*actions & (up | down)) + { + if (lock) *actions &= ~SB_CENTERVIEW; else *actions |= SB_CENTERVIEW; + double const amount = scaleAdjust * HorizToPitch(getTicrateScale(rate)); + + if (*actions & down) + pitch -= amount; + + if (*actions & up) + pitch += amount; + } + }; + doKbdInput(SB_AIM_UP, SB_AIM_DOWN, AIMSPEED, true); + doKbdInput(SB_LOOK_UP, SB_LOOK_DOWN, LOOKSPEED, false); + + // clamp before converting back to horizon + horiz = q16horiz(clamp(PitchToHoriz(pitch), gi->playerHorizMin(), gi->playerHorizMax())); } - // this is the locked type - if (*actions & (SB_AIM_UP|SB_AIM_DOWN)) - { - *actions &= ~SB_CENTERVIEW; - double const amount = HorizToPitch(250. / GameTicRate); - - if (*actions & SB_AIM_DOWN) - pitch -= scaleAdjust * amount; - - if (*actions & SB_AIM_UP) - pitch += scaleAdjust * amount; - } - - // this is the unlocked type - if (*actions & (SB_LOOK_UP|SB_LOOK_DOWN)) - { - *actions |= SB_CENTERVIEW; - double const amount = HorizToPitch(500. / GameTicRate); - - if (*actions & SB_LOOK_DOWN) - pitch -= scaleAdjust * amount; - - if (*actions & SB_LOOK_UP) - pitch += scaleAdjust * amount; - } - - // clamp before converting back to horizon - horiz = q16horiz(clamp(PitchToHoriz(pitch), gi->playerHorizMin(), gi->playerHorizMax())); - // return to center if conditions met. - if ((*actions & SB_CENTERVIEW) && !(*actions & (SB_LOOK_UP|SB_LOOK_DOWN)) && horiz.asq16()) + if ((*actions & SB_CENTERVIEW) && !(*actions & (SB_LOOK_UP|SB_LOOK_DOWN))) { - // move horiz back to 0 - horiz -= buildfhoriz(scaleAdjust * horiz.asbuildf() * (10. / GameTicRate)); - if (abs(horiz.asq16()) < (FRACUNIT >> 2)) - { - // not looking anymore because horiz is back at 0 - horiz = q16horiz(0); - *actions &= ~SB_CENTERVIEW; - } + scaletozero(horiz, CNTRSPEED, scaleAdjust); + if (!horiz.asq16()) *actions &= ~SB_CENTERVIEW; } } else @@ -312,35 +336,53 @@ void PlayerHorizon::applyinput(float const horz, ESyncBits* actions, double cons // //--------------------------------------------------------------------------- +/* +// Rotate return speed. +Duke: (1 / 2) * 30 = 15; + +// Look return speed. +Duke: (1 / 4) * 30 = 7.5; + +// Rotating speed. +Duke: 24 * 30 = 720; + +// Looking speed. +Duke: 152 * 30 = 4560; + +// Spin standing speed. +Duke: 128 * 30 = 3840; +Blood: 128 * 30 = 3840; + +// Looking speed. +Blood: 64 * 30 = 1920; +*/ + +enum +{ + LOOKROTRETBASE = 15, + ROTATESPEED = 720, + LOOKINGSPEED = 4560, + SPINSTAND = 3840, + SPINCROUCH = 1920, +}; + void PlayerAngle::applyinput(float const avel, ESyncBits* actions, double const scaleAdjust) { - if (rotscrnang.asbam()) - { - // return rotscrnang to 0 - rotscrnang -= buildfang(scaleAdjust * rotscrnang.signedbuildf() * (15. / GameTicRate)); - if (abs(rotscrnang.signedbam()) < (BAMUNIT >> 2)) rotscrnang = bamang(0); - } + // Process angle return to zeros. + scaletozero(rotscrnang, LOOKROTRETBASE, scaleAdjust); + scaletozero(look_ang, +LOOKROTRETBASE * 0.5, scaleAdjust); - if (look_ang.asbam()) + // Process keyboard input. + auto doLookKeys = [&](ESyncBits_ const key, double const direction) { - // return look_ang to 0 - look_ang -= buildfang(scaleAdjust * look_ang.signedbuildf() * (7.5 / GameTicRate)); - if (abs(look_ang.signedbam()) < (BAMUNIT >> 2)) look_ang = bamang(0); - } - - if (*actions & SB_LOOK_LEFT) - { - // start looking left - look_ang += buildfang(scaleAdjust * -(4560. / GameTicRate)); - rotscrnang += buildfang(scaleAdjust * (720. / GameTicRate)); - } - - if (*actions & SB_LOOK_RIGHT) - { - // start looking right - look_ang += buildfang(scaleAdjust * (4560. / GameTicRate)); - rotscrnang += buildfang(scaleAdjust * -(720. / GameTicRate)); - } + if (*actions & key) + { + look_ang += getscaledangle(LOOKINGSPEED, scaleAdjust * direction); + rotscrnang -= getscaledangle(ROTATESPEED, scaleAdjust * direction); + } + }; + doLookKeys(SB_LOOK_LEFT, -1); + doLookKeys(SB_LOOK_RIGHT, 1); if (!movementlocked()) { @@ -364,7 +406,7 @@ void PlayerAngle::applyinput(float const avel, ESyncBits* actions, double const if (spin < 0) { // return spin to 0 - double add = scaleAdjust * ((!(*actions & SB_CROUCH) ? 3840. : 1920.) / GameTicRate); + double add = getTicrateScale(!(*actions & SB_CROUCH) ? SPINSTAND : SPINCROUCH, scaleAdjust); spin += add; if (spin > 0) { @@ -387,6 +429,25 @@ void PlayerAngle::applyinput(float const avel, ESyncBits* actions, double const // //--------------------------------------------------------------------------- +/* +// Horizoff centre speed. +Duke: (1 / 8) * 30 = 3.75; +SW: (1 / 8) * 40 = 5; +Average: 4.375; +*/ + +enum +{ + // Values used by Duke/SW, where this function originated from. + DEFSINSHIFT = 5, + DEFVIEWPITCH = 160, + + // Values used by Blood since it calculates differently to Duke/SW. + BLOODSINSHIFT = 8, + SINSHIFTDELTA = BLOODSINSHIFT - DEFSINSHIFT, + BLOODVIEWPITCH = (0x4000 >> SINSHIFTDELTA) - (DEFVIEWPITCH << (SINSHIFTDELTA - 1)), // 1408. +}; + void PlayerHorizon::calcviewpitch(vec2_t const pos, binangle const ang, bool const aimmode, bool const canslopetilt, int const cursectnum, double const scaleAdjust, bool const climbing) { if (cl_slopetilting) @@ -394,10 +455,10 @@ void PlayerHorizon::calcviewpitch(vec2_t const pos, binangle const ang, bool con if (aimmode && canslopetilt) // If the floor is sloped { // Get a point, 512 (64 for Blood) units ahead of player's position - int const shift = -(isBlood() ? 8 : 5); + int const shift = -(isBlood() ? BLOODSINSHIFT : DEFSINSHIFT); int const x = pos.x + ang.bcos(shift); int const y = pos.y + ang.bsin(shift); - int16_t tempsect = cursectnum; + int tempsect = cursectnum; updatesector(x, y, &tempsect); if (tempsect >= 0) // If the new point is inside a valid sector... @@ -414,7 +475,7 @@ void PlayerHorizon::calcviewpitch(vec2_t const pos, binangle const ang, bool con // accordingly if (cursectnum == tempsect || (!isBlood() && abs(getflorzofslope(tempsect, x, y) - k) <= (4 << 8))) { - horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * ((j - k) * (!isBlood() ? 160 : 1408)))); + horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * ((j - k) * (!isBlood() ? DEFVIEWPITCH : BLOODVIEWPITCH)))); } } } @@ -423,21 +484,15 @@ void PlayerHorizon::calcviewpitch(vec2_t const pos, binangle const ang, bool con { // tilt when climbing but you can't even really tell it. if (horizoff.asq16() < IntToFixed(100)) - horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * (((IntToFixed(100) - horizoff.asq16()) >> 3) + FRACUNIT))); + { + auto temphorizoff = buildhoriz(100) - horizoff; + horizoff += getscaledhoriz(4.375, scaleAdjust, &temphorizoff, 1.); + } } else { // Make horizoff grow towards 0 since horizoff is not modified when you're not on a slope. - if (horizoff.asq16() > 0) - { - horizoff += q16horiz(xs_CRoundToInt(-scaleAdjust * ((horizoff.asq16() >> 3) + FRACUNIT))); - if (horizoff.asq16() < 0) horizoff = q16horiz(0); - } - if (horizoff.asq16() < 0) - { - horizoff += q16horiz(xs_CRoundToInt(-scaleAdjust * ((horizoff.asq16() >> 3) - FRACUNIT))); - if (horizoff.asq16() > 0) horizoff = q16horiz(0); - } + scaletozero(horizoff, 4.375, scaleAdjust, Sgn(horizoff.asq16())); } } } @@ -484,3 +539,17 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerHorizon& w, } return arc; } + +FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerPosition& w, PlayerPosition* def) +{ + if (arc.BeginObject(keyname)) + { + arc("pos", w.pos).EndObject(); + + if (arc.isReading()) + { + w.opos = w.pos; + } + } + return arc; +} diff --git a/source/core/gameinput.h b/source/core/gameinput.h index cb2befc7a..40059304a 100644 --- a/source/core/gameinput.h +++ b/source/core/gameinput.h @@ -9,69 +9,83 @@ int getincangle(int a, int na); binangle getincanglebam(binangle a, binangle na); + +//--------------------------------------------------------------------------- +// +// Functions for dividing an input value by current ticrate for angle/horiz scaling. +// +//--------------------------------------------------------------------------- + +inline double getTicrateScale(double const value) +{ + return value / GameTicRate; +} + +inline double getTicrateScale(double const value, double const scaleAdjust) +{ + return scaleAdjust * getTicrateScale(value); +} + + struct PlayerHorizon { fixedhoriz horiz, ohoriz, horizoff, ohorizoff; friend FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerHorizon& w, PlayerHorizon* def); + // Prototypes for functions in gameinput.cpp. + void applyinput(float const horz, ESyncBits* actions, double const scaleAdjust = 1); + void calcviewpitch(vec2_t const pos, binangle const ang, bool const aimmode, bool const canslopetilt, int const cursectnum, double const scaleAdjust = 1, bool const climbing = false); + + // Interpolation helpers. void backup() { ohoriz = horiz; ohorizoff = horizoff; } - void restore() { horiz = ohoriz; horizoff = ohorizoff; } - void addadjustment(double value) + // Commonly used getters. + fixedhoriz osum() { return ohoriz + ohorizoff; } + fixedhoriz sum() { return horiz + horizoff; } + fixedhoriz interpolatedsum(double const smoothratio) { return interpolatedhorizon(osum(), sum(), smoothratio); } + + // Ticrate playsim adjustment helpers. + void addadjustment(double value) { __addadjustment(buildfhoriz(value)); } + void addadjustment(fixedhoriz value) { __addadjustment(value); } + void settarget(double value, bool backup = false) { __settarget(buildfhoriz(value), backup); } + void settarget(fixedhoriz value, bool backup = false) { __settarget(value, backup); } + void resetadjustment() { adjustment = 0; } + bool targetset() { return target.asq16(); } + + // Input locking helpers. + void lockinput() { inputdisabled = true; } + void unlockinput() { inputdisabled = false; } + bool movementlocked() { return targetset() || inputdisabled; } + + // Draw code helpers. + double horizsumfrac(double const smoothratio) { return (!SyncInput() ? sum() : interpolatedsum(smoothratio)).asbuildf() * (1. / 16.); } + + // Ticrate scale helpers. + fixedhoriz getscaledhoriz(double const value, double const scaleAdjust = 1., fixedhoriz* const object = nullptr, double const push = 0.) { - __addadjustment(buildfhoriz(value)); - } - - void addadjustment(fixedhoriz value) - { - __addadjustment(value); - } - - void resetadjustment() - { - adjustment = 0; - } - - void settarget(double value, bool backup = false) - { - __settarget(buildfhoriz(value), backup); - } - - void settarget(fixedhoriz value, bool backup = false) - { - __settarget(value, backup); - } - - void lockinput() - { - inputdisabled = true; - } - - void unlockinput() - { - inputdisabled = false; - } - - bool targetset() - { - return target.asq16(); - } - - bool movementlocked() - { - return target.asq16() || inputdisabled; + return buildfhoriz(scaleAdjust * (((object ? object->asbuildf() : 1.) * getTicrateScale(value)) + push)); + } + void scaletozero(fixedhoriz& object, double const value, double const scaleAdjust, double const push = 0.) + { + if (object.asq16()) + { + auto sgn = Sgn(object.asq16()); + object -= getscaledhoriz(value, scaleAdjust, &object, push == 0 ? sgn * (1. / 3.) : push); + if (sgn != Sgn(object.asq16())) object = q16horiz(0); + } } + // Ticrate playsim adjustment processor. void processhelpers(double const scaleAdjust) { if (targetset()) @@ -94,35 +108,6 @@ struct PlayerHorizon } } - fixedhoriz osum() - { - return ohoriz + ohorizoff; - } - - fixedhoriz sum() - { - return horiz + horizoff; - } - - fixedhoriz interpolatedsum(double const smoothratio) - { - return q16horiz(interpolatedvalue(osum().asq16(), sum().asq16(), smoothratio)); - } - - double horizsumfrac(double const smoothratio) - { - return (!SyncInput() ? sum() : interpolatedsum(smoothratio)).asbuildf() * (1. / 16.); // Used within draw code for Duke. - } - - fixedhoriz interpolatedoff(double const smoothratio) - { - double const ratio = smoothratio * (1. / FRACUNIT); - return q16horiz(ohorizoff.asq16() + xs_CRoundToInt(ratio * (horizoff - ohorizoff).asq16())); - } - - void applyinput(float const horz, ESyncBits* actions, double const scaleAdjust = 1); - void calcviewpitch(vec2_t const pos, binangle const ang, bool const aimmode, bool const canslopetilt, int const cursectnum, double const scaleAdjust = 1, bool const climbing = false); - private: fixedhoriz target; double adjustment; @@ -164,13 +149,16 @@ struct PlayerAngle friend FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngle& w, PlayerAngle* def); + // Prototypes for functions in gameinput.cpp. + void applyinput(float const avel, ESyncBits* actions, double const scaleAdjust = 1); + + // Interpolation helpers. void backup() { oang = ang; olook_ang = look_ang; orotscrnang = rotscrnang; } - void restore() { ang = oang; @@ -178,51 +166,46 @@ struct PlayerAngle rotscrnang = orotscrnang; } - void addadjustment(double value) + // Commonly used getters. + binangle osum() { return oang + olook_ang; } + binangle sum() { return ang + look_ang; } + binangle interpolatedsum(double const smoothratio) { return interpolatedangle(osum(), sum(), smoothratio); } + binangle interpolatedlookang(double const smoothratio) { return interpolatedangle(olook_ang, look_ang, smoothratio); } + binangle interpolatedrotscrn(double const smoothratio) { return interpolatedangle(orotscrnang, rotscrnang, smoothratio); } + + // Ticrate playsim adjustment helpers. + void addadjustment(double value) { __addadjustment(buildfang(value)); } + void addadjustment(binangle value) { __addadjustment(value); } + void settarget(double value, bool backup = false) { __settarget(buildfang(value), backup); } + void settarget(binangle value, bool backup = false) { __settarget(value, backup); } + void resetadjustment() { adjustment = 0; } + bool targetset() { return target.asbam(); } + + // Input locking helpers. + void lockinput() { inputdisabled = true; } + void unlockinput() { inputdisabled = false; } + bool movementlocked() { return targetset() || inputdisabled; } + + // Draw code helpers. + double look_anghalf(double const smoothratio) { return (!SyncInput() ? look_ang : interpolatedlookang(smoothratio)).signedbuildf() * 0.5; } + double looking_arc(double const smoothratio) { return fabs((!SyncInput() ? look_ang : interpolatedlookang(smoothratio)).signedbuildf()) * (1. / 9.); } + + // Ticrate scale helpers. + binangle getscaledangle(double const value, double const scaleAdjust = 1., binangle* const object = nullptr, double const push = 0.) { - __addadjustment(buildfang(value)); - } - - void addadjustment(binangle value) - { - __addadjustment(value); - } - - void resetadjustment() - { - adjustment = 0; - } - - void settarget(double value, bool backup = false) - { - __settarget(buildfang(value), backup); - } - - void settarget(binangle value, bool backup = false) - { - __settarget(value, backup); - } - - void lockinput() - { - inputdisabled = true; - } - - void unlockinput() - { - inputdisabled = false; - } - - bool targetset() - { - return target.asbam(); - } - - bool movementlocked() - { - return target.asq16() || inputdisabled; + return buildfang(scaleAdjust * (((object ? object->signedbuildf() : 1.) * getTicrateScale(value)) + push)); + } + void scaletozero(binangle& object, double const value, double const scaleAdjust, double const push = 0.) + { + if (object.asbam()) + { + auto sgn = Sgn(object.signedbam()); + object -= getscaledangle(value, scaleAdjust, &object, push == 0 ? sgn * (1. / 3.) : push); + if (sgn != Sgn(object.signedbam())) object = bamang(0); + } } + // Ticrate playsim adjustment processor. void processhelpers(double const scaleAdjust) { if (targetset()) @@ -245,43 +228,6 @@ struct PlayerAngle } } - binangle osum() - { - return oang + olook_ang; - } - - binangle sum() - { - return ang + look_ang; - } - - binangle interpolatedsum(double const smoothratio) - { - return interpolatedangle(osum(), sum(), smoothratio); - } - - binangle interpolatedlookang(double const smoothratio) - { - return interpolatedangle(olook_ang, look_ang, smoothratio); - } - - binangle interpolatedrotscrn(double const smoothratio) - { - return interpolatedangle(orotscrnang, rotscrnang, smoothratio); - } - - double look_anghalf(double const smoothratio) - { - return (!SyncInput() ? look_ang : interpolatedlookang(smoothratio)).signedbuildf() * 0.5; // Used within draw code for weapon and crosshair when looking left/right. - } - - double looking_arc(double const smoothratio) - { - return fabs((!SyncInput() ? look_ang : interpolatedlookang(smoothratio)).signedbuildf()) * (1. / 9.); // Used within draw code for weapon and crosshair when looking left/right. - } - - void applyinput(float const avel, ESyncBits* actions, double const scaleAdjust = 1); - private: binangle target; double adjustment; @@ -314,12 +260,48 @@ private: } }; +struct PlayerPosition +{ + vec3_t pos, opos; + + // Interpolation helpers. + void backupx() { opos.x = pos.x; } + void backupy() { opos.y = pos.y; } + void backupz() { opos.z = pos.z; } + void backuppos() { opos = pos; } + + // Interpolated points. + int32_t interpolatedx(double const smoothratio, int const scale = 16) { return interpolatedvalue(opos.x, pos.x, smoothratio, scale); } + int32_t interpolatedy(double const smoothratio, int const scale = 16) { return interpolatedvalue(opos.y, pos.y, smoothratio, scale); } + int32_t interpolatedz(double const smoothratio, int const scale = 16) { return interpolatedvalue(opos.z, pos.z, smoothratio, scale); } + + // Interpolated vectors. + vec2_t interpolatedvec2(double const smoothratio, int const scale = 16) + { + return + { + interpolatedx(smoothratio, scale), + interpolatedy(smoothratio, scale) + }; + } + vec3_t interpolatedvec3(double const smoothratio, int const scale = 16) + { + return + { + interpolatedx(smoothratio, scale), + interpolatedy(smoothratio, scale), + interpolatedz(smoothratio, scale) + }; + } +}; + class FSerializer; FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngle& w, PlayerAngle* def); FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerHorizon& w, PlayerHorizon* def); +FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerPosition& w, PlayerPosition* def); void updateTurnHeldAmt(double const scaleAdjust); bool isTurboTurnTime(); void resetTurnHeldAmt(); -void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlInfo* const hidInput, double const scaleAdjust, int const drink_amt = 0, bool const allowstrafe = true, double const turnscale = 1); +void processMovement(InputPacket* const currInput, InputPacket* const inputBuffer, ControlInfo* const hidInput, double const scaleAdjust, int const drink_amt = 0, bool const allowstrafe = true, double const turnscale = 1); diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 96eb491b4..0196ddb75 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -48,6 +48,7 @@ static int WeaponToSend = 0; ESyncBits ActionsToSend = 0; static int dpad_lock = 0; +double InputScalePercentage = 0; bool sendPause; bool crouch_toggle; static double lastCheck; @@ -480,10 +481,19 @@ double InputScale() { if (!SyncInput()) { - double now = I_msTimeF(); - double elapsedInputTicks = lastCheck > 0 ? min(now - lastCheck, 1000.0 / GameTicRate) : 1; + const double max = 1000. / GameTicRate; + const double now = I_msTimeF(); + const double elapsedInputTicks = lastCheck > 0 ? min(now - lastCheck, max) : 1.; lastCheck = now; - return elapsedInputTicks * GameTicRate / 1000.0; + if (elapsedInputTicks == max) return 1; + + // Calculate a scale increase of the percentage InputScalePercentage is set as to correct an + // inherent drift in this function that progressively causes the actions that depend + // on this fractional scale to increase by over 100 ms as the framerate increases. + // This isn't pretty, but it's accurate to within 1-2 ms from 60 fps to at least 1000 fps. + const double result = elapsedInputTicks * GameTicRate / 1000.; + const double scaler = cl_preciseinputscaling ? 1. + InputScalePercentage * (1. - result) : 1.; + return result * scaler; } else { diff --git a/source/core/inputstate.h b/source/core/inputstate.h index dd457046e..0d82c8154 100644 --- a/source/core/inputstate.h +++ b/source/core/inputstate.h @@ -106,6 +106,7 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo* const hidInput, bool cons extern ESyncBits ActionsToSend; double InputScale(); extern bool gamesetinput; +extern double InputScalePercentage; inline bool SyncInput() { diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index a2f7eb0a4..090055a18 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -150,6 +150,7 @@ void NewGame(MapRecord* map, int skill, bool ns = false) ShowIntermission(nullptr, map, nullptr, [=](bool) { gi->NewGame(map, skill, ns); ResetStatusBar(); + Net_ClearFifo(); }); } @@ -200,6 +201,7 @@ static void GameTicker() gameaction = ga_level; gi->NextLevel(g_nextmap, g_nextskill); ResetStatusBar(); + Net_ClearFifo(); } else { @@ -213,6 +215,7 @@ static void GameTicker() gameaction = ga_level; gi->NextLevel(g_nextmap, g_nextskill); ResetStatusBar(); + Net_ClearFifo(); break; case ga_newgame: @@ -490,7 +493,7 @@ static void TicStabilityEnd() { using namespace std::chrono; uint64_t stabilityendtime = duration_cast(steady_clock::now().time_since_epoch()).count(); - stabilityticduration = std::min(stabilityendtime - stabilitystarttime, (uint64_t)1'000'000); + stabilityticduration = min(stabilityendtime - stabilitystarttime, (uint64_t)1'000'000); } //========================================================================== diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index 60928599c..69e8a3eb0 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -206,7 +206,7 @@ static void SetWallPalV5() } } -static void ValidateSprite(spritetype& spr) +void ValidateSprite(spritetype& spr) { int index = int(&spr - sprite); bool bugged = false; @@ -222,13 +222,15 @@ static void ValidateSprite(spritetype& spr) } else if ((unsigned)spr.sectnum >= (unsigned)numsectors) { - const int32_t osectnum = spr.sectnum; + int sectnum = -1; + updatesector(spr.x, spr.y, §num); - spr.sectnum = -1; - updatesector(spr.x, spr.y, &spr.sectnum); - - bugged = spr.sectnum < 0; - if (bugged) Printf("Sprite #%d (%d,%d) with invalid sector %d\n", index, spr.x, spr.y, spr.sectnum); + if (!DPrintf(DMSG_WARNING, "Sprite #%d (%d,%d) with invalid sector %d was corrected to sector %d\n", index, spr.x, spr.y, spr.sectnum, sectnum)) + { + bugged = sectnum < 0; + if (bugged) Printf("Sprite #%d (%d,%d) with invalid sector %d\n", index, spr.x, spr.y, spr.sectnum); + } + spr.sectnum = sectnum; } if (bugged) { @@ -332,7 +334,7 @@ static void ReadSpriteV5(FileReader& fr, spritetype& spr) } -static void insertAllSprites(const char* filename, const vec3_t* pos, int16_t* cursectnum, int16_t numsprites) +static void insertAllSprites(const char* filename, const vec3_t* pos, int* cursectnum, int16_t numsprites) { // This function is stupid because it exploits side effects of insertsprite and should be redone by only inserting the valid sprites. int i, realnumsprites = numsprites; @@ -373,7 +375,7 @@ static void insertAllSprites(const char* filename, const vec3_t* pos, int16_t* c void addBlockingPairs(); -void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, int16_t* cursectnum) +void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, int* cursectnum) { inputState.ClearAllInput(); memset(sector, 0, sizeof(*sector) * MAXSECTORS); @@ -469,6 +471,7 @@ void loadMapBackup(const char* filename) { vec3_t pos; int16_t scratch; + int scratch2; if (isBlood()) { @@ -476,7 +479,7 @@ void loadMapBackup(const char* filename) } else { - engineLoadBoard(filename, 0, &pos, &scratch, &scratch); + engineLoadBoard(filename, 0, &pos, &scratch, &scratch2); initspritelists(); } } @@ -507,4 +510,4 @@ void setWallSectors() } } -} \ No newline at end of file +} diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index e6adecb1c..28d9eb3fb 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -35,7 +35,7 @@ // HEADER FILES ------------------------------------------------------------ -#include "templates.h" + #include "c_dispatch.h" #include "filesystem.h" #include "v_text.h" diff --git a/source/core/nodebuilder/nodebuild.cpp b/source/core/nodebuilder/nodebuild.cpp index f355cba9c..26cb203dd 100644 --- a/source/core/nodebuilder/nodebuild.cpp +++ b/source/core/nodebuilder/nodebuild.cpp @@ -141,10 +141,10 @@ int FNodeBuilder::CreateNode (uint32_t set, unsigned int count, fixed_t bbox[4]) D(PrintSet (2, set2)); node.intchildren[0] = CreateNode (set1, count1, node.nb_bbox[0]); node.intchildren[1] = CreateNode (set2, count2, node.nb_bbox[1]); - bbox[BOXTOP] = MAX (node.nb_bbox[0][BOXTOP], node.nb_bbox[1][BOXTOP]); - bbox[BOXBOTTOM] = MIN (node.nb_bbox[0][BOXBOTTOM], node.nb_bbox[1][BOXBOTTOM]); - bbox[BOXLEFT] = MIN (node.nb_bbox[0][BOXLEFT], node.nb_bbox[1][BOXLEFT]); - bbox[BOXRIGHT] = MAX (node.nb_bbox[0][BOXRIGHT], node.nb_bbox[1][BOXRIGHT]); + bbox[BOXTOP] = max(node.nb_bbox[0][BOXTOP], node.nb_bbox[1][BOXTOP]); + bbox[BOXBOTTOM] = min(node.nb_bbox[0][BOXBOTTOM], node.nb_bbox[1][BOXBOTTOM]); + bbox[BOXLEFT] = min(node.nb_bbox[0][BOXLEFT], node.nb_bbox[1][BOXLEFT]); + bbox[BOXRIGHT] = max(node.nb_bbox[0][BOXRIGHT], node.nb_bbox[1][BOXRIGHT]); return (int)Nodes.Push (node); } else @@ -630,7 +630,7 @@ int FNodeBuilder::Heuristic (node_t &node, uint32_t set, bool honorNoSplit) frac = 1 - frac; } int penalty = int(1 / frac); - score = MAX(score - penalty, 1); + score = std::max(score - penalty, 1); D(Printf ("Penalized splitter by %d for being near endpt of seg %d (%f).\n", penalty, i, frac)); } diff --git a/source/core/nodebuilder/nodebuild_utility.cpp b/source/core/nodebuilder/nodebuild_utility.cpp index ddf6cbe72..7169d2569 100644 --- a/source/core/nodebuilder/nodebuild_utility.cpp +++ b/source/core/nodebuilder/nodebuild_utility.cpp @@ -383,8 +383,8 @@ FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder, { MinX = minx; MinY = miny; - BlocksWide = int(((double(maxx) - minx + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE); - BlocksTall = int(((double(maxy) - miny + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE); + BlocksWide = int(((double(maxx) - minx + 1) + (BLOCK_SIZE - 1)) / +BLOCK_SIZE); + BlocksTall = int(((double(maxy) - miny + 1) + (BLOCK_SIZE - 1)) / +BLOCK_SIZE); MaxX = MinX + fixed64_t(BlocksWide) * BLOCK_SIZE - 1; MaxY = MinY + fixed64_t(BlocksTall) * BLOCK_SIZE - 1; VertexGrid = new TArray[BlocksWide * BlocksTall]; @@ -447,10 +447,10 @@ int FNodeBuilder::FVertexMap::InsertVertex (FNodeBuilder::FPrivVert &vert) // If a vertex is near a block boundary, then it will be inserted on // both sides of the boundary so that SelectVertexClose can find // it by checking in only one block. - fixed64_t minx = MAX (MinX, fixed64_t(vert.x) - VERTEX_EPSILON); - fixed64_t maxx = MIN (MaxX, fixed64_t(vert.x) + VERTEX_EPSILON); - fixed64_t miny = MAX (MinY, fixed64_t(vert.y) - VERTEX_EPSILON); - fixed64_t maxy = MIN (MaxY, fixed64_t(vert.y) + VERTEX_EPSILON); + fixed64_t minx = max(MinX, fixed64_t(vert.x) - VERTEX_EPSILON); + fixed64_t maxx = min(MaxX, fixed64_t(vert.x) + VERTEX_EPSILON); + fixed64_t miny = max(MinY, fixed64_t(vert.y) - VERTEX_EPSILON); + fixed64_t maxy = min(MaxY, fixed64_t(vert.y) + VERTEX_EPSILON); int blk[4] = { diff --git a/source/core/palette.cpp b/source/core/palette.cpp index cfb395ed0..036b1568b 100644 --- a/source/core/palette.cpp +++ b/source/core/palette.cpp @@ -488,9 +488,9 @@ void DrawFullscreenBlends() // These get prepended to the 2D drawer so they must be submitted in reverse order of drawing. if (tint_blood_r | tint_blood_g | tint_blood_b) { - PalEntry color2(255, std::max(-tint_blood_r, 0), std::max(-tint_blood_g, 0), std::max(-tint_blood_b, 0)); + PalEntry color2(255, max(-tint_blood_r, 0), max(-tint_blood_g, 0), max(-tint_blood_b, 0)); twod->AddColorOnlyQuad(0, 0, twod->GetWidth(), twod->GetHeight(), color2, &LegacyRenderStyles[STYLE_Subtract], true); - PalEntry color(255, std::max(tint_blood_r, 0), std::max(tint_blood_g, 0), std::max(tint_blood_b, 0)); + PalEntry color(255, max(tint_blood_r, 0), max(tint_blood_g, 0), max(tint_blood_b, 0)); twod->AddColorOnlyQuad(0, 0, twod->GetWidth(), twod->GetHeight(), color, &LegacyRenderStyles[STYLE_Add], true); } diff --git a/source/core/palette.h b/source/core/palette.h index efc60b428..68e1fe7e5 100644 --- a/source/core/palette.h +++ b/source/core/palette.h @@ -15,7 +15,7 @@ #include "filesystem.h" #include "zstring.h" #include "palentry.h" -#include "templates.h" + enum { diff --git a/source/core/rendering/hw_entrypoint.cpp b/source/core/rendering/hw_entrypoint.cpp index a9dd0cb1a..e07bd2c75 100644 --- a/source/core/rendering/hw_entrypoint.cpp +++ b/source/core/rendering/hw_entrypoint.cpp @@ -314,9 +314,7 @@ void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sect if (gl_fogmode == 1) gl_fogmode = 2; // still needed? - int16_t sect = sectnum; - updatesector(position.x, position.y, §); - if (sect >= 0) sectnum = sect; + updatesector(position.x, position.y, §num); if (sectnum < 0) return; iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; @@ -369,9 +367,7 @@ void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sect void render_camtex(spritetype* playersprite, const vec3_t& position, int sectnum, binangle angle, fixedhoriz horizon, binangle rollang, FGameTexture* camtex, IntRect& rect, double smoothratio) { - int16_t sect = sectnum; - updatesector(position.x, position.y, §); - if (sect >= 0) sectnum = sect; + updatesector(position.x, position.y, §num); if (sectnum < 0) return; screen->RenderState()->SetVertexBuffer(screen->mVertexData); diff --git a/source/core/rendering/scene/hw_portal.h b/source/core/rendering/scene/hw_portal.h index 77278edfb..8bbc65c92 100644 --- a/source/core/rendering/scene/hw_portal.h +++ b/source/core/rendering/scene/hw_portal.h @@ -96,8 +96,8 @@ struct BoundingRect double distanceTo(const BoundingRect& other) const { if (intersects(other)) return 0; - return std::max(std::min(fabs(left - other.right), fabs(right - other.left)), - std::min(fabs(top - other.bottom), fabs(bottom - other.top))); + return max(min(fabs(left - other.right), fabs(right - other.left)), + min(fabs(top - other.bottom), fabs(bottom - other.top))); } void addVertex(double x, double y) diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index 24d54c23b..c6c9bf282 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -930,10 +930,10 @@ void HWWall::DoMidTexture(HWDrawInfo* di, walltype* wal, refheight = max(front->ceilingz, back->ceilingz); } - topleft = std::min(bch1,fch1); - topright = std::min(bch2,fch2); - bottomleft = std::max(bfh1,ffh1); - bottomright = std::max(bfh2,ffh2); + topleft = min(bch1,fch1); + topright = min(bch2,fch2); + bottomleft = max(bfh1,ffh1); + bottomright = max(bfh2,ffh2); if (topleft<=bottomleft && topright<=bottomright) return; type = seg->cstat & CSTAT_WALL_1WAY ? RENDERWALL_M1S : RENDERWALL_M2S; diff --git a/source/core/searchpaths.cpp b/source/core/searchpaths.cpp index 43b4b6ca7..4f2b8fdf4 100644 --- a/source/core/searchpaths.cpp +++ b/source/core/searchpaths.cpp @@ -96,6 +96,7 @@ static const char * ww2gi[] = { "/WW2GI", nullptr}; static const char * bloodfs[] = { "", R"(/addons/Cryptic Passage)", nullptr}; static const char * sw[] = { "/Shadow Warrior", nullptr}; static const char * redneck[] = { "/Redneck", "/AGAIN", "/HUNTIN", nullptr }; +static const char * dukezoom[] = { "/", "/AddOns", nullptr }; #ifndef _WIN64 #define WOW64 "\\" @@ -113,6 +114,8 @@ static const RegistryPathInfo paths[] = { { L"SOFTWARE" WOW64 "GOG.com\\Games\\1740836875", L"path", nullptr}, { L"SOFTWARE" WOW64 "GOG.com\\Games\\2132611980", L"path", nullptr}, // Powerslave + { L"SOFTWARE" WOW64 "ZOOM PLATFORM\\Duke Nukem 3D - Atomic Edition", L"InstallPath", dukezoom }, + { L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App 434050", L"InstallLocation", nullptr }, { L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App 225140", L"InstallLocation", dukeaddons }, { L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App 359850", L"InstallLocation", dn3d }, diff --git a/source/core/statusbar2.cpp b/source/core/statusbar2.cpp index c9c3f155c..60a232f91 100644 --- a/source/core/statusbar2.cpp +++ b/source/core/statusbar2.cpp @@ -36,7 +36,7 @@ #include #include "build.h" -#include "templates.h" + #include "statusbar.h" #include "c_cvars.h" #include "c_dispatch.h" @@ -109,7 +109,7 @@ void setViewport(int viewSize) reserved.top = xs_CRoundToInt((reserved.top * hud_scalefactor * ydim) / 200); reserved.statusbar = xs_CRoundToInt((reserved.statusbar * hud_scalefactor * ydim) / 200); - int xdimcorrect = std::min(Scale(ydim, 4, 3), xdim); + int xdimcorrect = min(Scale(ydim, 4, 3), xdim); if (viewSize > Hud_Stbar) { x0 = 0; diff --git a/source/core/version.h b/source/core/version.h index f1d9c4aca..48d4db272 100644 --- a/source/core/version.h +++ b/source/core/version.h @@ -73,13 +73,13 @@ const char *GetVersionString(); #define MINSAVEVER_DN3D 11 #define MINSAVEVER_BLD 12 #define MINSAVEVER_SW 13 -#define MINSAVEVER_PS 13 +#define MINSAVEVER_PS 15 #define MINSAVEVER_WH 10 #define SAVEVER_DN3D 11 #define SAVEVER_BLD 12 #define SAVEVER_SW 13 -#define SAVEVER_PS 13 +#define SAVEVER_PS 15 #define SAVEVER_WH 10 #define OLD_SAVEGAME 1 // this is to keep writing out the old format in Blood, even when data has been refactored. diff --git a/source/g_pch.h b/source/g_pch.h index db20b29f9..2f0347a54 100644 --- a/source/g_pch.h +++ b/source/g_pch.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -21,7 +20,6 @@ #include #include #include -#include // These two headers get included nearly everywhere so it doesn't matter if changing them forces a few more recompiles. // The overall savings from PCHing them are more significant. diff --git a/source/games/blood/src/_polymost.cpp b/source/games/blood/src/_polymost.cpp index decc850bb..88fbda77d 100644 --- a/source/games/blood/src/_polymost.cpp +++ b/source/games/blood/src/_polymost.cpp @@ -162,7 +162,7 @@ RORHACK: gView->pSprite->cstat |= 514; } - renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum); + renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum, false); viewProcessSprites(pm_tsprite, pm_spritesortcnt, cX, cY, cZ, cA.asbuild(), int(gInterpolate)); bool do_ror_hack = false; for (int i = 0; i < 16; i++) @@ -254,7 +254,7 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int { renderPrepareMirror(x, y, z, a, horiz, nWall, &cx, &cy, &ca); } - int32_t didmirror = renderDrawRoomsQ16(cx, cy, z, ca, horiz, mirrorsector | MAXSECTORS); + int32_t didmirror = renderDrawRoomsQ16(cx, cy, z, ca, horiz, mirrorsector, true); viewProcessSprites(pm_tsprite, pm_spritesortcnt, cx, cy, z, FixedToInt(ca), smooth); renderDrawMasks(); if (GetWallType(nWall) != kWallStack) @@ -282,7 +282,7 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int gPlayer[viewPlayer].pSprite->cstat |= 514; } } - renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector | MAXSECTORS); + renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector, true); viewProcessSprites(pm_tsprite, pm_spritesortcnt, x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, FixedToInt(a), smooth); short fstat = sector[nSector].floorstat; sector[nSector].floorstat |= 1; @@ -314,7 +314,7 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int gPlayer[viewPlayer].pSprite->cstat |= 514; } } - renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector | MAXSECTORS); + renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector, true); viewProcessSprites(pm_tsprite, pm_spritesortcnt, x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, FixedToInt(a), smooth); short cstat = sector[nSector].ceilingstat; sector[nSector].ceilingstat |= 1; diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index d405fbc7e..703a035de 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -2571,7 +2571,7 @@ static void ConcussSprite(DBloodActor* source, DBloodActor* actor, int x, int y, #ifdef NOONE_EXTENSIONS if (pSprite->type == kDudeModernCustom || pSprite->type == kDudeModernCustomBurning) { - mass = getSpriteMassBySize(pSprite); + mass = getSpriteMassBySize(actor); } #endif } @@ -2770,7 +2770,7 @@ static void actNapalmMove(DBloodActor* actor) static DBloodActor* actSpawnFloor(DBloodActor* actor) { auto pSprite = &actor->s(); - short sector = pSprite->sectnum; + int sector = pSprite->sectnum; int x = pSprite->x; int y = pSprite->y; updatesector(x, y, §or); @@ -2985,7 +2985,7 @@ static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType) { pXSprite->locked = 1; // lock while transforming - aiSetGenIdleState(pSprite, pXSprite); // set idle state + aiSetGenIdleState(actor); // set idle state if (pXSprite->key > 0) // drop keys actDropObject(actor, kItemKeyBase + pXSprite->key - 1); @@ -4210,7 +4210,7 @@ static void actTouchFloor(DBloodActor* actor, int nSector) actDamageSprite(actor, actor, nDamageType, scale(4, nDamage, 120) << 4); } - if (tileGetSurfType(nSector + 0x4000) == kSurfLava) + if (tileGetSurfType(sector[nSector].floorpicnum) == kSurfLava) { actDamageSprite(actor, actor, kDamageBurn, 16); sfxPlay3DSound(actor, 352, 5, 2); @@ -4267,7 +4267,7 @@ static void checkCeilHit(DBloodActor* actor) { case kDudeModernCustom: case kDudeModernCustomBurning: - mass2 = getSpriteMassBySize(pSprite); + mass2 = getSpriteMassBySize(actor); break; } if (mass1 > mass2) @@ -4292,7 +4292,7 @@ static void checkCeilHit(DBloodActor* actor) case kDudeModernCustom: case kDudeModernCustomBurning: int dmg = 0; - if (!actor->IsDudeActor() || (dmg = ClipLow((getSpriteMassBySize(pSprite2) - getSpriteMassBySize(pSprite)) >> 1, 0)) == 0) + if (!actor->IsDudeActor() || (dmg = ClipLow((getSpriteMassBySize(actor2) - getSpriteMassBySize(actor)) >> 1, 0)) == 0) break; if (!actor->IsPlayerActor()) @@ -4359,7 +4359,7 @@ static void checkHit(DBloodActor* actor) { case kDudeModernCustom: case kDudeModernCustomBurning: - mass2 = getSpriteMassBySize(pSprite2); + mass2 = getSpriteMassBySize(actor2); break; } if (mass1 > mass2) @@ -4436,7 +4436,7 @@ static void checkFloorHit(DBloodActor* actor) { case kDudeModernCustom: case kDudeModernCustomBurning: - mass2 = getSpriteMassBySize(pSprite2); + mass2 = getSpriteMassBySize(actor2); break; } @@ -4548,12 +4548,11 @@ static void ProcessTouchObjects(DBloodActor* actor) if (gModernMap && actor->IsDudeActor()) { DBloodActor* actor2 = nullptr; - for (int i : { actor->hit().hit, actor->hit().florhit, actor->hit().ceilhit}) + for (Collision* coll : { &actor->hit().hit, &actor->hit().florhit, &actor->hit().ceilhit}) { - Collision coll = i; - if (coll.type == kHitSprite) + if (coll->type == kHitSprite) { - actor2 = coll.actor; + actor2 = coll->actor; break; } } @@ -4625,18 +4624,19 @@ void actAirDrag(DBloodActor* actor, int a2) // //--------------------------------------------------------------------------- -int MoveThing(DBloodActor* actor) +static Collision MoveThing(DBloodActor* actor) { auto pSprite = &actor->s(); assert(actor->hasX()); XSPRITE* pXSprite = &actor->x(); - int lhit = 0; assert(pSprite->type >= kThingBase && pSprite->type < kThingMax); const THINGINFO* pThingInfo = &thingInfo[pSprite->type - kThingBase]; int nSector = pSprite->sectnum; assert(nSector >= 0 && nSector < kMaxSectors); int top, bottom; + Collision lhit; + lhit.setNone(); GetActorExtents(actor, &top, &bottom); const int bakCompat = enginecompatibility_mode; if (actor->xvel() || actor->yvel()) @@ -4645,17 +4645,17 @@ int MoveThing(DBloodActor* actor) pSprite->cstat &= ~257; if ((pSprite->owner >= 0) && !cl_bloodvanillaexplosions && !VanillaMode()) enginecompatibility_mode = ENGINECOMPATIBILITY_NONE; // improved clipmove accuracy - lhit = actor->hit().hit = ClipMove(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, actor->xvel() >> 12, actor->yvel() >> 12, pSprite->clipdist << 2, (pSprite->z - top) / 4, (bottom - pSprite->z) / 4, CLIPMASK0); + lhit = actor->hit().hit = ClipMove(&pSprite->pos, &nSector, actor->xvel() >> 12, actor->yvel() >> 12, pSprite->clipdist << 2, (pSprite->z - top) / 4, (bottom - pSprite->z) / 4, CLIPMASK0); enginecompatibility_mode = bakCompat; // restore pSprite->cstat = bakCstat; assert(nSector >= 0); if (pSprite->sectnum != nSector) { assert(nSector >= 0 && nSector < kMaxSectors); - ChangeSpriteSect(pSprite->index, nSector); + ChangeActorSect(actor, nSector); } - Collision coll(actor->hit().hit); + Collision &coll = actor->hit().hit; if (coll.type == kHitWall) { int nHitWall = coll.index; @@ -4681,8 +4681,9 @@ int MoveThing(DBloodActor* actor) pSprite->z += actor->zvel() >> 8; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0); GetActorExtents(actor, &top, &bottom); if ((pSprite->flags & 2) && bottom < floorZ) @@ -4709,13 +4710,13 @@ int MoveThing(DBloodActor* actor) } } } - if (CheckLink(pSprite)) GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0); + if (CheckLink(pSprite)) GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0); GetActorExtents(actor, &top, &bottom); if (bottom >= floorZ) { actTouchFloor(actor, pSprite->sectnum); - actor->hit().florhit = floorHit; + actor->hit().florhit = floorColl; pSprite->z += floorZ - bottom; int v20 = actor->zvel() - velFloor[pSprite->sectnum]; @@ -4770,7 +4771,7 @@ int MoveThing(DBloodActor* actor) if (top <= ceilZ) { - actor->hit().ceilhit = ceilHit; + actor->hit().ceilhit = ceilColl; pSprite->z += ClipLow(ceilZ - top, 0); if (actor->zvel() < 0) { @@ -4801,7 +4802,7 @@ int MoveThing(DBloodActor* actor) { int nVel = approxDist(actor->xvel(), actor->yvel()); int nVelClipped = ClipHigh(nVel, 0x11111); - Collision coll(floorHit); + Collision& coll = floorColl; if (coll.type == kHitSprite) { @@ -4868,7 +4869,7 @@ void MoveDude(DBloodActor* actor) { short bakCstat = pSprite->cstat; pSprite->cstat &= ~257; - actor->hit().hit = ClipMove(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, actor->xvel() >> 12, actor->yvel() >> 12, wd, tz, bz, CLIPMASK0); + actor->hit().hit = ClipMove(&pSprite->pos, &nSector, actor->xvel() >> 12, actor->yvel() >> 12, wd, tz, bz, CLIPMASK0); if (nSector == -1) { nSector = pSprite->sectnum; @@ -4878,8 +4879,8 @@ void MoveDude(DBloodActor* actor) if (sector[nSector].type >= kSectorPath && sector[nSector].type <= kSectorRotate) { - short nSector2 = nSector; - if (pushmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector2, wd, tz, bz, CLIPMASK0) == -1) + int nSector2 = nSector; + if (pushmove(&pSprite->pos, &nSector2, wd, tz, bz, CLIPMASK0) == -1) actDamageSprite(actor, actor, kDamageFall, 1000 << 4); if (nSector2 != -1) nSector = nSector2; @@ -4887,8 +4888,8 @@ void MoveDude(DBloodActor* actor) assert(nSector >= 0); pSprite->cstat = bakCstat; } - Collision coll = actor->hit().hit; - switch (actor->hit().hit & 0xc000) + const Collision& coll = actor->hit().hit; + switch (coll.type) { case kHitSprite: { @@ -4963,7 +4964,7 @@ void MoveDude(DBloodActor* actor) pXSector = nullptr; if (pXSector && pXSector->Exit && (pPlayer || !pXSector->dudeLockout)) trTriggerSector(pSprite->sectnum, pXSector, kCmdSectorExit); - ChangeSpriteSect(pSprite->index, nSector); + ChangeActorSect(actor, nSector); nXSector = sector[nSector].extra; pXSector = (nXSector > 0) ? &xsector[nXSector] : nullptr; @@ -4991,8 +4992,9 @@ void MoveDude(DBloodActor* actor) if (pPlayer) wd += 16; if (actor->zvel()) pSprite->z += actor->zvel() >> 8; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); GetActorExtents(actor, &top, &bottom); if (pSprite->flags & 2) @@ -5041,7 +5043,7 @@ void MoveDude(DBloodActor* actor) int nLink = CheckLink(pSprite); if (nLink) { - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, wd, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); if (pPlayer) playerCorrectInertia(pPlayer, &oldpos); switch (nLink) @@ -5204,17 +5206,17 @@ void MoveDude(DBloodActor* actor) if (pPlayer && bottom >= floorZ) { int floorZ2 = floorZ; - int floorHit2 = floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + auto floorColl2 = floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); if (bottom <= floorZ && pSprite->z - floorZ2 < bz) { floorZ = floorZ2; - floorHit = floorHit2; + floorColl = floorColl2; } } if (floorZ <= bottom) { - actor->hit().florhit = floorHit; + actor->hit().florhit = floorColl; pSprite->z += floorZ - bottom; int v30 = actor->zvel() - velFloor[pSprite->sectnum]; if (v30 > 0) @@ -5237,13 +5239,12 @@ void MoveDude(DBloodActor* actor) if (abs(actor->zvel()) < 0x10000) { actor->zvel() = velFloor[pSprite->sectnum]; - pSprite->flags &= ~4; } else - pSprite->flags |= 4; - switch (tileGetSurfType(floorHit)) + + switch (tileGetSurfType(floorColl)) { case kSurfWater: gFX.fxSpawnActor(FX_9, pSprite->sectnum, pSprite->x, pSprite->y, floorZ, 0); @@ -5282,7 +5283,7 @@ void MoveDude(DBloodActor* actor) } if (top <= ceilZ) { - actor->hit().ceilhit = ceilHit; + actor->hit().ceilhit = ceilColl; pSprite->z += ClipLow(ceilZ - top, 0); if (actor->zvel() <= 0 && (pSprite->flags & 4)) @@ -5296,10 +5297,9 @@ void MoveDude(DBloodActor* actor) pXSprite->height = ClipLow(floorZ - bottom, 0) >> 8; if (actor->xvel() || actor->yvel()) { - Collision coll = floorHit; - if (coll.type == kHitSprite) + if (floorColl.type == kHitSprite) { - auto hitAct = coll.actor; + auto hitAct = floorColl.actor; if ((hitAct->s().cstat & 0x30) == 0) { actor->xvel() += MulScale(4, pSprite->x - hitAct->s().x, 2); @@ -5379,22 +5379,18 @@ int MoveMissile(DBloodActor* actor) const bool isFlameSprite = (pSprite->type == kMissileFlameSpray || pSprite->type == kMissileFlameHound); // do not use accurate clipmove for flame based sprites (changes damage too much) while (1) { - int x = pSprite->x; - int y = pSprite->y; - int z = pSprite->z; + vec3_t pos = pSprite->pos; int nSector2 = pSprite->sectnum; - clipmoveboxtracenum = 1; const short bakSpriteCstat = pSprite->cstat; if (pOwner && !isFlameSprite && !cl_bloodvanillaexplosions && !VanillaMode()) { enginecompatibility_mode = ENGINECOMPATIBILITY_NONE; // improved clipmove accuracy pSprite->cstat &= ~257; // remove self collisions for accurate clipmove } - Collision clipmoveresult = ClipMove(&x, &y, &z, &nSector2, vx, vy, pSprite->clipdist << 2, (z - top) / 4, (bottom - z) / 4, CLIPMASK0); + Collision clipmoveresult = ClipMove(&pos, &nSector2, vx, vy, pSprite->clipdist << 2, (pos.z - top) / 4, (bottom - pos.z) / 4, CLIPMASK0, 1); enginecompatibility_mode = bakCompat; // restore pSprite->cstat = bakSpriteCstat; - clipmoveboxtracenum = 3; - short nSector = nSector2; + int nSector = nSector2; if (nSector2 < 0) { cliptype = -1; @@ -5412,8 +5408,8 @@ int MoveMissile(DBloodActor* actor) else { int32_t fz, cz; - getzsofslope(wall[clipmoveresult.index].nextsector, x, y, &cz, &fz); - if (z <= cz || z >= fz) cliptype = 0; + getzsofslope(wall[clipmoveresult.index].nextsector, pos.x, pos.y, &cz, &fz); + if (pos.z <= cz || pos.z >= fz) cliptype = 0; else cliptype = 4; } } @@ -5440,38 +5436,38 @@ int MoveMissile(DBloodActor* actor) if (cliptype >= 0 && cliptype != 3) { int nAngle = getangle(actor->xvel(), actor->yvel()); - x -= MulScale(Cos(nAngle), 16, 30); - y -= MulScale(Sin(nAngle), 16, 30); + pos.x -= MulScale(Cos(nAngle), 16, 30); + pos.y -= MulScale(Sin(nAngle), 16, 30); int nVel = approxDist(actor->xvel(), actor->yvel()); vz -= scale(0x100, actor->zvel(), nVel); - updatesector(x, y, &nSector); + updatesector(pos.x, pos.y, &nSector); nSector2 = nSector; } - int ceilZ, ceilHit, floorZ, floorHit; - GetZRangeAtXYZ(x, y, z, nSector2, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist << 2, CLIPMASK0); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRangeAtXYZ(pos.x, pos.y, pos.z, nSector2, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0); GetActorExtents(actor, &top, &bottom); top += vz; bottom += vz; if (bottom >= floorZ) { - actor->hit().florhit = floorHit; + actor->hit().florhit = floorColl; vz += floorZ - bottom; cliptype = 2; } if (top <= ceilZ) { - actor->hit().ceilhit = ceilHit; + actor->hit().ceilhit = ceilColl; vz += ClipLow(ceilZ - top, 0); cliptype = 1; } - pSprite->x = x; - pSprite->y = y; - pSprite->z = z + vz; - updatesector(x, y, &nSector); + pSprite->pos = pos; + pSprite->z += vz; + updatesector(pos.x, pos.y, &nSector); if (nSector >= 0 && nSector != pSprite->sectnum) { assert(nSector >= 0 && nSector < kMaxSectors); - ChangeSpriteSect(pSprite->index, nSector); + ChangeActorSect(actor, nSector); } CheckLink(pSprite); gHitInfo.hitsect = pSprite->sectnum; @@ -5532,7 +5528,7 @@ void actExplodeSprite(DBloodActor* actor) case kThingArmedTNTStick: nType = kExplosionSmall; - if (actor->hit().florhit == 0) seqSpawn(4, actor, -1); + if (actor->hit().florhit.type == kHitNone) seqSpawn(4, actor, -1); else seqSpawn(3, actor, -1); sfxPlay3DSound(actor, 303, -1, 0); GibSprite(pSprite, GIBTYPE_5, nullptr, nullptr); @@ -5545,7 +5541,7 @@ void actExplodeSprite(DBloodActor* actor) case kModernThingTNTProx: #endif nType = kExplosionStandard; - if (actor->hit().florhit == 0) seqSpawn(4, actor, -1); + if (actor->hit().florhit.type == kHitNone) seqSpawn(4, actor, -1); else seqSpawn(3, actor, -1); sfxPlay3DSound(actor, 304, -1, 0); @@ -6050,7 +6046,7 @@ static void actCheckExplosion() if (pDebris->sectnum < 0 || (pDebris->flags & kHitagFree) != 0) continue; if (!TestBitString(sectormap, pDebris->sectnum) || !CheckProximity(pDebris, x, y, z, nSector, radius)) continue; - else debrisConcuss(Owner ? Owner->s().index : -1, i, x, y, z, pExplodeInfo->dmgType); + else debrisConcuss(Owner, i, x, y, z, pExplodeInfo->dmgType); } } @@ -6133,8 +6129,8 @@ static void actCheckTraps() x += (dx / 2) >> 12; y += (dy / 2) >> 12; } - dy = SinScale16(pSprite->ang); - dx = CosScale16(pSprite->ang); + dy = bsin(pSprite->ang); + dx = bcos(pSprite->ang); gVectorData[kVectorTchernobogBurn].maxDist = pXSprite->data1 << 9; actFireVector(actor, 0, 0, dx, dy, Random2(0x8888), kVectorTchernobogBurn); } @@ -6401,7 +6397,7 @@ DBloodActor* actSpawnSprite(int nSector, int x, int y, int z, int nStat, bool se pSprite->type = kSpriteDecoration; if (setextra && !actor->hasX()) { - actor->addExtra(); + actor->addX(); actor->hit().florhit = 0; actor->hit().ceilhit = 0; if (!VanillaMode()) actor->SetTarget(nullptr); @@ -7051,7 +7047,7 @@ void actFireVector(DBloodActor* shooter, int a2, int a3, int a4, int a5, int a6, { case kDudeModernCustom: case kDudeModernCustomBurning: - t = getSpriteMassBySize(pSprite); + t = getSpriteMassBySize(actor); break; } } @@ -7374,20 +7370,52 @@ void MakeSplash(DBloodActor* actor) // //--------------------------------------------------------------------------- -FSerializer& Serialize(FSerializer& arc, const char* keyname, SPRITEHIT& w, SPRITEHIT* def) +FSerializer& Serialize(FSerializer& arc, const char* keyname, Collision& w, Collision* def) { int empty = 0; if (arc.isReading()) w = {}; if (arc.BeginObject(keyname)) { - arc("hit", w.hit, &empty) - ("ceilhit", w.ceilhit, &empty) - ("florhit", w.florhit, &empty) + arc("type", w.type, &empty) + ("index", w.index, &empty) + ("legacyval", w.legacyVal, &empty) + ("actor", w.actor) .EndObject(); } return arc; } +FSerializer& Serialize(FSerializer& arc, const char* keyname, SPRITEHIT& w, SPRITEHIT* def) +{ +#ifdef OLD_SAVEGAME + int empty = 0; + int hit = w.hit.legacyVal, ceilhit = w.ceilhit.legacyVal, florhit = w.florhit.legacyVal; + if (arc.isReading()) w = {}; + if (arc.BeginObject(keyname)) + { + arc("hit", hit, &empty) + ("ceilhit", ceilhit, &empty) + ("florhit", florhit, &empty) + .EndObject(); + if (arc.isReading()) + { + w.hit.setFromEngine(hit); + w.florhit.setFromEngine(florhit); + w.ceilhit.setFromEngine(ceilhit); + } + } +#else + if (arc.BeginObject(keyname)) + { + arc("hit", w.hit) + ("ceilhit", w.ceilhit) + ("florhit", w.florhit) + .EndObject(); + } +#endif + return arc; +} + void SerializeActor(FSerializer& arc) { if (arc.BeginObject("actor")) diff --git a/source/games/blood/src/ai.cpp b/source/games/blood/src/ai.cpp index cb21df8e6..f532c5e67 100644 --- a/source/games/blood/src/ai.cpp +++ b/source/games/blood/src/ai.cpp @@ -138,7 +138,7 @@ bool CanMove(DBloodActor* actor, DBloodActor* target, int nAngle, int nRange) int x = pSprite->x; int y = pSprite->y; int z = pSprite->z; - HitScan(pSprite, z, CosScale16(nAngle), SinScale16(nAngle), 0, CLIPMASK0, nRange); + HitScan(pSprite, z, bcos(nAngle), bsin(nAngle), 0, CLIPMASK0, nRange); int nDist = approxDist(x - gHitInfo.hitx, y - gHitInfo.hity); if (nDist - (pSprite->clipdist << 2) < nRange) { @@ -230,7 +230,7 @@ bool CanMove(DBloodActor* actor, DBloodActor* target, int nAngle, int nRange) #ifdef NOONE_EXTENSIONS case kDudeModernCustom: case kDudeModernCustomBurning: - if ((Crusher && !nnExtIsImmune(pSprite, pXSector->damageType)) || ((Water || Underwater) && !canSwim(actor))) return false; + if ((Crusher && !nnExtIsImmune(actor, pXSector->damageType)) || ((Water || Underwater) && !canSwim(actor))) return false; return true; [[fallthrough]]; #endif diff --git a/source/games/blood/src/aibat.cpp b/source/games/blood/src/aibat.cpp index aa450b15c..14dac7606 100644 --- a/source/games/blood/src/aibat.cpp +++ b/source/games/blood/src/aibat.cpp @@ -68,8 +68,8 @@ void batBiteSeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype* pTarget = &actor->GetTarget()->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); DUDEINFO* pDudeInfoT = getDudeInfo(pTarget->type); diff --git a/source/games/blood/src/aibeast.cpp b/source/games/blood/src/aibeast.cpp index 3c09c1dbf..7acb3f64e 100644 --- a/source/games/blood/src/aibeast.cpp +++ b/source/games/blood/src/aibeast.cpp @@ -69,8 +69,8 @@ void SlashSeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype* pTarget = &actor->GetTarget()->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); // Correct ? int dz = pSprite->z - pTarget->z; dx += Random3(4000 - 700 * gGameOptions.nDifficulty); @@ -86,8 +86,8 @@ void StompSeqCallback(int, DBloodActor* actor1) uint8_t sectmap[(kMaxSectors + 7) >> 3]; XSPRITE* pXSprite = &actor1->x(); spritetype* pSprite = &actor1->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int x = pSprite->x; int y = pSprite->y; int z = pSprite->z; diff --git a/source/games/blood/src/aiboneel.cpp b/source/games/blood/src/aiboneel.cpp index a2debbd8b..5605a49e4 100644 --- a/source/games/blood/src/aiboneel.cpp +++ b/source/games/blood/src/aiboneel.cpp @@ -80,8 +80,8 @@ void eelBiteSeqCallback(int, DBloodActor* actor) } spritetype* pTarget = &actor->GetTarget()->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); DUDEINFO* pDudeInfoT = getDudeInfo(pTarget->type); diff --git a/source/games/blood/src/aicaleb.cpp b/source/games/blood/src/aicaleb.cpp index 83a7eed10..79ed74cfb 100644 --- a/source/games/blood/src/aicaleb.cpp +++ b/source/games/blood/src/aicaleb.cpp @@ -61,8 +61,8 @@ AISTATE tinycaleb139698 = { kAiStateOther, 8, -1, 120, NULL, aiMoveTurn, NULL, & void SeqAttackCallback(int, DBloodActor* actor) { spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int dz = actor->dudeSlope; dx += Random2(1500); dy += Random2(1500); diff --git a/source/games/blood/src/aicerber.cpp b/source/games/blood/src/aicerber.cpp index d130f985f..f8e9e6c58 100644 --- a/source/games/blood/src/aicerber.cpp +++ b/source/games/blood/src/aicerber.cpp @@ -60,8 +60,8 @@ void cerberusBiteSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); ///assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax)) { Printf(PRINT_HIGH, "pSprite->type >= kDudeBase && pSprite->type < kDudeMax"); @@ -88,8 +88,8 @@ void cerberusBurnSeqCallback(int, DBloodActor* actor) int z = height; // ??? TARGETTRACK tt1 = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa }; Aim aim; - aim.dx = CosScale16(pSprite->ang); - aim.dy = SinScale16(pSprite->ang); + aim.dx = bcos(pSprite->ang); + aim.dy = bsin(pSprite->ang); aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; BloodStatIterator it(kStatDude); @@ -133,8 +133,8 @@ void cerberusBurnSeqCallback(int, DBloodActor* actor) if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(nAngle); - aim.dy = SinScale16(nAngle); + aim.dx = bcos(nAngle); + aim.dy = bsin(nAngle); aim.dz = DivScale(tz, nDist, 10); } else @@ -167,8 +167,8 @@ void cerberusBurnSeqCallback2(int, DBloodActor* actor) TARGETTRACK tt1 = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa }; Aim aim; int ax, ay, az; - aim.dx = ax = CosScale16(pSprite->ang); - aim.dy = ay = SinScale16(pSprite->ang); + aim.dx = ax = bcos(pSprite->ang); + aim.dy = ay = bsin(pSprite->ang); aim.dz = actor->dudeSlope; az = 0; int nClosest = 0x7fffffff; @@ -215,8 +215,8 @@ void cerberusBurnSeqCallback2(int, DBloodActor* actor) if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(nAngle); - aim.dy = SinScale16(nAngle); + aim.dx = bcos(nAngle); + aim.dy = bsin(nAngle); aim.dz = DivScale(tz, nDist, 10); } else diff --git a/source/games/blood/src/aicult.cpp b/source/games/blood/src/aicult.cpp index ca936925e..b73796cea 100644 --- a/source/games/blood/src/aicult.cpp +++ b/source/games/blood/src/aicult.cpp @@ -77,8 +77,8 @@ void TommySeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int dz = actor->dudeSlope; dx += Random3((5 - gGameOptions.nDifficulty) * 1000); dy += Random3((5 - gGameOptions.nDifficulty) * 1000); @@ -93,8 +93,8 @@ void TeslaSeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); if (Chance(dword_138BB0[gGameOptions.nDifficulty])) { - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int dz = actor->dudeSlope; dx += Random3((5 - gGameOptions.nDifficulty) * 1000); dy += Random3((5 - gGameOptions.nDifficulty) * 1000); @@ -108,8 +108,8 @@ void ShotSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int dz = actor->dudeSlope; dx += Random2((5 - gGameOptions.nDifficulty) * 1000 - 500); dy += Random2((5 - gGameOptions.nDifficulty) * 1000 - 500); diff --git a/source/games/blood/src/aigarg.cpp b/source/games/blood/src/aigarg.cpp index 17719adc7..e9345aadd 100644 --- a/source/games/blood/src/aigarg.cpp +++ b/source/games/blood/src/aigarg.cpp @@ -88,8 +88,8 @@ void SlashFSeqCallback(int, DBloodActor* actor) int height = (pSprite->yrepeat * pDudeInfo->eyeHeight) << 2; int height2 = (pTarget->yrepeat * pDudeInfoT->eyeHeight) << 2; int dz = height - height2; - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); actFireVector(actor, 0, 0, dx, dy, dz, kVectorGargSlash); int r1 = Random(50); int r2 = Random(50); @@ -121,8 +121,8 @@ void BlastSSeqCallback(int, DBloodActor* actor) int z = height; TARGETTRACK tt = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa }; Aim aim; - aim.dx = CosScale16(pSprite->ang); - aim.dy = SinScale16(pSprite->ang); + aim.dx = bcos(pSprite->ang); + aim.dy = bsin(pSprite->ang); aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; BloodStatIterator it(kStatDude); @@ -166,8 +166,8 @@ void BlastSSeqCallback(int, DBloodActor* actor) if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(nAngle); - aim.dy = SinScale16(nAngle); + aim.dx = bcos(nAngle); + aim.dy = bsin(nAngle); aim.dz = DivScale(tz, nDist, 10); if (tz > -0x333) aim.dz = DivScale(tz, nDist, 10); diff --git a/source/games/blood/src/aighost.cpp b/source/games/blood/src/aighost.cpp index 65ba703da..fbb97d5fd 100644 --- a/source/games/blood/src/aighost.cpp +++ b/source/games/blood/src/aighost.cpp @@ -72,8 +72,8 @@ void ghostSlashSeqCallback(int, DBloodActor* actor) int height = (pSprite->yrepeat * pDudeInfo->eyeHeight) << 2; int height2 = (pTarget->yrepeat * pDudeInfoT->eyeHeight) << 2; int dz = height - height2; - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); sfxPlay3DSound(actor, 1406, 0, 0); actFireVector(actor, 0, 0, dx, dy, dz, kVectorGhost); int r1 = Random(50); @@ -104,8 +104,8 @@ void ghostBlastSeqCallback(int, DBloodActor* actor) int z = height; TARGETTRACK tt = { 0x10000, 0x10000, 0x100, 0x55, 0x1aaaaa }; Aim aim; - aim.dx = CosScale16(pSprite->ang); - aim.dy = SinScale16(pSprite->ang); + aim.dx = bcos(pSprite->ang); + aim.dy = bsin(pSprite->ang); aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; BloodStatIterator it(kStatDude); @@ -149,8 +149,8 @@ void ghostBlastSeqCallback(int, DBloodActor* actor) if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(nAngle); - aim.dy = SinScale16(nAngle); + aim.dx = bcos(nAngle); + aim.dy = bsin(nAngle); aim.dz = DivScale(tz, nDist, 10); if (tz > -0x333) aim.dz = DivScale(tz, nDist, 10); diff --git a/source/games/blood/src/aigilbst.cpp b/source/games/blood/src/aigilbst.cpp index f3e54c4a1..fdffad182 100644 --- a/source/games/blood/src/aigilbst.cpp +++ b/source/games/blood/src/aigilbst.cpp @@ -64,8 +64,8 @@ void GillBiteSeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype* pTarget = &actor->GetTarget()->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int dz = pSprite->z - pTarget->z; dx += Random3(2000); dy += Random3(2000); diff --git a/source/games/blood/src/aihound.cpp b/source/games/blood/src/aihound.cpp index 3d78a2b86..a1e4fa351 100644 --- a/source/games/blood/src/aihound.cpp +++ b/source/games/blood/src/aihound.cpp @@ -47,8 +47,8 @@ void houndBiteSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); ///assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax)) { Printf(PRINT_HIGH, "pSprite->type >= kDudeBase && pSprite->type < kDudeMax"); @@ -69,7 +69,7 @@ void houndBiteSeqCallback(int, DBloodActor* actor) void houndBurnSeqCallback(int, DBloodActor* actor) { spritetype* pSprite = &actor->s(); - actFireMissile(actor, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), 0, kMissileFlameHound); + actFireMissile(actor, 0, 0, bcos(pSprite->ang), bsin(pSprite->ang), 0, kMissileFlameHound); } static void houndThinkSearch(DBloodActor* actor) diff --git a/source/games/blood/src/airat.cpp b/source/games/blood/src/airat.cpp index 3e3bc72e1..bff2dd4a5 100644 --- a/source/games/blood/src/airat.cpp +++ b/source/games/blood/src/airat.cpp @@ -46,8 +46,8 @@ void ratBiteSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype* pTarget = &actor->GetTarget()->s(); diff --git a/source/games/blood/src/aispid.cpp b/source/games/blood/src/aispid.cpp index f7416c408..8e3d7fd9a 100644 --- a/source/games/blood/src/aispid.cpp +++ b/source/games/blood/src/aispid.cpp @@ -65,8 +65,8 @@ void SpidBiteSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); dx += Random2(2000); dy += Random2(2000); int dz = Random2(2000); @@ -117,8 +117,8 @@ void SpidJumpSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); dx += Random2(200); dy += Random2(200); int dz = Random2(200); diff --git a/source/games/blood/src/aitchern.cpp b/source/games/blood/src/aitchern.cpp index 8bd0f30e9..aaa2b40a2 100644 --- a/source/games/blood/src/aitchern.cpp +++ b/source/games/blood/src/aitchern.cpp @@ -74,8 +74,8 @@ void sub_71BD4(int, DBloodActor* actor) int z = height; TARGETTRACK tt = { 0x10000, 0x10000, 0x100, 0x55, 0x100000 }; Aim aim; - aim.dx = CosScale16(pSprite->ang); - aim.dy = SinScale16(pSprite->ang); + aim.dx = bcos(pSprite->ang); + aim.dy = bsin(pSprite->ang); aim.dz = actor->dudeSlope; int nClosest = 0x7fffffff; BloodStatIterator it(kStatDude); @@ -119,8 +119,8 @@ void sub_71BD4(int, DBloodActor* actor) if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(nAngle); - aim.dy = SinScale16(nAngle); + aim.dx = bcos(nAngle); + aim.dy = bsin(nAngle); aim.dz = DivScale(tz, nDist, 10); } else @@ -141,8 +141,8 @@ void sub_720AC(int, DBloodActor* actor) DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); int height = pSprite->yrepeat * pDudeInfo->eyeHeight; int ax, ay, az; - ax = CosScale16(pSprite->ang); - ay = SinScale16(pSprite->ang); + ax = bcos(pSprite->ang); + ay = bsin(pSprite->ang); int x = pSprite->x; int y = pSprite->y; int z = height; @@ -194,8 +194,8 @@ void sub_720AC(int, DBloodActor* actor) if (cansee(x, y, z, pSprite->sectnum, x2, y2, z2, pSprite2->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(nAngle); - aim.dy = SinScale16(nAngle); + aim.dx = bcos(nAngle); + aim.dy = bsin(nAngle); aim.dz = DivScale(tz, nDist, 10); } else diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index df85c17fd..522ca141d 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -151,7 +151,7 @@ static bool genDudeAdjustSlope(DBloodActor* actor, int dist, int weaponType, int for (int i = -8191; i < 8192; i += by) { - HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), i, clipMask, dist); + HitScan(pSprite, pSprite->z, bcos(pSprite->ang), bsin(pSprite->ang), i, clipMask, dist); if (!fStart && actor->GetTarget() == gHitInfo.hitactor) fStart = i; else if (fStart && actor->GetTarget() != gHitInfo.hitactor) { @@ -213,8 +213,8 @@ void punchCallback(int, DBloodActor* actor) if(target->IsDudeActor()) nZOffset2 = getDudeInfo(pTarget->type)->eyeHeight * pTarget->yrepeat << 2; - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int dz = nZOffset1 - nZOffset2; if (!playGenDudeSound(actor, kGenDudeSndAttackMelee)) @@ -247,7 +247,7 @@ void genDudeAttack1(int, DBloodActor* actor) if (pExtra->weaponType == kGenDudeWeaponHitscan) { - dx = CosScale16(pSprite->ang); dy = SinScale16(pSprite->ang); dz = actor->dudeSlope; + dx = bcos(pSprite->ang); dy = bsin(pSprite->ang); dz = actor->dudeSlope; // dispersal modifiers here in case if non-melee enemy if (!dudeIsMelee(actor)) { @@ -256,7 +256,7 @@ void genDudeAttack1(int, DBloodActor* actor) actFireVector(actor, 0, 0, dx, dy, dz,(VECTOR_TYPE)pExtra->curWeapon); if (!playGenDudeSound(actor, kGenDudeSndAttackNormal)) - sfxPlayVectorSound(pSprite, pExtra->curWeapon); + sfxPlayVectorSound(actor, pExtra->curWeapon); } else if (pExtra->weaponType == kGenDudeWeaponSummon) { @@ -285,14 +285,14 @@ void genDudeAttack1(int, DBloodActor* actor) } else if (pExtra->weaponType == kGenDudeWeaponMissile) { - dx = CosScale16(pSprite->ang); dy = SinScale16(pSprite->ang); dz = actor->dudeSlope; + dx = bcos(pSprite->ang); dy = bsin(pSprite->ang); dz = actor->dudeSlope; // dispersal modifiers here dx += Random3(dispersion); dy += Random3(dispersion); dz += Random3(dispersion >> 1); actFireMissile(actor, 0, 0, dx, dy, dz, pExtra->curWeapon); if (!playGenDudeSound(actor, kGenDudeSndAttackNormal)) - sfxPlayMissileSound(pSprite, pExtra->curWeapon); + sfxPlayMissileSound(actor, pExtra->curWeapon); } } @@ -778,9 +778,9 @@ static void unicultThinkChase(DBloodActor* actor) { int objDist = -1; int targetDist = -1; int hit = -1; if (weaponType == kGenDudeWeaponHitscan) - hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, CLIPMASK1, dist); + hit = HitScan(pSprite, pSprite->z, bcos(pSprite->ang), bsin(pSprite->ang), actor->dudeSlope, CLIPMASK1, dist); else if (weaponType == kGenDudeWeaponMissile) - hit = HitScan(pSprite, pSprite->z, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, CLIPMASK0, dist); + hit = HitScan(pSprite, pSprite->z, bcos(pSprite->ang), bsin(pSprite->ang), actor->dudeSlope, CLIPMASK0, dist); if (hit >= 0) { @@ -902,10 +902,10 @@ static void unicultThinkChase(DBloodActor* actor) else if (weaponType == kGenDudeWeaponHitscan && hscn) { if (genDudeAdjustSlope(actor, dist, weaponType)) break; - VectorScan(pSprite, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, dist, 1); + VectorScan(pSprite, 0, 0, bcos(pSprite->ang), bsin(pSprite->ang), actor->dudeSlope, dist, 1); if (actor == gHitInfo.hitactor) break; - bool immune = nnExtIsImmune(pHSprite, gVectorData[curWeapon].dmgType); + bool immune = nnExtIsImmune(hitactor, gVectorData[curWeapon].dmgType); if (!(pXHSprite != NULL && (!immune || (immune && pHSprite->statnum == kStatThing && pXHSprite->Vector)) && !pXHSprite->locked)) { if ((approxDist(gHitInfo.hitx - pSprite->x, gHitInfo.hity - pSprite->y) <= 1500 && !blck) @@ -938,7 +938,7 @@ static void unicultThinkChase(DBloodActor* actor) else pXSprite->dodgeDir = -1; } - if (((gSpriteHit[pSprite->extra].hit & 0xc000) == 0x8000) || ((gSpriteHit[pSprite->extra].hit & 0xc000) == 0xc000)) + if (actor->hit().hit.type == kHitWall || actor->hit().hit.type == kHitSprite) { if (spriteIsUnderwater(actor)) aiGenDudeNewState(actor, &genDudeChaseW); else aiGenDudeNewState(actor, &genDudeChaseL); @@ -962,7 +962,7 @@ static void unicultThinkChase(DBloodActor* actor) if (hit == 4 && weaponType == kGenDudeWeaponHitscan && hscn) { bool masked = (pHWall->cstat & CSTAT_WALL_MASKED); - if (masked) VectorScan(pSprite, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), actor->dudeSlope, dist, 1); + if (masked) VectorScan(pSprite, 0, 0, bcos(pSprite->ang), bsin(pSprite->ang), actor->dudeSlope, dist, 1); //viewSetSystemMessage("WALL VHIT: %d", gHitInfo.hitwall); if ((actor != gHitInfo.hitactor) && (pHWall->type != kWallGib || !masked || pXHWall == NULL || !pXHWall->triggerVector || pXHWall->locked)) @@ -1008,7 +1008,7 @@ static void unicultThinkChase(DBloodActor* actor) // check also for damage resistance (all possible damages missile can use) for (int i = 0; i < kDmgMax; i++) { - if (gMissileInfoExtra[curWeapon - kMissileBase].dmgType[i] && (failed = nnExtIsImmune(pHSprite, i)) == false) + if (gMissileInfoExtra[curWeapon - kMissileBase].dmgType[i] && (failed = nnExtIsImmune(hitactor, i)) == false) break; } } @@ -1643,7 +1643,7 @@ static void scaleDamage(DBloodActor* actor) } // take in account yrepeat of sprite - short yrepeat = sprite[pXSprite->reference].yrepeat; + short yrepeat = actor->s().yrepeat; if (yrepeat < 64) { for (int i = 0; i < kDmgMax; i++) curScale[i] += (64 - yrepeat); @@ -1654,7 +1654,7 @@ static void scaleDamage(DBloodActor* actor) } // take surface type into account - int surfType = tileGetSurfType(sprite[pXSprite->reference].index + 0xc000); + int surfType = tileGetSurfType(actor->s().picnum); switch (surfType) { case 1: // stone @@ -1809,9 +1809,8 @@ int getBaseChanceModifier(int baseChance) int getRecoilChance(DBloodActor* actor) { - auto const pSprite = &actor->s(); auto const pXSprite = &actor->x(); - int mass = getSpriteMassBySize(pSprite); + int mass = getSpriteMassBySize(actor); int baseChance = (!dudeIsMelee(actor) ? 0x8000 : 0x4000); baseChance = getBaseChanceModifier(baseChance) + pXSprite->data3; @@ -1821,9 +1820,8 @@ int getRecoilChance(DBloodActor* actor) int getDodgeChance(DBloodActor* actor) { - auto const pSprite = &actor->s(); auto const pXSprite = &actor->x(); - int mass = getSpriteMassBySize(pSprite); + int mass = getSpriteMassBySize(actor); int baseChance = (!dudeIsMelee(actor) ? 0x6000 : 0x1000); baseChance = getBaseChanceModifier(baseChance) + pXSprite->data3; @@ -1874,8 +1872,8 @@ void dudeLeechOperate(DBloodActor* actor, const EVENT& event) y += (actTarget->yvel() * t) >> 12; int angBak = pSprite->ang; pSprite->ang = getangle(x - pSprite->x, y - pSprite->y); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int tz = pTarget->z - (pTarget->yrepeat * pDudeInfo->aimHeight) * 4; int dz = DivScale(tz - top - 256, nDist, 10); int nMissileType = kMissileLifeLeechAltNormal + (pXSprite->data3 ? 1 : 0); @@ -2058,7 +2056,7 @@ void genDudeTransform(DBloodActor* actor) if (actIncarnation == NULL) { if (pXSprite->sysData1 == kGenDudeTransformStatus) pXSprite->sysData1 = 0; - trTriggerSprite(pSprite->index, pXSprite, kCmdOff); + trTriggerSprite(actor, kCmdOff); return; } @@ -2075,7 +2073,7 @@ void genDudeTransform(DBloodActor* actor) pXIncarnation->triggerOff = false; // trigger dude death before transform - trTriggerSprite(pSprite->index, pXSprite, kCmdOff); + trTriggerSprite(actor, kCmdOff); pSprite->type = pSprite->inittype = pIncarnation->type; pSprite->flags = pIncarnation->flags; @@ -2417,7 +2415,7 @@ bool genDudePrepare(DBloodActor* actor, int propId) SPRITEMASS* pMass = &actor->spriteMass; pMass->seqId = pMass->picnum = pMass->xrepeat = pMass->yrepeat = pMass->clipdist = 0; pMass->mass = pMass->airVel = pMass->fraction = 0; - getSpriteMassBySize(pSprite); + getSpriteMassBySize(actor); if (propId) break; [[fallthrough]]; } diff --git a/source/games/blood/src/aizomba.cpp b/source/games/blood/src/aizomba.cpp index 84bc81042..442b930ac 100644 --- a/source/games/blood/src/aizomba.cpp +++ b/source/games/blood/src/aizomba.cpp @@ -73,8 +73,8 @@ void HackSeqCallback(int, DBloodActor* actor) int height = (pSprite->yrepeat * pDudeInfo->eyeHeight) << 2; int height2 = (pTarget->yrepeat * pDudeInfoT->eyeHeight) << 2; int dz = height - height2; - int dx = CosScale16(nAngle); - int dy = SinScale16(nAngle); + int dx = bcos(nAngle); + int dy = bsin(nAngle); sfxPlay3DSound(pSprite, 1101, 1, 0); actFireVector(actor, 0, 0, dx, dy, dz, kVectorAxe); } diff --git a/source/games/blood/src/aizombf.cpp b/source/games/blood/src/aizombf.cpp index 2dcf412d8..4b4465939 100644 --- a/source/games/blood/src/aizombf.cpp +++ b/source/games/blood/src/aizombf.cpp @@ -58,7 +58,7 @@ void zombfHackSeqCallback(int, DBloodActor* actor) int height = (pDudeInfo->eyeHeight * pSprite->yrepeat); DUDEINFO* pDudeInfoT = getDudeInfo(pTarget->type); int height2 = (pDudeInfoT->eyeHeight * pTarget->yrepeat); - actFireVector(actor, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), height - height2, kVectorCleaver); + actFireVector(actor, 0, 0, bcos(pSprite->ang), bsin(pSprite->ang), height - height2, kVectorCleaver); } void PukeSeqCallback(int, DBloodActor* actor) @@ -74,8 +74,8 @@ void PukeSeqCallback(int, DBloodActor* actor) int tx = pXSprite->targetX - pSprite->x; int ty = pXSprite->targetY - pSprite->y; int nAngle = getangle(tx, ty); - int dx = CosScale16(nAngle); - int dy = SinScale16(nAngle); + int dx = bcos(nAngle); + int dy = bsin(nAngle); sfxPlay3DSound(pSprite, 1203, 1, 0); actFireMissile(actor, 0, -(height - height2), dx, dy, 0, kMissilePukeGreen); } @@ -83,7 +83,7 @@ void PukeSeqCallback(int, DBloodActor* actor) void ThrowSeqCallback(int, DBloodActor* actor) { spritetype* pSprite = &actor->s(); - actFireMissile(actor, 0, -getDudeInfo(pSprite->type)->eyeHeight, CosScale16(pSprite->ang), SinScale16(pSprite->ang), 0, kMissileButcherKnife); + actFireMissile(actor, 0, -getDudeInfo(pSprite->type)->eyeHeight, bcos(pSprite->ang), bsin(pSprite->ang), 0, kMissileButcherKnife); } static void zombfThinkSearch(DBloodActor* actor) diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 812376d9e..7eb1d64e5 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -601,7 +601,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int { if (nXSprite > 0) { - if (gSpriteHit[nXSprite].florhit == 0) + if (gSpriteHit[nXSprite].florhit.type == kHitNone) nAnim = 1; } else @@ -927,7 +927,8 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int case kStatThing: { viewApplyDefaultPal(pTSprite, pSector); - if (pTSprite->type < kThingBase || pTSprite->type >= kThingMax || !gSpriteHit[nXSprite].florhit) { + if (pTSprite->type < kThingBase || pTSprite->type >= kThingMax || gSpriteHit[nXSprite].florhit.type == kHitNone) + { if ((pTSprite->flags & kPhysMove) && getflorzofslope(pTSprite->sectnum, pTSprite->x, pTSprite->y) >= cZ) viewAddEffect(tsprite, spritesortcnt, nTSprite, kViewEffectShadow); } diff --git a/source/games/blood/src/blood.cpp b/source/games/blood/src/blood.cpp index e2f25c308..1ec375334 100644 --- a/source/games/blood/src/blood.cpp +++ b/source/games/blood/src/blood.cpp @@ -123,10 +123,12 @@ void StartLevel(MapRecord* level, bool newgame) int modernTypesErased = 0; for (int i = 0; i < kMaxSprites; i++) { - spritetype* pSprite = &sprite[i]; - if (pSprite->statnum < kMaxStatus && pSprite->extra > 0) { + DBloodActor* actor = &bloodActors[i]; + spritetype* pSprite = &actor->s(); + if (pSprite->statnum < kMaxStatus && actor->hasX()) + { - XSPRITE* pXSprite = &xsprite[pSprite->extra]; + XSPRITE* pXSprite = &actor->x(); if ((pXSprite->lSkill & (1 << gGameOptions.nDifficulty)) || (pXSprite->lS && gGameOptions.nGameType == 0) || (pXSprite->lB && gGameOptions.nGameType == 2) || (pXSprite->lT && gGameOptions.nGameType == 3) || (pXSprite->lC && gGameOptions.nGameType == 1)) { @@ -137,7 +139,7 @@ void StartLevel(MapRecord* level, bool newgame) #ifdef NOONE_EXTENSIONS - if (!gModernMap && nnExtEraseModernStuff(pSprite, pXSprite)) + if (!gModernMap && nnExtEraseModernStuff(actor)) modernTypesErased++; #endif } @@ -435,8 +437,6 @@ void GameInterface::app_init() SetTileNames(); C_InitConback(TexMan.CheckForTexture("BACKTILE", ETextureType::Any), true, 0.25); - Printf(PRINT_NONOTIFY, "Loading cosine table\n"); - trigInit(); Printf(PRINT_NONOTIFY, "Initializing view subsystem\n"); viewInit(); Printf(PRINT_NONOTIFY, "Initializing dynamic fire\n"); diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index c6e5fbfca..1cc47b8fa 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -2,6 +2,87 @@ BEGIN_BLD_NS +class DBloodActor; + +// Wrapper around the insane collision info mess from Build. +struct Collision +{ + int type; + int index; + int legacyVal; // should be removed later, but needed for converting back for unadjusted code. + DBloodActor* actor; + + Collision() = default; + Collision(int legacyval) { setFromEngine(legacyval); } + + // need forward declarations of these. + int actorIndex(DBloodActor*); + DBloodActor* Actor(int); + + int setNone() + { + type = kHitNone; + index = -1; + legacyVal = 0; + actor = nullptr; + return kHitNone; + } + + int setSector(int num) + { + type = kHitSector; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitSector; + } + int setWall(int num) + { + type = kHitWall; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitWall; + } + int setSprite(DBloodActor* num) + { + type = kHitSprite; + index = -1; + legacyVal = type | actorIndex(num); + actor = num; + return kHitSprite; + } + + int setFromEngine(int value) + { + legacyVal = value; + type = value & kHitTypeMask; + if (type == 0) { index = -1; actor = nullptr; } + else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; } + else { index = -1; actor = Actor(value & kHitIndexMask); } + return type; + } + + walltype* wall() + { + assert(type == kHitWall); + return &::wall[index]; + } + + sectortype* sector() + { + assert(type == kHitSector); + return &::sector[index]; + } + +}; + +struct SPRITEHIT +{ + Collision hit, ceilhit, florhit; +}; +extern SPRITEHIT gSpriteHit[kMaxXSprites]; + // Due to the messed up array storage of all the game data we cannot do any direct references here yet. We have to access everything via wrapper functions for now. // Note that the indexing is very inconsistent - partially by sprite index, partially by xsprite index. @@ -137,12 +218,6 @@ public: return true; } } - - void addExtra() - { - if (s().extra <= 0) s().extra = dbInsertXSprite(index); - } - }; extern DBloodActor bloodActors[kMaxSprites]; @@ -224,62 +299,6 @@ inline DBloodActor* PLAYER::actor() } -// Wrapper around the insane collision info mess from Build. -struct Collision -{ - int type; - int index; - int legacyVal; // should be removed later, but needed for converting back for unadjusted code. - DBloodActor* actor; - - Collision() = default; - Collision(int legacyval) { setFromEngine(legacyval); } - - int setNone() - { - type = kHitNone; - index = -1; - legacyVal = 0; - actor = nullptr; - return kHitNone; - } - - int setSector(int num) - { - type = kHitSector; - index = num; - legacyVal = type | index; - actor = nullptr; - return kHitSector; - } - int setWall(int num) - { - type = kHitWall; - index = num; - legacyVal = type | index; - actor = nullptr; - return kHitWall; - } - int setSprite(DBloodActor* num) - { - type = kHitSprite; - index = -1; - legacyVal = type | int(num - bloodActors); - actor = num; - return kHitSprite; - } - - int setFromEngine(int value) - { - legacyVal = value; - type = value & kHitTypeMask; - if (type == 0) { index = -1; actor = nullptr; } - else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; } - else { index = -1; actor = &bloodActors[value & kHitIndexMask]; } - return type; - } -}; - inline DBloodActor* getUpperLink(int sect) { auto l = gUpperLink[sect]; @@ -292,11 +311,6 @@ inline DBloodActor* getLowerLink(int sect) return l == -1 ? nullptr : &bloodActors[l]; } -inline void viewBackupSpriteLoc(DBloodActor* actor) -{ - viewBackupSpriteLoc(actor->s().index, &actor->s()); -} - inline FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor*& w, DBloodActor** def) { int index = w? int(w - bloodActors) : -1; @@ -318,4 +332,24 @@ inline void sfxKill3DSound(DBloodActor* pSprite, int a2 = -1, int a3 = -1) sfxKill3DSound(&pSprite->s(), a2, a3); } +inline void ChangeActorStat(DBloodActor* actor, int stat) +{ + ChangeSpriteStat(actor->s().index, stat); +} + +inline void ChangeActorSect(DBloodActor* actor, int stat) +{ + ChangeSpriteSect(actor->s().index, stat); +} + +inline int Collision::actorIndex(DBloodActor* actor) +{ + return int(actor - bloodActors); +} + +inline DBloodActor* Collision::Actor(int a) +{ + return &bloodActors[a]; +} + END_BLD_NS diff --git a/source/games/blood/src/callback.cpp b/source/games/blood/src/callback.cpp index e7153413f..a6d804932 100644 --- a/source/games/blood/src/callback.cpp +++ b/source/games/blood/src/callback.cpp @@ -394,8 +394,9 @@ void fxBloodBits(DBloodActor* actor, int) // 14 { if (!actor) return; spritetype *pSprite = &actor->s(); - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0); + int ceilZ, floorZ; + Collision floorColl, ceilColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist, CLIPMASK0); int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); pSprite->z += floorZ-bottom; @@ -441,19 +442,22 @@ int sawedOffSleeveSnd[] = { 610, 612 }; void fxBouncingSleeve(DBloodActor* actor, int) // 16 { if (!actor) return; - spritetype* pSprite = &actor->s(); int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0); + spritetype* pSprite = &actor->s(); + int ceilZ, floorZ; + Collision floorColl, ceilColl; + + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist, CLIPMASK0); int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); pSprite->z += floorZ - bottom; int zv = actor->zvel() - velFloor[pSprite->sectnum]; - if (actor->zvel() == 0) sleeveStopBouncing(pSprite); + if (actor->zvel() == 0) sleeveStopBouncing(actor); else if (zv > 0) { actFloorBounceVector((int*)& actor->xvel(), (int*)& actor->yvel(), &zv, pSprite->sectnum, 0x9000); actor->zvel() = zv; if (velFloor[pSprite->sectnum] == 0 && abs(actor->zvel()) < 0x20000) { - sleeveStopBouncing(pSprite); + sleeveStopBouncing(actor); return; } @@ -474,8 +478,10 @@ void fxBouncingSleeve(DBloodActor* actor, int) // 16 } -void sleeveStopBouncing(spritetype* pSprite) { - xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0; +void sleeveStopBouncing(DBloodActor* actor) +{ + auto pSprite = &actor->s(); + actor->xvel() = actor->yvel() = actor->zvel() = 0; if (pSprite->extra > 0) seqKill(3, pSprite->extra); sfxKill3DSound(pSprite, -1, -1); @@ -501,11 +507,13 @@ void returnFlagToBase(DBloodActor* actor, int) // 17 { if (!actor) return; spritetype* pSprite = &actor->s(); - if (pSprite->owner >= 0 && pSprite->owner < kMaxSprites) + auto owner = actor->GetOwner(); + if (owner) { - spritetype* pOwner = &sprite[pSprite->owner]; - XSPRITE* pXOwner = &xsprite[pOwner->extra]; - switch (pSprite->type) { + spritetype* pOwner = &owner->s(); + XSPRITE* pXOwner = &owner->x(); + switch (pSprite->type) + { case kItemFlagA: trTriggerSprite(pOwner->index, pXOwner, kCmdOn); sndStartSample(8003, 255, 2, 0); @@ -546,8 +554,10 @@ void fxPodBloodSplat(DBloodActor* actor, int) // 19 { if (!actor) return; spritetype *pSprite = &actor->s(); - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist, CLIPMASK0); + int ceilZ, floorZ; + Collision floorColl, ceilColl; + + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist, CLIPMASK0); int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); pSprite->z += floorZ-bottom; @@ -605,7 +615,7 @@ void sub_76A08(DBloodActor *actor, spritetype *pSprite2, PLAYER *pPlayer) // ??? pSprite->y = pSprite2->y; pSprite->z = sector[pSprite2->sectnum].floorz-(bottom-pSprite->z); pSprite->ang = pSprite2->ang; - ChangeSpriteSect(pSprite->index, pSprite2->sectnum); + ChangeActorSect(actor, pSprite2->sectnum); sfxPlay3DSound(pSprite2, 201, -1, 0); actor->xvel() = actor->yvel() = actor->zvel() = 0; viewBackupSpriteLoc(pSprite->index, pSprite); @@ -743,16 +753,8 @@ void callbackCondition(DBloodActor* actor, int) for (unsigned i = 0; i < pCond->length; i++) { EVENT evn; evn.type = pCond->obj[i].type; - if (evn.type == SS_SPRITE) - { - evn.index_ = 0; - evn.actor = &bloodActors[pCond->obj[i].index]; - } - else - { - evn.actor = nullptr; - evn.index_ = pCond->obj[i].index; - } + evn.actor = pCond->obj[i].actor; + evn.index_ = pCond->obj[i].index_; evn.cmd = pCond->obj[i].cmd; evn.funcID = kCallbackCondition; useCondition(&sprite[pXSprite->reference], pXSprite, evn); diff --git a/source/games/blood/src/callback.h b/source/games/blood/src/callback.h index 0e6ea98f9..3e911076b 100644 --- a/source/games/blood/src/callback.h +++ b/source/games/blood/src/callback.h @@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma once BEGIN_BLD_NS -void sleeveStopBouncing(spritetype* pSprite); +void sleeveStopBouncing(DBloodActor* pSprite); enum CALLBACK_ID { kCallbackNone = -1, diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index f8731f72c..06925fd9a 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -189,8 +189,9 @@ int InsertSprite(int nSector, int nStat) return nSprite; } RemoveSpriteStat(nSprite); - spritetype *pSprite = &sprite[nSprite]; - memset(&sprite[nSprite], 0, sizeof(spritetype)); + DBloodActor* actor = &bloodActors[nSprite]; + spritetype *pSprite = &actor->s(); + memset(pSprite, 0, sizeof(spritetype)); InsertSpriteStat(nSprite, nStat); InsertSpriteSect(nSprite, nSector); pSprite->cstat = 128; @@ -199,7 +200,7 @@ int InsertSprite(int nSector, int nStat) pSprite->owner = -1; pSprite->extra = -1; pSprite->index = nSprite; - xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0; + actor->xvel() = actor->yvel() = actor->zvel() = 0; Numsprites++; @@ -226,7 +227,9 @@ int DeleteSprite(int nSprite) assert(sprite[nSprite].sectnum >= 0 && sprite[nSprite].sectnum < kMaxSectors); RemoveSpriteSect(nSprite); InsertSpriteStat(nSprite, kMaxStatus); - +#ifdef NOONE_EXTENSIONS + for (auto& ctrl : gPlayerCtrl) if (ctrl.qavScene.initiator == &bloodActors[nSprite]) ctrl.qavScene.initiator = nullptr; +#endif Numsprites--; return nSprite; @@ -515,9 +518,14 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor gModernMap = false; #endif - memset(sector, 0, sizeof(*sector) * MAXSECTORS); - memset(wall, 0, sizeof(*wall) * MAXWALLS); - memset(sprite, 0, sizeof(*sector) * MAXSPRITES); + memset(sector, 0, sizeof(sector)); + memset(wall, 0, sizeof(wall)); + memset(sprite, 0, sizeof(sprite)); + +#ifdef NOONE_EXTENSIONS + for (auto& ctrl : gPlayerCtrl) ctrl.qavScene.initiator = nullptr; +#endif + #ifdef USE_OPENGL Polymost::Polymost_prepare_loadboard(); @@ -885,6 +893,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor pSprite->shade = load.shade; pSprite->blend = 0; pSprite->time = i; + ValidateSprite(*pSprite); InsertSpriteSect(i, sprite[i].sectnum); InsertSpriteStat(i, sprite[i].statnum); diff --git a/source/games/blood/src/db.h b/source/games/blood/src/db.h index dc1031eb1..a51047bc2 100644 --- a/source/games/blood/src/db.h +++ b/source/games/blood/src/db.h @@ -289,11 +289,6 @@ struct MAPHEADER2 { char pad[52]; }; -struct SPRITEHIT -{ - int hit, ceilhit, florhit; -}; - #pragma pack(pop) extern unsigned short gStatCount[kMaxStatus + 1];; @@ -307,7 +302,6 @@ extern XWALL xwall[kMaxXWalls]; extern FixedBitArray activeXSprites; -extern SPRITEHIT gSpriteHit[kMaxXSprites]; extern char qsector_filler[kMaxSectors]; diff --git a/source/games/blood/src/eventq.cpp b/source/games/blood/src/eventq.cpp index acf517d25..fe3e1b38d 100644 --- a/source/games/blood/src/eventq.cpp +++ b/source/games/blood/src/eventq.cpp @@ -417,19 +417,17 @@ void evSend(DBloodActor* actor, int nIndex, int nType, int rxId, COMMAND_ID comm case kChannelRemoteBomb6: case kChannelRemoteBomb7: { - int nSprite; - StatIterator it(kStatThing); - while ((nSprite = it.NextIndex()) >= 0) + BloodStatIterator it(kStatThing); + while (auto actor = it.Next()) { - spritetype* pSprite = &sprite[nSprite]; + spritetype* pSprite = &actor->s(); if (pSprite->flags & 32) continue; - int nXSprite = pSprite->extra; - if (nXSprite > 0) + if (actor->hasX()) { - XSPRITE* pXSprite = &xsprite[nXSprite]; + XSPRITE* pXSprite = &actor->x(); if (pXSprite->rxID == rxId) - trMessageSprite(nSprite, event); + trMessageSprite(actor->s().index, event); } } return; @@ -437,19 +435,17 @@ void evSend(DBloodActor* actor, int nIndex, int nType, int rxId, COMMAND_ID comm case kChannelTeamAFlagCaptured: case kChannelTeamBFlagCaptured: { - int nSprite; - StatIterator it(kStatItem); - while ((nSprite = it.NextIndex()) >= 0) + BloodStatIterator it(kStatItem); + while (auto actor = it.Next()) { - spritetype* pSprite = &sprite[nSprite]; + spritetype* pSprite = &actor->s(); if (pSprite->flags & 32) continue; - int nXSprite = pSprite->extra; - if (nXSprite > 0) + if (actor->hasX()) { - XSPRITE* pXSprite = &xsprite[nXSprite]; + XSPRITE* pXSprite = &actor->x(); if (pXSprite->rxID == rxId) - trMessageSprite(nSprite, event); + trMessageSprite(actor->s().index, event); } } return; diff --git a/source/games/blood/src/fx.cpp b/source/games/blood/src/fx.cpp index 846f595cc..a3c84dd91 100644 --- a/source/games/blood/src/fx.cpp +++ b/source/games/blood/src/fx.cpp @@ -179,8 +179,8 @@ DBloodActor* CFX::fxSpawnActor(FX_ID nFx, int nSector, int x, int y, int z, unsi pSprite->cstat |= 8; if (pFX->seq) { - int nXSprite = dbInsertXSprite(pSprite->index); - seqSpawn(pFX->seq, 3, nXSprite, -1); + actor->addX(); + seqSpawn(pFX->seq, actor, -1); } if (a6 == 0) a6 = pFX->ate; @@ -196,7 +196,7 @@ void CFX::fxProcess(void) { spritetype *pSprite = &actor->s(); viewBackupSpriteLoc(actor); - short nSector = pSprite->sectnum; + int nSector = pSprite->sectnum; assert(nSector >= 0 && nSector < kMaxSectors); assert(pSprite->type < kFXMax); FXDATA *pFXData = &gFXData[pSprite->type]; @@ -227,7 +227,7 @@ void CFX::fxProcess(void) if (nSector != pSprite->sectnum) { assert(nSector >= 0 && nSector < kMaxSectors); - ChangeSpriteSect(actor->s().index, nSector); + ChangeActorSect(actor, nSector); } } if (actor->xvel() || actor->yvel() || actor->zvel()) @@ -304,40 +304,40 @@ void fxSpawnPodStuff(DBloodActor* actor, int ) void fxSpawnEjectingBrass(DBloodActor* actor, int z, int a3, int a4) { auto pSprite = &actor->s(); - int x = pSprite->x+MulScale(pSprite->clipdist-4, Cos(pSprite->ang), 28); - int y = pSprite->y+MulScale(pSprite->clipdist-4, Sin(pSprite->ang), 28); - x += MulScale(a3, Cos(pSprite->ang+512), 30); - y += MulScale(a3, Sin(pSprite->ang+512), 30); - auto pBrass = gFX.fxSpawnActor((FX_ID)(FX_37+Random(3)), pSprite->sectnum, x, y, z, 0); + int x = pSprite->x + MulScale(pSprite->clipdist - 4, Cos(pSprite->ang), 28); + int y = pSprite->y + MulScale(pSprite->clipdist - 4, Sin(pSprite->ang), 28); + x += MulScale(a3, Cos(pSprite->ang + 512), 30); + y += MulScale(a3, Sin(pSprite->ang + 512), 30); + auto pBrass = gFX.fxSpawnActor((FX_ID)(FX_37 + Random(3)), pSprite->sectnum, x, y, z, 0); if (pBrass) { if (!VanillaMode()) pBrass->s().ang = Random(2047); - int nDist = (a4<<18)/120+Random2(((a4/4)<<18)/120); - int nAngle = pSprite->ang+Random2(56)+512; + int nDist = (a4 << 18) / 120 + Random2(((a4 / 4) << 18) / 120); + int nAngle = pSprite->ang + Random2(56) + 512; pBrass->xvel() = MulScale(nDist, Cos(nAngle), 30); pBrass->yvel() = MulScale(nDist, Sin(nAngle), 30); - pBrass->zvel() = zvel[pSprite->index]-(0x20000+(Random2(40)<<18)/120); + pBrass->zvel() = actor->zvel() - (0x20000 + (Random2(40) << 18) / 120); } } void fxSpawnEjectingShell(DBloodActor* actor, int z, int a3, int a4) { auto pSprite = &actor->s(); - int x = pSprite->x+MulScale(pSprite->clipdist-4, Cos(pSprite->ang), 28); - int y = pSprite->y+MulScale(pSprite->clipdist-4, Sin(pSprite->ang), 28); - x += MulScale(a3, Cos(pSprite->ang+512), 30); - y += MulScale(a3, Sin(pSprite->ang+512), 30); - auto pShell = gFX.fxSpawnActor((FX_ID)(FX_40+Random(3)), pSprite->sectnum, x, y, z, 0); + int x = pSprite->x + MulScale(pSprite->clipdist - 4, Cos(pSprite->ang), 28); + int y = pSprite->y + MulScale(pSprite->clipdist - 4, Sin(pSprite->ang), 28); + x += MulScale(a3, Cos(pSprite->ang + 512), 30); + y += MulScale(a3, Sin(pSprite->ang + 512), 30); + auto pShell = gFX.fxSpawnActor((FX_ID)(FX_40 + Random(3)), pSprite->sectnum, x, y, z, 0); if (pShell) { if (!VanillaMode()) pShell->s().ang = Random(2047); - int nDist = (a4<<18)/120+Random2(((a4/4)<<18)/120); - int nAngle = pSprite->ang+Random2(56)+512; + int nDist = (a4 << 18) / 120 + Random2(((a4 / 4) << 18) / 120); + int nAngle = pSprite->ang + Random2(56) + 512; pShell->xvel() = MulScale(nDist, Cos(nAngle), 30); pShell->yvel() = MulScale(nDist, Sin(nAngle), 30); - pShell->zvel() = zvel[pSprite->index]-(0x20000+(Random2(20)<<18)/120); + pShell->zvel() = actor->zvel() - (0x20000 + (Random2(20) << 18) / 120); } } diff --git a/source/games/blood/src/gameutil.cpp b/source/games/blood/src/gameutil.cpp index 1475de6f1..c52beecdb 100644 --- a/source/games/blood/src/gameutil.cpp +++ b/source/games/blood/src/gameutil.cpp @@ -617,16 +617,19 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i return -1; } -void GetZRange(spritetype *pSprite, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax) +void GetZRange(spritetype *pSprite, int *ceilZ, Collision *ceilColl, int *floorZ, Collision *floorColl, int nDist, unsigned int nMask, unsigned int nClipParallax) { + int floorHit, ceilHit; assert(pSprite != NULL); int bakCstat = pSprite->cstat; int32_t nTemp1, nTemp2; pSprite->cstat &= ~257; - getzrange_old(pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, (int32_t*)ceilZ, (int32_t*)ceilHit, (int32_t*)floorZ, (int32_t*)floorHit, nDist, nMask); - if (((*floorHit) & 0xc000) == 0x4000) + getzrange(&pSprite->pos, pSprite->sectnum, (int32_t*)ceilZ, &ceilHit, (int32_t*)floorZ, &floorHit, nDist, nMask); + ceilColl->setFromEngine(ceilHit); + floorColl->setFromEngine(floorHit); + if (floorColl->type == kHitSector) { - int nSector = (*floorHit) & 0x3fff; + int nSector = floorColl->index; if ((nClipParallax & PARALLAXCLIP_FLOOR) == 0 && (sector[nSector].floorstat & 1)) *floorZ = 0x7fffffff; if (sector[nSector].extra > 0) @@ -638,37 +641,43 @@ void GetZRange(spritetype *pSprite, int *ceilZ, int *ceilHit, int *floorZ, int * { int nSprite = gUpperLink[nSector]; int nLink = sprite[nSprite].owner & 0xfff; - getzrange_old(pSprite->x+sprite[nLink].x-sprite[nSprite].x, pSprite->y+sprite[nLink].y-sprite[nSprite].y, - pSprite->z+sprite[nLink].z-sprite[nSprite].z, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, (int32_t*)floorHit, - nDist, nMask); + vec3_t lpos = { pSprite->x + sprite[nLink].x - sprite[nSprite].x, pSprite->y + sprite[nLink].y - sprite[nSprite].y, + pSprite->z + sprite[nLink].z - sprite[nSprite].z }; + getzrange(&lpos, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, &floorHit, nDist, nMask); *floorZ -= sprite[nLink].z - sprite[nSprite].z; + floorColl->setFromEngine(floorHit); } } - if (((*ceilHit) & 0xc000) == 0x4000) + if (ceilColl->type == kHitSector) { - int nSector = (*ceilHit) & 0x3fff; + int nSector = ceilColl->index; if ((nClipParallax & PARALLAXCLIP_CEILING) == 0 && (sector[nSector].ceilingstat & 1)) *ceilZ = 0x80000000; if (gLowerLink[nSector] >= 0) { int nSprite = gLowerLink[nSector]; int nLink = sprite[nSprite].owner & 0xfff; - getzrange_old(pSprite->x+sprite[nLink].x-sprite[nSprite].x, pSprite->y+sprite[nLink].y-sprite[nSprite].y, - pSprite->z+sprite[nLink].z-sprite[nSprite].z, sprite[nLink].sectnum, (int32_t*)ceilZ, (int32_t*)ceilHit, &nTemp1, &nTemp2, - nDist, nMask); + vec3_t lpos = { pSprite->x + sprite[nLink].x - sprite[nSprite].x, pSprite->y + sprite[nLink].y - sprite[nSprite].y, + pSprite->z + sprite[nLink].z - sprite[nSprite].z }; + getzrange(&lpos, sprite[nLink].sectnum, (int32_t*)ceilZ, &ceilHit, &nTemp1, &nTemp2, nDist, nMask); *ceilZ -= sprite[nLink].z - sprite[nSprite].z; + ceilColl->setFromEngine(ceilHit); } } pSprite->cstat = bakCstat; } -void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax) +void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, Collision* ceilColl, int* floorZ, Collision* floorColl, int nDist, unsigned int nMask, unsigned int nClipParallax) { + int ceilHit, floorHit; int32_t nTemp1, nTemp2; - getzrange_old(x, y, z, nSector, (int32_t*)ceilZ, (int32_t*)ceilHit, (int32_t*)floorZ, (int32_t*)floorHit, nDist, nMask); - if (((*floorHit) & 0xc000) == 0x4000) + vec3_t lpos = { x, y, z }; + getzrange(&lpos, nSector, (int32_t*)ceilZ, &ceilHit, (int32_t*)floorZ, &floorHit, nDist, nMask); + ceilColl->setFromEngine(ceilHit); + floorColl->setFromEngine(floorHit); + if (floorColl->type == kHitSector) { - int nSector = (*floorHit) & 0x3fff; + int nSector = floorColl->index; if ((nClipParallax & PARALLAXCLIP_FLOOR) == 0 && (sector[nSector].floorstat & 1)) *floorZ = 0x7fffffff; if (sector[nSector].extra > 0) @@ -680,24 +689,24 @@ void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, int *ceilHit, { int nSprite = gUpperLink[nSector]; int nLink = sprite[nSprite].owner & 0xfff; - getzrange_old(x+sprite[nLink].x-sprite[nSprite].x, y+sprite[nLink].y-sprite[nSprite].y, - z+sprite[nLink].z-sprite[nSprite].z, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, (int32_t*)floorHit, - nDist, nMask); + lpos = { x + sprite[nLink].x - sprite[nSprite].x, y + sprite[nLink].y - sprite[nSprite].y, + z + sprite[nLink].z - sprite[nSprite].z }; + getzrange(&lpos, sprite[nLink].sectnum, &nTemp1, &nTemp2, (int32_t*)floorZ, &floorHit, nDist, nMask); *floorZ -= sprite[nLink].z - sprite[nSprite].z; } } - if (((*ceilHit) & 0xc000) == 0x4000) + if (ceilColl->type == kHitSector) { - int nSector = (*ceilHit) & 0x3fff; + int nSector = ceilColl->index; if ((nClipParallax & PARALLAXCLIP_CEILING) == 0 && (sector[nSector].ceilingstat & 1)) *ceilZ = 0x80000000; if (gLowerLink[nSector] >= 0) { int nSprite = gLowerLink[nSector]; int nLink = sprite[nSprite].owner & 0xfff; - getzrange_old(x+sprite[nLink].x-sprite[nSprite].x, y+sprite[nLink].y-sprite[nSprite].y, - z+sprite[nLink].z-sprite[nSprite].z, sprite[nLink].sectnum, (int32_t*)ceilZ, (int32_t*)ceilHit, &nTemp1, &nTemp2, - nDist, nMask); + lpos = { x + sprite[nLink].x - sprite[nSprite].x, y + sprite[nLink].y - sprite[nSprite].y, + z + sprite[nLink].z - sprite[nSprite].z }; + getzrange(&lpos, sprite[nLink].sectnum, (int32_t*)ceilZ, &ceilHit, &nTemp1, &nTemp2, nDist, nMask); *ceilZ -= sprite[nLink].z - sprite[nSprite].z; } } @@ -730,16 +739,14 @@ int GetDistToLine(int x1, int y1, int x2, int y2, int x3, int y3) return approxDist(t1-x1, t2-y1); } -unsigned int ClipMove(int *x, int *y, int *z, int *nSector, int xv, int yv, int wd, int cd, int fd, unsigned int nMask) +unsigned int ClipMove(vec3_t *pos, int *nSector, int xv, int yv, int wd, int cd, int fd, unsigned int nMask, int tracecount) { - int bakX = *x; - int bakY = *y; - int bakZ = *z; - short bakSect = *nSector; - unsigned int nRes = clipmove_old((int32_t*)x, (int32_t*)y, (int32_t*)z, &bakSect, xv<<14, yv<<14, wd, cd, fd, nMask); + auto opos = *pos; + int bakSect = *nSector; + unsigned int nRes = clipmove(pos, &bakSect, xv<<14, yv<<14, wd, cd, fd, nMask, tracecount); if (bakSect == -1) { - *x = bakX; *y = bakY; *z = bakZ; + *pos = opos; } else { diff --git a/source/games/blood/src/gameutil.h b/source/games/blood/src/gameutil.h index ce08ba8f0..39eb7b041 100644 --- a/source/games/blood/src/gameutil.h +++ b/source/games/blood/src/gameutil.h @@ -73,7 +73,7 @@ inline bool wallRangeIsFine(int nIndex) { return (nIndex >= 0 && nIndex < kMaxWalls); } /// - +struct Collision; bool AreSectorsNeighbors(int sect1, int sect2); bool FindSector(int nX, int nY, int nZ, int *nSector); bool FindSector(int nX, int nY, int *nSector); @@ -86,10 +86,10 @@ void GetWallNormal(int nWall, int *pX, int *pY); bool IntersectRay(int wx, int wy, int wdx, int wdy, int x1, int y1, int z1, int x2, int y2, int z2, int *ix, int *iy, int *iz); int HitScan(spritetype *pSprite, int z, int dx, int dy, int dz, unsigned int nMask, int a8); int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, int dz, int nRange, int ac); -void GetZRange(spritetype *pSprite, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); -void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, int *ceilHit, int *floorZ, int *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); +void GetZRange(spritetype *pSprite, int *ceilZ, Collision *ceilHit, int *floorZ, Collision *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); +void GetZRangeAtXYZ(int x, int y, int z, int nSector, int *ceilZ, Collision *ceilHit, int *floorZ, Collision *floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0); int GetDistToLine(int x1, int y1, int x2, int y2, int x3, int y3); -unsigned int ClipMove(int *x, int *y, int *z, int *nSector, int xv, int yv, int wd, int cd, int fd, unsigned int nMask); +unsigned int ClipMove(vec3_t* pos, int *nSector, int xv, int yv, int wd, int cd, int fd, unsigned int nMask, int tracecount = 3); int GetClosestSectors(int nSector, int x, int y, int nDist, short *pSectors, char *pSectBit); int GetClosestSpriteSectors(int nSector, int x, int y, int nDist, uint8_t *pSectBit, short *pWalls = nullptr, bool newSectCheckMethod = false); int picWidth(short nPic, short repeat); diff --git a/source/games/blood/src/gib.cpp b/source/games/blood/src/gib.cpp index 5c670b345..9bfa321fc 100644 --- a/source/games/blood/src/gib.cpp +++ b/source/games/blood/src/gib.cpp @@ -382,37 +382,39 @@ void GibThing(spritetype *pSprite, GIBTHING *pGThing, CGibPosition *pPos, CGibVe getzsofslope(nSector, x, y, &ceilZ, &floorZ); int dz1 = floorZ-z; int dz2 = z-ceilZ; - spritetype *pGib = &actSpawnThing(nSector, x, y, z, pGThing->type)->s(); + auto gibactor = actSpawnThing(nSector, x, y, z, pGThing->type); + if (!gibactor) return; + spritetype *pGib = &gibactor->s(); assert(pGib != NULL); if (pGThing->Kills > -1) pGib->picnum = pGThing->Kills; if (pVel) { - xvel[pGib->index] = pVel->vx+Random2(pGThing->atc); - yvel[pGib->index] = pVel->vy+Random2(pGThing->atc); - zvel[pGib->index] = pVel->vz-Random(pGThing->at10); + gibactor->xvel() = pVel->vx+Random2(pGThing->atc); + gibactor->yvel() = pVel->vy+Random2(pGThing->atc); + gibactor->zvel() = pVel->vz-Random(pGThing->at10); } else { - xvel[pGib->index] = Random2((pGThing->atc<<18)/120); - yvel[pGib->index] = Random2((pGThing->atc<<18)/120); + gibactor->xvel() = Random2((pGThing->atc<<18)/120); + gibactor->yvel() = Random2((pGThing->atc<<18)/120); switch (pSprite->cstat&48) { case 16: - zvel[pGib->index] = Random2((pGThing->at10<<18)/120); + gibactor->zvel() = Random2((pGThing->at10<<18)/120); break; default: if (dz2 < dz1 && dz2 < 0x4000) { - zvel[pGib->index] = 0; + gibactor->zvel() = 0; } else if (dz2 > dz1 && dz1 < 0x4000) { - zvel[pGib->index] = -(int)Random((pGThing->at10<<18)/120); + gibactor->zvel() = -(int)Random((pGThing->at10<<18)/120); } else { - zvel[pGib->index] = Random2((pGThing->at10<<18)/120); + gibactor->zvel() = Random2((pGThing->at10<<18)/120); } break; } diff --git a/source/games/blood/src/misc.h b/source/games/blood/src/misc.h index f889ce817..8fe783ab4 100644 --- a/source/games/blood/src/misc.h +++ b/source/games/blood/src/misc.h @@ -64,33 +64,20 @@ void warpInit(void); int CheckLink(spritetype *pSprite); int CheckLink(int *x, int *y, int *z, int *nSector); -extern int costable[2048]; - int GetOctant(int x, int y); void RotateVector(int *dx, int *dy, int nAngle); void RotatePoint(int *x, int *y, int nAngle, int ox, int oy); -void trigInit(); #include "m_fixed.h" inline int Sin(int ang) { - return costable[(ang - 512) & 2047]; + return sintable[ang & 2047]; } inline int Cos(int ang) { - return costable[ang & 2047]; -} - -inline int SinScale16(int ang) -{ - return FixedToInt(costable[(ang - 512) & 2047]); -} - -inline int CosScale16(int ang) -{ - return FixedToInt(costable[ang & 2047]); + return sintable[(ang + 512) & 2047]; } enum SurfaceType { @@ -120,6 +107,8 @@ extern int nPrecacheCount; void tilePrecacheTile(int nTile, int nType, int palette); -char tileGetSurfType(int hit); +struct Collision; +int tileGetSurfType(int hit); +int tileGetSurfType(Collision& hit); END_BLD_NS diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 0d22ce855..1df4a8d68 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -255,27 +255,36 @@ CONDITION_TYPE_NAMES gCondTypeNames[7] = { // for actor.cpp //------------------------------------------------------------------------- -spritetype* nnExtSpawnDude(XSPRITE* pXSource, spritetype* pSprite, short nType, int a3, int a4) -{ +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- +static DBloodActor* nnExtSpawnDude(DBloodActor* sourceActor, DBloodActor* origin, short nType, int a3, int a4) +{ DBloodActor* pDudeActor = nullptr; - spritetype* pSource = &sprite[pXSource->reference]; - if (nType < kDudeBase || nType >= kDudeMax || (pDudeActor = actSpawnSprite(&bloodActors[pSprite->index], kStatDude)) == NULL) + auto pSource = &sourceActor->s(); + auto pXSource = &sourceActor->x(); + auto pOrigin = &origin->s(); + + if (nType < kDudeBase || nType >= kDudeMax || (pDudeActor = actSpawnSprite(origin, kStatDude)) == NULL) return NULL; spritetype* pDude = &pDudeActor->s(); XSPRITE* pXDude = &pDudeActor->x(); - int angle = pSprite->ang; - int x, y, z = a4 + pSprite->z; + int angle = pOrigin->ang; + int x, y, z = a4 + pOrigin->z; if (a3 < 0) { - x = pSprite->x; - y = pSprite->y; - } else + x = pOrigin->x; + y = pOrigin->y; + } + else { - x = pSprite->x + mulscale30r(Cos(angle), a3); - y = pSprite->y + mulscale30r(Sin(angle), a3); + x = pOrigin->x + mulscale30r(Cos(angle), a3); + y = pOrigin->y + mulscale30r(Sin(angle), a3); } vec3_t pos = { x, y, z }; @@ -331,18 +340,28 @@ spritetype* nnExtSpawnDude(XSPRITE* pXSource, spritetype* pSprite, short nType, if ((burning || (pSource->flags & kModernTypeFlag3)) && !pXDude->dudeFlag4) aiActivateDude(pDudeActor); - return pDude; + return pDudeActor; } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- -bool nnExtIsImmune(spritetype* pSprite, int dmgType, int minScale) { - - if (dmgType >= kDmgFall && dmgType < kDmgMax && pSprite->extra >= 0 && xsprite[pSprite->extra].locked != 1) { +bool nnExtIsImmune(DBloodActor* actor, int dmgType, int minScale) +{ + auto pSprite = &actor->s(); + if (dmgType >= kDmgFall && dmgType < kDmgMax && actor->hasX() && actor->x().locked != 1) + { if (pSprite->type >= kThingBase && pSprite->type < kThingMax) + { return (thingInfo[pSprite->type - kThingBase].dmgControl[dmgType] <= minScale); - else if (IsDudeSprite(pSprite)) { - if (IsPlayerSprite(pSprite)) return (gPlayer[pSprite->type - kDudePlayer1].damageControl[dmgType]); - else if (pSprite->type == kDudeModernCustom) return (gGenDudeExtra[pSprite->index].dmgControl[dmgType] <= minScale); + } + else if (actor->IsDudeActor()) + { + if (actor->IsPlayerActor()) return (gPlayer[pSprite->type - kDudePlayer1].damageControl[dmgType]); + else if (pSprite->type == kDudeModernCustom) return (actor->genDudeExtra().dmgControl[dmgType] <= minScale); else return (getDudeInfo(pSprite->type)->damageVal[dmgType] <= minScale); } } @@ -350,8 +369,17 @@ bool nnExtIsImmune(spritetype* pSprite, int dmgType, int minScale) { return true; } -bool nnExtEraseModernStuff(spritetype* pSprite, XSPRITE* pXSprite) { - +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool nnExtEraseModernStuff(DBloodActor* actor) +{ + auto pSprite = &actor->s(); + auto pXSprite = &actor->x(); + bool erased = false; switch (pSprite->type) { // erase all modern types if the map is not extended @@ -383,7 +411,7 @@ bool nnExtEraseModernStuff(spritetype* pSprite, XSPRITE* pXSprite) { case kModernThingTNTProx: case kModernThingEnemyLifeLeech: pSprite->type = kSpriteDecoration; - changespritestat(pSprite->index, kStatDecoration); + ChangeActorStat(actor, kStatDecoration); erased = true; break; // also erase some modernized vanilla types which was not active @@ -394,14 +422,17 @@ bool nnExtEraseModernStuff(spritetype* pSprite, XSPRITE* pXSprite) { break; } - if (pXSprite->Sight) { + if (pXSprite->Sight) + { pXSprite->Sight = false; // it does not work in vanilla at all erased = true; } - if (pXSprite->Proximity) { + if (pXSprite->Proximity) + { // proximity works only for things and dudes in vanilla - switch (pSprite->statnum) { + switch (pSprite->statnum) + { case kStatThing: case kStatDude: break; @@ -415,8 +446,16 @@ bool nnExtEraseModernStuff(spritetype* pSprite, XSPRITE* pXSprite) { return erased; } -void nnExtTriggerObject(int objType, int objIndex, int command) { - switch (objType) { +//--------------------------------------------------------------------------- +// +// todo later. This depends on condSerialize. +// +//--------------------------------------------------------------------------- + +void nnExtTriggerObject(int objType, int objIndex, int command) +{ + switch (objType) + { case OBJ_SECTOR: if (!xsectRangeIsFine(sector[objIndex].extra)) break; trTriggerSector(objIndex, &xsector[sector[objIndex].extra], command); @@ -434,7 +473,14 @@ void nnExtTriggerObject(int objType, int objIndex, int command) { return; } -void nnExtResetGlobals() { +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void nnExtResetGlobals() +{ gAllowTrueRandom = gEventRedirectsUsed = false; // reset counters @@ -447,11 +493,15 @@ void nnExtResetGlobals() { memset(gImpactSpritesList, 0, sizeof(gImpactSpritesList)); // reset tracking conditions, if any - if (gTrackingCondsCount > 0) { - for (int i = 0; i < gTrackingCondsCount; i++) { + if (gTrackingCondsCount > 0) + { + for (int i = 0; i < gTrackingCondsCount; i++) + { TRCONDITION* pCond = &gCondition[i]; - for (unsigned k = 0; k < pCond->length; k++) { - pCond->obj[k].index = pCond->obj[k].cmd = 0; + for (unsigned k = 0; k < pCond->length; k++) + { + pCond->obj[k].actor = nullptr; + pCond->obj[k].index_ = pCond->obj[k].cmd = 0; pCond->obj[k].type = -1; } @@ -469,31 +519,36 @@ void nnExtResetGlobals() { } -void nnExtInitModernStuff(bool bSaveLoad) { - +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void nnExtInitModernStuff(bool bSaveLoad) +{ nnExtResetGlobals(); // use true random only for single player mode, otherwise use Blood's default one. - if (gGameOptions.nGameType == 0 && !VanillaMode()) { - + if (gGameOptions.nGameType == 0 && !VanillaMode()) + { gStdRandom.seed(std::random_device()()); // since true random is not working if compiled with old mingw versions, we should // check if it works in game and if not - switch to using in-game random function. - for (int i = kMaxRandomizeRetries; i >= 0; i--) { + for (int i = kMaxRandomizeRetries; i >= 0; i--) + { std::uniform_int_distribution dist_a_b(0, 100); if (gAllowTrueRandom || i <= 0) break; else if (dist_a_b(gStdRandom) != 0) gAllowTrueRandom = true; } - } - - for (int i = 0; i < kMaxXSprites; i++) { - - if (xsprite[i].reference < 0) continue; + for (int i = 0; i < kMaxXSprites; i++) + { auto actor = &bloodActors[i]; + if (!actor->hasX()) continue; XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); @@ -504,33 +559,36 @@ void nnExtInitModernStuff(bool bSaveLoad) { break; case kDudeModernCustom: case kDudeModernCustomBurning: - getSpriteMassBySize(pSprite); // create mass cache + getSpriteMassBySize(actor); // create mass cache break; case kModernCondition: case kModernConditionFalse: if (bSaveLoad) break; - else if (!pXSprite->rxID && pXSprite->data1 > kCondGameMax) condError(pXSprite,"\nThe condition must have RX ID!\nSPRITE #%d", pSprite->index); - else if (!pXSprite->txID && !pSprite->flags) { + else if (!pXSprite->rxID && pXSprite->data1 > kCondGameMax) condError(pXSprite,"\nThe condition must have RX ID!\nSPRITE #%d", actor->GetIndex()); + else if (!pXSprite->txID && !pSprite->flags) + { Printf(PRINT_HIGH, "The condition must have TX ID or hitag to be set: RX ID %d, SPRITE #%d", pXSprite->rxID, pSprite->index); } break; } // init after loading save file - if (bSaveLoad) { - + if (bSaveLoad) + { // add in list of physics affected sprites - if (pXSprite->physAttr != 0) { - //xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0; - + if (pXSprite->physAttr != 0) + { gPhysSpritesList[gPhysSpritesCount++] = &bloodActors[pSprite->index]; // add sprite index - getSpriteMassBySize(pSprite); // create mass cache + getSpriteMassBySize(actor); // create mass cache } - if (pXSprite->data3 != pXSprite->sysData1) { - switch (pSprite->statnum) { + if (pXSprite->data3 != pXSprite->sysData1) + { + switch (pSprite->statnum) + { case kStatDude: - switch (pSprite->type) { + switch (pSprite->type) + { case kDudeModernCustom: case kDudeModernCustomBurning: pXSprite->data3 = pXSprite->sysData1; // move sndStartId back from sysData1 to data3 @@ -539,21 +597,23 @@ void nnExtInitModernStuff(bool bSaveLoad) { break; } } - - } else { - + } + else + { // auto set going On and going Off if both are empty if (pXSprite->txID && !pXSprite->triggerOn && !pXSprite->triggerOff) pXSprite->triggerOn = pXSprite->triggerOff = true; // copy custom start health to avoid overwrite by kThingBloodChunks - if (IsDudeSprite(pSprite)) + if (actor->IsDudeActor()) pXSprite->sysData2 = pXSprite->data4; // check reserved statnums - if (pSprite->statnum >= kStatModernBase && pSprite->statnum < kStatModernMax) { + if (pSprite->statnum >= kStatModernBase && pSprite->statnum < kStatModernMax) + { bool sysStat = true; - switch (pSprite->statnum) { + switch (pSprite->statnum) + { case kStatModernStealthRegion: sysStat = (pSprite->type != kModernStealthRegion); break; @@ -576,19 +636,20 @@ void nnExtInitModernStuff(bool bSaveLoad) { } if (sysStat) - I_Error("Sprite statnum %d on sprite #%d is in a range of reserved (%d - %d)!", pSprite->statnum, pSprite->index, kStatModernBase, kStatModernMax); + I_Error("Sprite statnum %d on sprite #%d is in a range of reserved (%d - %d)!", pSprite->statnum, actor->GetIndex(), kStatModernBase, kStatModernMax); } - switch (pSprite->type) { + switch (pSprite->type) + { case kModernRandomTX: case kModernSequentialTX: if (pXSprite->command != kCmdLink) break; // add statnum for faster redirects search - changespritestat(pSprite->index, kStatModernEventRedirector); + ChangeActorStat(actor, kStatModernEventRedirector); break; case kModernWindGenerator: pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; - changespritestat(pSprite->index, kStatModernWindGen); + ChangeActorStat(actor, kStatModernWindGen); break; case kModernDudeTargetChanger: case kModernObjDataAccumulator: @@ -597,21 +658,22 @@ void nnExtInitModernStuff(bool bSaveLoad) { case kModernStealthRegion: pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; pSprite->cstat |= CSTAT_SPRITE_INVISIBLE; - switch (pSprite->type) { + switch (pSprite->type) + { // stealth regions for patrolling enemies case kModernStealthRegion: - changespritestat(pSprite->index, kStatModernStealthRegion); + ChangeActorStat(actor, kStatModernStealthRegion); break; // add statnum for faster dude searching case kModernDudeTargetChanger: - changespritestat(pSprite->index, kStatModernDudeTargetChanger); + ChangeActorStat(actor, kStatModernDudeTargetChanger); if (pXSprite->busyTime <= 0) pXSprite->busyTime = 5; pXSprite->command = kCmdLink; break; // remove kStatItem status from random item generators case kModernRandom: case kModernRandom2: - changespritestat(pSprite->index, kStatDecoration); + ChangeActorStat(actor, kStatDecoration); pXSprite->sysData1 = pXSprite->command; // save the command so spawned item can inherit it pXSprite->command = kCmdLink; // generator itself can't send commands break; @@ -623,14 +685,14 @@ void nnExtInitModernStuff(bool bSaveLoad) { case kDudeModernCustom: { if (pXSprite->txID <= 0) break; - int nSprite, found = 0; - StatIterator it(kStatDude); - while ((nSprite = it.NextIndex()) >= 0) + int found = 0; + BloodStatIterator it(kStatDude); + while (DBloodActor* iactor = it.Next()) { - XSPRITE* pXSpr = &xsprite[sprite[nSprite].extra]; + XSPRITE* pXSpr = &iactor->x(); if (pXSpr->rxID != pXSprite->txID) continue; else if (found) I_Error("\nCustom dude (TX ID %d):\nOnly one incarnation allowed per channel!", pXSprite->txID); - changespritestat(nSprite, kStatInactive); + ChangeActorStat(iactor, kStatInactive); found++; } break; @@ -640,20 +702,21 @@ void nnExtInitModernStuff(bool bSaveLoad) { pXSprite->state = 1; break; case kModernPlayerControl: - switch (pXSprite->command) { + switch (pXSprite->command) + { case kCmdLink: { if (pXSprite->data1 < 1 || pXSprite->data1 > kMaxPlayers) - I_Error("\nPlayer Control (SPRITE #%d):\nPlayer out of a range (data1 = %d)", pSprite->index, pXSprite->data1); + I_Error("\nPlayer Control (SPRITE #%d):\nPlayer out of a range (data1 = %d)", actor->GetIndex(), pXSprite->data1); //if (numplayers < pXSprite->data1) //I_Error("\nPlayer Control (SPRITE #%d):\n There is no player #%d", pSprite->index, pXSprite->data1); if (pXSprite->rxID && pXSprite->rxID != kChannelLevelStart) - I_Error("\nPlayer Control (SPRITE #%d) with Link command should have no RX ID!", pSprite->index); + I_Error("\nPlayer Control (SPRITE #%d) with Link command should have no RX ID!", actor->GetIndex()); if (pXSprite->txID && pXSprite->txID < kChannelUser) - I_Error("\nPlayer Control (SPRITE #%d):\nTX ID should be in range of %d and %d!", pSprite->index, kChannelUser, kChannelMax); + I_Error("\nPlayer Control (SPRITE #%d):\nTX ID should be in range of %d and %d!", actor->GetIndex(), kChannelUser, kChannelMax); // only one linker per player allowed int nSprite; @@ -662,28 +725,28 @@ void nnExtInitModernStuff(bool bSaveLoad) { { XSPRITE* pXCtrl = &xsprite[sprite[nSprite].extra]; if (pXSprite->data1 == pXCtrl->data1) - I_Error("\nPlayer Control (SPRITE #%d):\nPlayer %d already linked with different player control sprite #%d!", pSprite->index, pXSprite->data1, nSprite); + I_Error("\nPlayer Control (SPRITE #%d):\nPlayer %d already linked with different player control sprite #%d!", actor->GetIndex(), pXSprite->data1, nSprite); } pXSprite->sysData1 = -1; pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; - changespritestat(pSprite->index, kStatModernPlayerLinker); + ChangeActorStat(actor, kStatModernPlayerLinker); break; } case 67: // play qav animation if (pXSprite->txID && !pXSprite->waitTime) pXSprite->waitTime = 1; - changespritestat(pSprite->index, kStatModernQavScene); + ChangeActorStat(actor, kStatModernQavScene); break; } break; case kModernCondition: case kModernConditionFalse: - if (pXSprite->busyTime > 0) { - - if (pXSprite->waitTime > 0) { + if (pXSprite->busyTime > 0) + { + if (pXSprite->waitTime > 0) + { pXSprite->busyTime += ClipHigh(((pXSprite->waitTime * 120) / 10), 4095); pXSprite->waitTime = 0; Printf(PRINT_HIGH, "Summing busyTime and waitTime for tracking condition #%d, RX ID %d. Result = %d ticks", pSprite->index, pXSprite->rxID, pXSprite->busyTime); } - pXSprite->busy = pXSprite->busyTime; } @@ -697,7 +760,7 @@ void nnExtInitModernStuff(bool bSaveLoad) { pXSprite->targetX = pXSprite->targetY = pXSprite->targetZ = pXSprite->sysData2 = -1; actor->SetTarget(nullptr); - changespritestat(pSprite->index, kStatModernCondition); + ChangeActorStat(actor, kStatModernCondition); int oldStat = pSprite->cstat; pSprite->cstat = 0x30; if (oldStat & CSTAT_SPRITE_BLOCK) @@ -725,8 +788,10 @@ void nnExtInitModernStuff(bool bSaveLoad) { } // make Proximity flag work not just for dudes and things... - if (pXSprite->Proximity && gProxySpritesCount < kMaxSuperXSprites) { - switch (pSprite->statnum) { + if (pXSprite->Proximity && gProxySpritesCount < kMaxSuperXSprites) + { + switch (pSprite->statnum) + { case kStatFX: case kStatExplosion: case kStatItem: case kStatPurge: case kStatSpares: case kStatFlare: case kStatInactive: case kStatFree: case kStatMarker: @@ -734,7 +799,7 @@ void nnExtInitModernStuff(bool bSaveLoad) { case kStatModernPlayerLinker: break; default: - gProxySpritesList[gProxySpritesCount++] = &bloodActors[pSprite->index]; + gProxySpritesList[gProxySpritesCount++] = actor; if (gProxySpritesCount == kMaxSuperXSprites) I_Error("Max (%d) *additional* Proximity sprites reached!", kMaxSuperXSprites); break; @@ -742,15 +807,17 @@ void nnExtInitModernStuff(bool bSaveLoad) { } // make Sight, Screen, Aim flags work not just for dudes and things... - if ((pXSprite->Sight || pXSprite->unused3) && gSightSpritesCount < kMaxSuperXSprites) { - switch (pSprite->statnum) { + if ((pXSprite->Sight || pXSprite->unused3) && gSightSpritesCount < kMaxSuperXSprites) + { + switch (pSprite->statnum) + { case kStatFX: case kStatExplosion: case kStatItem: case kStatPurge: case kStatSpares: case kStatFlare: case kStatInactive: case kStatFree: case kStatMarker: case kStatPathMarker: case kStatModernPlayerLinker: break; default: - gSightSpritesList[gSightSpritesCount++] = &bloodActors[pSprite->index]; + gSightSpritesList[gSightSpritesCount++] = actor; if (gSightSpritesCount == kMaxSuperXSprites) I_Error("Max (%d) Sight sprites reached!", kMaxSuperXSprites); break; @@ -758,15 +825,17 @@ void nnExtInitModernStuff(bool bSaveLoad) { } // make Impact flag work for sprites that affected by explosions... - if (pXSprite->Impact && gImpactSpritesCount < kMaxSuperXSprites) { - switch (pSprite->statnum) { + if (pXSprite->Impact && gImpactSpritesCount < kMaxSuperXSprites) + { + switch (pSprite->statnum) + { case kStatFX: case kStatExplosion: case kStatItem: case kStatPurge: case kStatSpares: case kStatFlare: case kStatInactive: case kStatFree: case kStatMarker: case kStatPathMarker: case kStatModernPlayerLinker: break; default: - gImpactSpritesList[gImpactSpritesCount++] = &bloodActors[pSprite->index]; + gImpactSpritesList[gImpactSpritesCount++] = actor; if (gImpactSpritesCount == kMaxSuperXSprites) I_Error("Max (%d) *additional* Impact sprites reached!", kMaxSuperXSprites); break; @@ -775,11 +844,11 @@ void nnExtInitModernStuff(bool bSaveLoad) { } // collect objects for tracking conditions - int i; - StatIterator it(kStatModernCondition); - while ((i = it.NextIndex()) >= 0) + BloodStatIterator it(kStatModernCondition); + while (auto iactor = it.Next()) { - spritetype* pSprite = &sprite[i]; XSPRITE* pXSprite = &xsprite[pSprite->extra]; + spritetype* pSprite = &iactor->s(); + XSPRITE* pXSprite = &iactor->x(); if (pXSprite->busyTime <= 0 || pXSprite->isTriggered) continue; else if (gTrackingCondsCount >= kMaxTrackingConditions) @@ -788,7 +857,8 @@ void nnExtInitModernStuff(bool bSaveLoad) { int count = 0; TRCONDITION* pCond = &gCondition[gTrackingCondsCount]; - for (int i = 0; i < kMaxXSprites; i++) { + for (int i = 0; i < kMaxXSprites; i++) + { if (!spriRangeIsFine(xsprite[i].reference) || xsprite[i].txID != pXSprite->rxID || xsprite[i].reference == pSprite->index) continue; @@ -813,21 +883,25 @@ void nnExtInitModernStuff(bool bSaveLoad) { condError(pXSprite, "Max(%d) objects to track reached for condition #%d, RXID: %d!"); pCond->obj[count].type = OBJ_SPRITE; - pCond->obj[count].index = index; + pCond->obj[count].index_ = 0; + pCond->obj[count].actor = &bloodActors[index]; pCond->obj[count++].cmd = cmd; } - for (int i = 0; i < kMaxXSectors; i++) { + for (int i = 0; i < kMaxXSectors; i++) + { if (!sectRangeIsFine(xsector[i].reference) || xsector[i].txID != pXSprite->rxID) continue; else if (count >= kMaxTracedObjects) condError(pXSprite, "Max(%d) objects to track reached for condition #%d, RXID: %d!"); pCond->obj[count].type = OBJ_SECTOR; - pCond->obj[count].index = xsector[i].reference; + pCond->obj[count].actor = nullptr; + pCond->obj[count].index_ = xsector[i].reference; pCond->obj[count++].cmd = xsector[i].command; } - for (int i = 0; i < kMaxXWalls; i++) { + for (int i = 0; i < kMaxXWalls; i++) + { if (!wallRangeIsFine(xwall[i].reference) || xwall[i].txID != pXSprite->rxID) continue; @@ -842,7 +916,8 @@ void nnExtInitModernStuff(bool bSaveLoad) { condError(pXSprite, "Max(%d) objects to track reached for condition #%d, RXID: %d!"); pCond->obj[count].type = OBJ_WALL; - pCond->obj[count].index = xwall[i].reference; + pCond->obj[count].index_ = xwall[i].reference; + pCond->obj[count].actor = nullptr; pCond->obj[count++].cmd = xwall[i].command; } @@ -850,7 +925,7 @@ void nnExtInitModernStuff(bool bSaveLoad) { Printf(PRINT_HIGH, "No objects to track found for condition #%d, RXID: %d!", pSprite->index, pXSprite->rxID); pCond->length = count; - pCond->xindex = pSprite->extra; + pCond->actor = iactor; gTrackingCondsCount++; } @@ -858,37 +933,52 @@ void nnExtInitModernStuff(bool bSaveLoad) { // The following functions required for random event features -//------------------------- -int nnExtRandom(int a, int b) { +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int nnExtRandom(int a, int b) +{ if (!gAllowTrueRandom) return Random(((b + 1) - a)) + a; // used for better randomness in single player std::uniform_int_distribution dist_a_b(a, b); return dist_a_b(gStdRandom); } -int GetDataVal(spritetype* pSprite, int data) { - assert(xspriRangeIsFine(pSprite->extra)); +static int GetDataVal(DBloodActor* actor, int data) +{ + if (!actor->hasX()) return -1; switch (data) { - case 0: return xsprite[pSprite->extra].data1; - case 1: return xsprite[pSprite->extra].data2; - case 2: return xsprite[pSprite->extra].data3; - case 3: return xsprite[pSprite->extra].data4; + case 0: return actor->x().data1; + case 1: return actor->x().data2; + case 2: return actor->x().data3; + case 3: return actor->x().data4; } return -1; } +//--------------------------------------------------------------------------- +// // tries to get random data field of sprite -int randomGetDataValue(XSPRITE* pXSprite, int randType) { - if (pXSprite == NULL) return -1; +// +//--------------------------------------------------------------------------- + +static int randomGetDataValue(DBloodActor* actor, int randType) +{ + if (actor == NULL || !actor->hasX()) return -1; + auto pXSprite = &actor->x(); int random = 0; int bad = 0; int maxRetries = kMaxRandomizeRetries; int rData[4]; rData[0] = pXSprite->data1; rData[2] = pXSprite->data3; rData[1] = pXSprite->data2; rData[3] = pXSprite->data4; // randomize only in case if at least 2 data fields fits. - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) + { switch (randType) { case kRandomizeItem: if (rData[i] >= kItemWeaponBase && rData[i] < kItemMax) break; @@ -908,9 +998,11 @@ int randomGetDataValue(XSPRITE* pXSprite, int randType) { } } - if (bad < 3) { + if (bad < 3) + { // try randomize few times - while (maxRetries > 0) { + while (maxRetries > 0) + { random = nnExtRandom(0, 3); if (rData[random] > 0) return rData[random]; else maxRetries--; @@ -920,30 +1012,38 @@ int randomGetDataValue(XSPRITE* pXSprite, int randType) { return -1; } +//--------------------------------------------------------------------------- +// // this function drops random item using random pickup generator(s) -spritetype* randomDropPickupObject(spritetype* pSource, short prevItem) -{ - auto actor = &bloodActors[pSource->index]; +// +//--------------------------------------------------------------------------- - spritetype* pSprite2 = NULL; int selected = -1; int maxRetries = 9; - if (xspriRangeIsFine(pSource->extra)) { - XSPRITE* pXSource = &xsprite[pSource->extra]; - while ((selected = randomGetDataValue(pXSource, kRandomizeItem)) == prevItem) if (maxRetries-- <= 0) break; +static DBloodActor* randomDropPickupObject(DBloodActor* sourceactor, int prevItem) +{ + DBloodActor* spawned = nullptr; + int selected = -1; + int maxRetries = 9; + if (sourceactor->hasX()) + { + auto pSource = &sourceactor->s(); + XSPRITE* pXSource = &sourceactor->x(); + while ((selected = randomGetDataValue(sourceactor, kRandomizeItem)) == prevItem) if (maxRetries-- <= 0) break; if (selected > 0) { - DBloodActor* spawned = actDropObject(actor, selected); - if (spawned) { - pSprite2 = &spawned->s(); + spawned = actDropObject(sourceactor, selected); + if (spawned) + { + auto pSprite2 = &spawned->s(); pXSource->dropMsg = uint8_t(pSprite2->type); // store dropped item type in dropMsg pSprite2->x = pSource->x; pSprite2->y = pSource->y; pSprite2->z = pSource->z; - if ((pSource->flags & kModernTypeFlag1) && (pXSource->txID > 0 || (pXSource->txID != 3 && pXSource->lockMsg > 0)) && - dbInsertXSprite(pSprite2->index) > 0) { - - XSPRITE* pXSprite2 = &xsprite[pSprite2->extra]; + if ((pSource->flags & kModernTypeFlag1) && (pXSource->txID > 0 || (pXSource->txID != 3 && pXSource->lockMsg > 0))) + { + spawned->addX(); + XSPRITE* pXSprite2 = &spawned->x(); // inherit spawn sprite trigger settings, so designer can send command when item picked up. pXSprite2->txID = pXSource->txID; @@ -957,135 +1057,142 @@ spritetype* randomDropPickupObject(spritetype* pSource, short prevItem) } } } - return pSprite2; + return spawned; } +//--------------------------------------------------------------------------- +// // this function spawns random dude using dudeSpawn -spritetype* randomSpawnDude(XSPRITE* pXSource, spritetype* pSprite, int a3, int a4) -{ - spritetype* pSprite2 = NULL; int selected = -1; - - if ((selected = randomGetDataValue(pXSource, kRandomizeDude)) > 0) - pSprite2 = nnExtSpawnDude(pXSource, pSprite, selected, a3, 0); +// +//--------------------------------------------------------------------------- - return pSprite2; +DBloodActor* randomSpawnDude(DBloodActor* sourceactor, DBloodActor* origin, int a3, int a4) +{ + DBloodActor* spawned = NULL; int selected = -1; + + if ((selected = randomGetDataValue(sourceactor, kRandomizeDude)) > 0) + spawned = nnExtSpawnDude(sourceactor, origin, selected, a3, 0); + + return spawned; } -//------------------------- -void windGenDoVerticalWind(XSPRITE* pXSource, int nSector) { +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- - - //spritetype* pSource = &sprite[pXSource->reference]; - int j, val, maxZ, zdiff; bool maxZfound = false; +static void windGenDoVerticalWind(int factor, int nSector) +{ + int val, maxZ, zdiff; bool maxZfound = false; // find maxz marker first - for (j = headspritesect[nSector]; j != -1; j = nextspritesect[j]) { - if (sprite[j].type == kMarkerOn && sprite[j].statnum != kStatMarker) { - - maxZ = sprite[j].z; + BloodSectIterator it(nSector); + while (auto actor = it.Next()) + { + auto sp = &actor->s(); + if (sp->type == kMarkerOn && sp->statnum != kStatMarker) + { + maxZ = sp->z; maxZfound = true; break; - } } - - for (j = headspritesect[nSector]; j != -1; j = nextspritesect[j]) { - - spritetype* pSpr = &sprite[j]; - - switch (pSpr->statnum) { + it.Reset(nSector); + while (auto actor = it.Next()) + { + auto pSpr = &actor->s(); + switch (pSpr->statnum) + { case kStatFree: continue; case kStatFX: - if (zvel[pSpr->index]) break; + if (actor->zvel()) break; continue; case kStatThing: case kStatDude: if (pSpr->flags & kPhysGravity) break; continue; default: - if (pSpr->extra > 0 && xsprite[pSpr->extra].physAttr & kPhysGravity) break; + if (actor->hasX() && actor->x().physAttr & kPhysGravity) break; continue; } - - if (maxZfound && pSpr->z <= maxZ) { - + if (maxZfound && pSpr->z <= maxZ) + { zdiff = pSpr->z - maxZ; - if (zvel[pSpr->index] < 0) zvel[pSpr->index] += MulScale(zvel[pSpr->index] >> 4, zdiff, 16); + if (actor->zvel() < 0) actor->zvel() += MulScale(actor->zvel() >> 4, zdiff, 16); continue; } - val = -MulScale(pXSource->sysData2 * 64, 0x10000, 16); - if (zvel[pSpr->index] >= 0) zvel[pSpr->index] += val; - else zvel[pSpr->index] = val; + val = -MulScale(factor * 64, 0x10000, 16); + if (actor->zvel() >= 0) actor->zvel() += val; + else actor->zvel() = val; - pSpr->z += zvel[pSpr->index] >> 12; + pSpr->z += actor->zvel() >> 12; } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- -void nnExtProcessSuperSprites() { - +void nnExtProcessSuperSprites() +{ // process tracking conditions - if (gTrackingCondsCount > 0) { - for (int i = 0; i < gTrackingCondsCount; i++) { - - TRCONDITION* pCond = &gCondition[i]; XSPRITE* pXCond = &xsprite[pCond->xindex]; + if (gTrackingCondsCount > 0) + { + for (int i = 0; i < gTrackingCondsCount; i++) + { + TRCONDITION* pCond = &gCondition[i]; + XSPRITE* pXCond = &pCond->actor->x(); if (pXCond->locked || pXCond->isTriggered || ++pXCond->busy < pXCond->busyTime) continue; - if (pXCond->data1 >= kCondGameBase && pXCond->data1 < kCondGameMax) { - + if (pXCond->data1 >= kCondGameBase && pXCond->data1 < kCondGameMax) + { EVENT evn; evn.index_ = 0; - evn.actor = &bloodActors[pXCond->reference]; + evn.actor = pCond->actor; evn.cmd = (int8_t)pXCond->command; evn.type = OBJ_SPRITE; evn.funcID = kCallbackMax; - useCondition(&sprite[pXCond->reference], pXCond, evn); - - } else if (pCond->length > 0) { - + useCondition(&pCond->actor->s(), pXCond, evn); + } + else if (pCond->length > 0) + { pXCond->busy = 0; - for (unsigned k = 0; k < pCond->length; k++) { - + for (unsigned k = 0; k < pCond->length; k++) + { EVENT evn; - // temporary mess. - if (pCond->obj[k].type == OBJ_SPRITE) - { - evn.actor = &bloodActors[pCond->obj[k].type]; - evn.index_ = 0; - } - else - { - evn.actor = nullptr; - evn.index_ = pCond->obj[k].index; - } + evn.actor = pCond->obj[k].actor; + evn.index_ = pCond->obj[k].index_; evn.cmd = pCond->obj[k].cmd; - evn.type = pCond->obj[k].type; + evn.type = pCond->obj[k].type; evn.funcID = kCallbackMax; - useCondition(&sprite[pXCond->reference], pXCond, evn); - + useCondition(&pCond->actor->s(), pXCond, evn); } - } } } // process floor oriented kModernWindGenerator to create a vertical wind in the sectors - for (int i = headspritestat[kStatModernWindGen]; i != -1; i = nextspritestat[i]) { - - spritetype* pWind = &sprite[i]; - if (!(pWind->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR) || pWind->statnum >= kMaxStatus || pWind->extra <= 0) + BloodStatIterator it(kStatModernWindGen); + while (auto windactor = it.Next()) + { + + spritetype* pWind = &windactor->s(); + if (!(pWind->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR) || pWind->statnum >= kMaxStatus || !windactor->hasX()) continue; - XSPRITE* pXWind = &xsprite[pWind->extra]; + XSPRITE* pXWind = &windactor->x(); if (!pXWind->state || pXWind->locked) continue; @@ -1093,43 +1200,49 @@ void nnExtProcessSuperSprites() { bool fWindAlways = (pWind->flags & kModernTypeFlag1); if (pXWind->txID) { - + rx = pXWind->txID; - for (j = bucketHead[rx]; j < bucketHead[rx + 1]; j++) { + for (j = bucketHead[rx]; j < bucketHead[rx + 1]; j++) + { if (rxBucket[j].type != OBJ_SECTOR) continue; - XSECTOR* pXSector = &xsector[sector[rxBucket[j].rxindex].extra]; + int index = rxBucket[j].rxindex; + XSECTOR* pXSector = &xsector[sector[index].extra]; if ((!pXSector->locked) && (fWindAlways || pXSector->windAlways || pXSector->busy)) - windGenDoVerticalWind(pXWind, rxBucket[j].rxindex); + windGenDoVerticalWind(pXWind->sysData2, index); } XSPRITE* pXRedir = NULL; // check redirected TX buckets - while ((pXRedir = evrListRedirectors(OBJ_SPRITE, sprite[pXWind->reference].extra, pXRedir, &rx)) != NULL) { - for (j = bucketHead[rx]; j < bucketHead[rx + 1]; j++) { + while ((pXRedir = evrListRedirectors(OBJ_SPRITE, sprite[pXWind->reference].extra, pXRedir, &rx)) != NULL) + { + for (j = bucketHead[rx]; j < bucketHead[rx + 1]; j++) + { if (rxBucket[j].type != OBJ_SECTOR) continue; - XSECTOR* pXSector = &xsector[sector[rxBucket[j].rxindex].extra]; + int index = rxBucket[j].rxindex; + XSECTOR* pXSector = &xsector[sector[index].extra]; if ((!pXSector->locked) && (fWindAlways || pXSector->windAlways || pXSector->busy)) - windGenDoVerticalWind(pXWind, rxBucket[j].rxindex); + windGenDoVerticalWind(pXWind->sysData2, index); } } - } else if (sectRangeIsFine(pWind->sectnum)) { - + } + else if (sectRangeIsFine(pWind->sectnum)) + { sectortype* pSect = §or[pWind->sectnum]; XSECTOR* pXSector = (pSect->extra > 0) ? &xsector[pSect->extra] : NULL; if ((fWindAlways) || (pXSector && !pXSector->locked && (pXSector->windAlways || pXSector->busy))) - windGenDoVerticalWind(pXWind, pWind->sectnum); - + windGenDoVerticalWind(pXWind->sysData2, pWind->sectnum); } - } // process additional proximity sprites - if (gProxySpritesCount > 0) { - for (int i = 0; i < gProxySpritesCount; i++) { + if (gProxySpritesCount > 0) + { + for (int i = 0; i < gProxySpritesCount; i++) + { if (!gProxySpritesList[i] || !gProxySpritesList[i]->hasX()) continue; auto const pProxSpr = &gProxySpritesList[i]->s(); @@ -1137,47 +1250,48 @@ void nnExtProcessSuperSprites() { if (!pXProxSpr->Proximity || (!pXProxSpr->Interrutable && pXProxSpr->state != pXProxSpr->restState) || pXProxSpr->locked == 1 || pXProxSpr->isTriggered) continue; // don't process locked or triggered sprites - int okDist = (IsDudeSprite(pProxSpr)) ? 96 : ClipLow(pProxSpr->clipdist * 3, 32); + int okDist = (gProxySpritesList[i]->IsDudeActor()) ? 96 : ClipLow(pProxSpr->clipdist * 3, 32); int x = pProxSpr->x; int y = pProxSpr->y; int z = pProxSpr->z; int sectnum = pProxSpr->sectnum; - if (!pXProxSpr->DudeLockout) { - - int nAffected; - StatIterator it(kStatDude); - while ((nAffected = it.NextIndex()) >= 0) + if (!pXProxSpr->DudeLockout) + { + BloodStatIterator it(kStatDude); + while (auto affected = it.Next()) { - if (!xsprIsFine(&sprite[nAffected]) || xsprite[sprite[nAffected].extra].health <= 0) continue; - else if (CheckProximity(&sprite[nAffected], x, y, z, sectnum, okDist)) { + if (!affected->hasX() || affected->x().health <= 0) continue; + else if (CheckProximity(&affected->s(), x, y, z, sectnum, okDist)) + { trTriggerSprite(gProxySpritesList[i], kCmdSpriteProximity); break; } } - - } else { - - for (int a = connecthead; a >= 0; a = connectpoint2[a]) { - + } + else + { + for (int a = connecthead; a >= 0; a = connectpoint2[a]) + { PLAYER* pPlayer = &gPlayer[a]; - if (!pPlayer || !xsprIsFine(pPlayer->pSprite) || pPlayer->pXSprite->health <= 0) + if (!pPlayer || !pPlayer->actor()->hasX() || pPlayer->pXSprite->health <= 0) continue; - if (gPlayer[a].pXSprite->health > 0 && CheckProximity(gPlayer[a].pSprite, x, y, z, sectnum, okDist)) { + if (pPlayer->pXSprite->health > 0 && CheckProximity(gPlayer->pSprite, x, y, z, sectnum, okDist)) + { trTriggerSprite(gProxySpritesList[i], kCmdSpriteProximity); break; } - } - } } } // process sight sprites (for players only) - if (gSightSpritesCount > 0) { - for (int i = 0; i < gSightSpritesCount; i++) { + if (gSightSpritesCount > 0) + { + for (int i = 0; i < gSightSpritesCount; i++) + { if (!gSightSpritesList[i] || !gSightSpritesList[i]->hasX()) continue; auto const pSightSpr = &gSightSpritesList[i]->s(); @@ -1191,7 +1305,7 @@ void nnExtProcessSuperSprites() { // sprite is drawn for one of players if ((pXSightSpr->unused3 & kTriggerSpriteScreen) && (gSightSpritesList[i]->s().cstat2 & CSTAT2_SPRITE_MAPPED)) { - trTriggerSprite(index, pXSightSpr, kCmdSpriteSight); + trTriggerSprite(gSightSpritesList[i], kCmdSpriteSight); gSightSpritesList[i]->s().cstat2 &= ~CSTAT2_SPRITE_MAPPED; continue; } @@ -1202,219 +1316,248 @@ void nnExtProcessSuperSprites() { int sectnum = pSightSpr->sectnum; int ztop2, zbot2; - for (int a = connecthead; a >= 0; a = connectpoint2[a]) { - + for (int a = connecthead; a >= 0; a = connectpoint2[a]) + { PLAYER* pPlayer = &gPlayer[a]; - if (!pPlayer || !xsprIsFine(pPlayer->pSprite) || pPlayer->pXSprite->health <= 0) + if (!pPlayer || !pPlayer->actor()->hasX() || pPlayer->pXSprite->health <= 0) continue; spritetype* pPlaySprite = pPlayer->pSprite; GetSpriteExtents(pPlaySprite, &ztop2, &zbot2); - if (cansee(x, y, z, sectnum, pPlaySprite->x, pPlaySprite->y, ztop2, pPlaySprite->sectnum)) { - - if (pXSightSpr->Sight) { + if (cansee(x, y, z, sectnum, pPlaySprite->x, pPlaySprite->y, ztop2, pPlaySprite->sectnum)) + { + if (pXSightSpr->Sight) + { trTriggerSprite(gSightSpritesList[i], kCmdSpriteSight); break; } - if (pXSightSpr->unused3 & kTriggerSpriteAim) { - - + if (pXSightSpr->unused3 & kTriggerSpriteAim) + { bool vector = (sprite[index].cstat & CSTAT_SPRITE_BLOCK_HITSCAN); if (!vector) sprite[index].cstat |= CSTAT_SPRITE_BLOCK_HITSCAN; HitScan(pPlaySprite, pPlayer->zWeapon, pPlayer->aim.dx, pPlayer->aim.dy, pPlayer->aim.dz, CLIPMASK0 | CLIPMASK1, 0); - + //VectorScan(pPlaySprite, 0, pPlayer->zWeapon, pPlayer->aim.dx, pPlayer->aim.dy, pPlayer->aim.dz, 0, 1); if (!vector) sprite[index].cstat &= ~CSTAT_SPRITE_BLOCK_HITSCAN; - if (gHitInfo.hitsprite == index) { + if (gHitInfo.hitsprite == index) + { trTriggerSprite(index, pXSightSpr, kCmdSpriteSight); break; } } - } - } } } // process Debris sprites for movement - if (gPhysSpritesCount > 0) { - for (int i = 0; i < gPhysSpritesCount; i++) { - + if (gPhysSpritesCount > 0) + { + for (int i = 0; i < gPhysSpritesCount; i++) + { auto debrisactor = gPhysSpritesList[i]; if (debrisactor == nullptr || !debrisactor->hasX()) continue; auto const pDebris = &debrisactor->s(); - if (pDebris->statnum == kStatFree || (pDebris->flags & kHitagFree) != 0) { + if (pDebris->statnum == kStatFree || (pDebris->flags & kHitagFree) != 0) + { gPhysSpritesList[i] = nullptr; continue; } XSPRITE* pXDebris = &debrisactor->x(); - if (!(pXDebris->physAttr & kPhysMove) && !(pXDebris->physAttr & kPhysGravity)) { + if (!(pXDebris->physAttr & kPhysMove) && !(pXDebris->physAttr & kPhysGravity)) + { gPhysSpritesList[i] = nullptr; continue; } - int idx = pDebris->index; + int nDebris = pDebris->index; + + XSECTOR* pXSector = (sector[pDebris->sectnum].extra >= 0) ? &xsector[sector[pDebris->sectnum].extra] : nullptr; + viewBackupSpriteLoc(nDebris, pDebris); - XSECTOR* pXSector = (sector[pDebris->sectnum].extra >= 0) ? &xsector[sector[pDebris->sectnum].extra] : NULL; - viewBackupSpriteLoc(idx, pDebris); - bool uwater = false; int mass = debrisactor->spriteMass.mass; int airVel = debrisactor->spriteMass.airVel; - int top, bottom; - GetSpriteExtents(pDebris, &top, &bottom); + int top, bottom; + GetActorExtents(debrisactor, &top, &bottom); - if (pXSector != NULL) { - + if (pXSector != nullptr) + { if ((uwater = pXSector->Underwater) != 0) airVel <<= 6; - if (pXSector->panVel != 0 && getflorzofslope(pDebris->sectnum, pDebris->x, pDebris->y) <= bottom) { - + if (pXSector->panVel != 0 && getflorzofslope(pDebris->sectnum, pDebris->x, pDebris->y) <= bottom) + { int angle = pXSector->panAngle; int speed = 0; - if (pXSector->panAlways || pXSector->state || pXSector->busy) { - speed = pXSector->panVel << 9; - if (!pXSector->panAlways && pXSector->busy) - speed = MulScale(speed, pXSector->busy, 16); - } - if (sector[pDebris->sectnum].floorstat & 64) - angle = (angle + GetWallAngle(sector[pDebris->sectnum].wallptr) + 512) & 2047; - int dx = MulScale(speed, Cos(angle), 30); - int dy = MulScale(speed, Sin(angle), 30); - xvel[idx] += dx; - yvel[idx] += dy; - + if (pXSector->panAlways || pXSector->state || pXSector->busy) + { + speed = pXSector->panVel << 9; + if (!pXSector->panAlways && pXSector->busy) + speed = MulScale(speed, pXSector->busy, 16); } - + if (sector[pDebris->sectnum].floorstat & 64) + angle = (angle + GetWallAngle(sector[pDebris->sectnum].wallptr) + 512) & 2047; + int dx = MulScale(speed, Cos(angle), 30); + int dy = MulScale(speed, Sin(angle), 30); + debrisactor->xvel() += dx; + debrisactor->yvel() += dy; } + } actAirDrag(&bloodActors[pDebris->index], airVel); - if (pXDebris->physAttr & kPhysDebrisTouch) { + if (pXDebris->physAttr & kPhysDebrisTouch) + { PLAYER* pPlayer = NULL; - for (int a = connecthead; a != -1; a = connectpoint2[a]) { + for (int a = connecthead; a != -1; a = connectpoint2[a]) + { pPlayer = &gPlayer[a]; - if ((gSpriteHit[pPlayer->pSprite->extra].hit & 0xc000) == 0xc000 && (gSpriteHit[pPlayer->pSprite->extra].hit & 0x3fff) == idx) { - - int nSpeed = approxDist(xvel[pPlayer->pSprite->index], yvel[pPlayer->pSprite->index]); + auto pact = pPlayer->actor(); + if (pact->hit().hit.type == kHitSprite && pact->hit().hit.index == nDebris) + { + int nSpeed = approxDist(pact->xvel(), pact->yvel()); nSpeed = ClipLow(nSpeed - MulScale(nSpeed, mass, 6), 0x9000 - (mass << 3)); - xvel[idx] += MulScale(nSpeed, Cos(pPlayer->pSprite->ang), 30); - yvel[idx] += MulScale(nSpeed, Sin(pPlayer->pSprite->ang), 30); - - gSpriteHit[pDebris->extra].hit = pPlayer->pSprite->index | 0xc000; + debrisactor->xvel() += MulScale(nSpeed, Cos(pPlayer->pSprite->ang), 30); + debrisactor->yvel() += MulScale(nSpeed, Sin(pPlayer->pSprite->ang), 30); + debrisactor->hit().hit = pPlayer->pSprite->index | 0xc000; } } } if (pXDebris->physAttr & kPhysGravity) pXDebris->physAttr |= kPhysFalling; - if ((pXDebris->physAttr & kPhysFalling) || xvel[idx] || yvel[idx] || zvel[idx] || velFloor[pDebris->sectnum] || velCeil[pDebris->sectnum]) + if ((pXDebris->physAttr & kPhysFalling) || debrisactor->xvel() || debrisactor->yvel() || debrisactor->zvel() || velFloor[pDebris->sectnum] || velCeil[pDebris->sectnum]) debrisMove(i); - if (xvel[idx] || yvel[idx]) - pXDebris->goalAng = getangle(xvel[idx], yvel[idx]) & 2047; + if (debrisactor->xvel() || debrisactor->yvel()) + pXDebris->goalAng = getangle(debrisactor->xvel(), debrisactor->yvel()) & 2047; int ang = pDebris->ang & 2047; if ((uwater = spriteIsUnderwater(debrisactor)) == false) evKillActor(debrisactor, kCallbackEnemeyBubble); - else if (Chance(0x1000 - mass)) { - - if (zvel[idx] > 0x100) debrisBubble(idx); - if (ang == pXDebris->goalAng) { + else if (Chance(0x1000 - mass)) + { + if (debrisactor->zvel() > 0x100) debrisBubble(debrisactor); + if (ang == pXDebris->goalAng) + { pXDebris->goalAng = (pDebris->ang + Random3(kAng60)) & 2047; - debrisBubble(idx); + debrisBubble(debrisactor); } - } - int angStep = ClipLow(mulscale8(1, ((abs(xvel[idx]) + abs(yvel[idx])) >> 5)), (uwater) ? 1 : 0); + int angStep = ClipLow(mulscale8(1, ((abs(debrisactor->xvel()) + abs(debrisactor->yvel())) >> 5)), (uwater) ? 1 : 0); if (ang < pXDebris->goalAng) pDebris->ang = ClipHigh(ang + angStep, pXDebris->goalAng); else if (ang > pXDebris->goalAng) pDebris->ang = ClipLow(ang - angStep, pXDebris->goalAng); int nSector = pDebris->sectnum; int cz = getceilzofslope(nSector, pDebris->x, pDebris->y); int fz = getflorzofslope(nSector, pDebris->x, pDebris->y); - - GetSpriteExtents(pDebris, &top, &bottom); + + GetActorExtents(debrisactor, &top, &bottom); if (fz >= bottom && gLowerLink[nSector] < 0 && !(sector[nSector].ceilingstat & 0x1)) pDebris->z += ClipLow(cz - top, 0); if (cz <= top && gUpperLink[nSector] < 0 && !(sector[nSector].floorstat & 0x1)) pDebris->z += ClipHigh(fz - bottom, 0); - } } - } +//--------------------------------------------------------------------------- +// // this function plays sound predefined in missile info -void sfxPlayMissileSound(spritetype* pSprite, int missileId) { +// +//--------------------------------------------------------------------------- + +void sfxPlayMissileSound(DBloodActor* actor, int missileId) +{ const MISSILEINFO_EXTRA* pMissType = &gMissileInfoExtra[missileId - kMissileBase]; - sfxPlay3DSound(pSprite, Chance(0x5000) ? pMissType->fireSound[0] : pMissType->fireSound[1], -1, 0); + sfxPlay3DSound(actor, Chance(0x5000) ? pMissType->fireSound[0] : pMissType->fireSound[1], -1, 0); } +//--------------------------------------------------------------------------- +// // this function plays sound predefined in vector info -void sfxPlayVectorSound(spritetype* pSprite, int vectorId) { +// +//--------------------------------------------------------------------------- + +void sfxPlayVectorSound(DBloodActor* actor, int vectorId) +{ const VECTORINFO_EXTRA* pVectorData = &gVectorInfoExtra[vectorId]; - sfxPlay3DSound(pSprite, Chance(0x5000) ? pVectorData->fireSound[0] : pVectorData->fireSound[1], -1, 0); + sfxPlay3DSound(actor, Chance(0x5000) ? pVectorData->fireSound[0] : pVectorData->fireSound[1], -1, 0); } -int getSpriteMassBySize(spritetype* pSprite) { - auto actor = &bloodActors[pSprite->index]; +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int getSpriteMassBySize(DBloodActor* actor) +{ + auto pSprite = &actor->s(); int mass = 0; int seqId = -1; int clipDist = pSprite->clipdist; Seq* pSeq = NULL; - if (pSprite->extra < 0) { + if (!actor->hasX()) + { I_Error("getSpriteMassBySize: pSprite->extra < 0"); - - } else if (IsDudeSprite(pSprite)) { - - switch (pSprite->type) { + } + else if (actor->IsDudeActor()) + { + switch (pSprite->type) + { case kDudePodMother: // fake dude, no seq break; case kDudeModernCustom: case kDudeModernCustomBurning: - seqId = xsprite[pSprite->extra].data2; - clipDist = gGenDudeExtra[pSprite->index].initVals[2]; + seqId = actor->x().data2; + clipDist = actor->genDudeExtra().initVals[2]; break; default: seqId = getDudeInfo(pSprite->type)->seqStartID; break; } - - } else { - + } + else + { seqId = seqGetID(3, pSprite->extra); - } SPRITEMASS* cached = &actor->spriteMass; if (((seqId >= 0 && seqId == cached->seqId) || pSprite->picnum == cached->picnum) && pSprite->xrepeat == cached->xrepeat && - pSprite->yrepeat == cached->yrepeat && clipDist == cached->clipdist) { + pSprite->yrepeat == cached->yrepeat && clipDist == cached->clipdist) + { return cached->mass; } - short picnum = pSprite->picnum; - short massDiv = 30; short addMul = 2; short subMul = 2; + int picnum = pSprite->picnum; + int massDiv = 30; + int addMul = 2; + int subMul = 2; - if (seqId >= 0) { + if (seqId >= 0) + { auto pSeq = getSequence(seqId); if (pSeq) { picnum = seqGetTile(&pSeq->frames[0]); - } else + } + else picnum = pSprite->picnum; } clipDist = ClipLow(pSprite->clipdist, 1); - short x = tileWidth(picnum); short y = tileHeight(picnum); - short xrepeat = pSprite->xrepeat; short yrepeat = pSprite->yrepeat; + int x = tileWidth(picnum); + int y = tileHeight(picnum); + int xrepeat = pSprite->xrepeat; + int yrepeat = pSprite->yrepeat; // take surface type into account - switch (tileGetSurfType(pSprite->index + 0xc000)) { + switch (tileGetSurfType(pSprite->picnum)) + { case 1: massDiv = 16; break; // stone case 2: massDiv = 18; break; // metal case 3: massDiv = 21; break; // wood @@ -1434,9 +1577,12 @@ int getSpriteMassBySize(spritetype* pSprite) { mass = ((x + y) * (clipDist / 2)) / massDiv; if (xrepeat > 64) mass += ((xrepeat - 64) * addMul); - else if (xrepeat < 64 && mass > 0) { - for (int i = 64 - xrepeat; i > 0; i--) { - if ((mass -= subMul) <= 100 && subMul-- <= 1) { + else if (xrepeat < 64 && mass > 0) + { + for (int i = 64 - xrepeat; i > 0; i--) + { + if ((mass -= subMul) <= 100 && subMul-- <= 1) + { mass -= i; break; } @@ -1444,9 +1590,12 @@ int getSpriteMassBySize(spritetype* pSprite) { } if (yrepeat > 64) mass += ((yrepeat - 64) * addMul); - else if (yrepeat < 64 && mass > 0) { - for (int i = 64 - yrepeat; i > 0; i--) { - if ((mass -= subMul) <= 100 && subMul-- <= 1) { + else if (yrepeat < 64 && mass > 0) + { + for (int i = 64 - yrepeat; i > 0; i--) + { + if ((mass -= subMul) <= 100 && subMul-- <= 1) + { mass -= i; break; } @@ -1459,27 +1608,39 @@ int getSpriteMassBySize(spritetype* pSprite) { cached->airVel = ClipRange(400 - cached->mass, 32, 400); cached->fraction = ClipRange(60000 - (cached->mass << 7), 8192, 60000); - cached->xrepeat = pSprite->xrepeat; cached->yrepeat = pSprite->yrepeat; - cached->picnum = pSprite->picnum; cached->seqId = seqId; + cached->xrepeat = pSprite->xrepeat; + cached->yrepeat = pSprite->yrepeat; + cached->picnum = pSprite->picnum; + cached->seqId = seqId; cached->clipdist = pSprite->clipdist; return cached->mass; } -int debrisGetIndex(int nSprite) { - if (sprite[nSprite].extra < 0 || xsprite[sprite[nSprite].extra].physAttr == 0) +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static int debrisGetIndex(DBloodActor* actor) +{ + if (!actor->hasX() || actor->x().physAttr == 0) return -1; - for (int i = 0; i < gPhysSpritesCount; i++) { - if (gPhysSpritesList[i] != &bloodActors[nSprite]) continue; + for (int i = 0; i < gPhysSpritesCount; i++) + { + if (gPhysSpritesList[i] != actor) continue; return i; } return -1; } -int debrisGetFreeIndex(void) { - for (int i = 0; i < kMaxSuperXSprites; i++) { +int debrisGetFreeIndex(void) +{ + for (int i = 0; i < kMaxSuperXSprites; i++) + { if (gPhysSpritesList[i] == nullptr) return i; auto spr = &gPhysSpritesList[i]->s(); if (spr->statnum == kStatFree) return i; @@ -1491,9 +1652,14 @@ int debrisGetFreeIndex(void) { return -1; } -void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg) +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void debrisConcuss(DBloodActor* owner, int listIndex, int x, int y, int z, int dmg) { - auto owner = &bloodActors[nOwner]; auto actor = gPhysSpritesList[listIndex]; if (actor != nullptr && actor->hasX()) { @@ -1502,14 +1668,15 @@ void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg) dmg = scale(0x40000, dmg, 0x40000 + dx * dx + dy * dy + dz * dz); bool thing = (pSprite->type >= kThingBase && pSprite->type < kThingMax); int size = (tileWidth(pSprite->picnum) * pSprite->xrepeat * tileHeight(pSprite->picnum) * pSprite->yrepeat) >> 1; - if (xsprite[pSprite->extra].physAttr & kPhysDebrisExplode) { + if (xsprite[pSprite->extra].physAttr & kPhysDebrisExplode) + { if (actor->spriteMass.mass > 0) { int t = scale(dmg, size, actor->spriteMass.mass); - xvel[pSprite->index] += MulScale(t, dx, 16); - yvel[pSprite->index] += MulScale(t, dy, 16); - zvel[pSprite->index] += MulScale(t, dz, 16); + actor->xvel() += MulScale(t, dx, 16); + actor->yvel() += MulScale(t, dy, 16); + actor->zvel() += MulScale(t, dz, 16); } if (thing) @@ -1523,11 +1690,16 @@ void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg) } } -void debrisBubble(int nSprite) +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void debrisBubble(DBloodActor* actor) { + spritetype* pSprite = &actor->s(); - spritetype* pSprite = &sprite[nSprite]; - int top, bottom; GetSpriteExtents(pSprite, &top, &bottom); for (unsigned int i = 0; i < 1 + Random(5); i++) { @@ -1539,18 +1711,24 @@ void debrisBubble(int nSprite) int z = bottom - Random(bottom - top); auto pFX = gFX.fxSpawnActor((FX_ID)(FX_23 + Random(3)), pSprite->sectnum, x, y, z, 0); if (pFX) { - pFX->xvel() = xvel[nSprite] + Random2(0x1aaaa); - pFX->yvel() = yvel[nSprite] + Random2(0x1aaaa); - pFX->zvel() = zvel[nSprite] + Random2(0x1aaaa); + pFX->xvel() = actor->xvel() + Random2(0x1aaaa); + pFX->yvel() = actor->yvel() + Random2(0x1aaaa); + pFX->zvel() = actor->zvel() + Random2(0x1aaaa); } } if (Chance(0x2000)) - evPostActor(&bloodActors[nSprite], 0, kCallbackEnemeyBubble); + evPostActor(actor, 0, kCallbackEnemeyBubble); } -void debrisMove(int listIndex) +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void debrisMove(int listIndex) { auto actor = gPhysSpritesList[listIndex]; XSPRITE* pXSprite = &actor->x(); @@ -1572,7 +1750,8 @@ void debrisMove(int listIndex) int top, bottom, i; GetActorExtents(actor, &top, &bottom); - int moveHit = 0; + Collision moveHit; + moveHit.setNone(); int floorDist = (bottom - pSprite->z) >> 2; int ceilDist = (pSprite->z - top) >> 2; int clipDist = pSprite->clipdist << 2; @@ -1580,60 +1759,68 @@ void debrisMove(int listIndex) bool uwater = false; int tmpFraction = actor->spriteMass.fraction; - if (sector[nSector].extra >= 0 && xsector[sector[nSector].extra].Underwater) { + if (sector[nSector].extra >= 0 && xsector[sector[nSector].extra].Underwater) + { tmpFraction >>= 1; uwater = true; } - int nSprite = pSprite->index; - int nXSprite = pSprite->extra; - if (xvel[nSprite] || yvel[nSprite]) { + if (actor->xvel() || actor->yvel()) + { short oldcstat = pSprite->cstat; pSprite->cstat &= ~(CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); - moveHit = gSpriteHit[nXSprite].hit = ClipMove((int*)&pSprite->x, (int*)&pSprite->y, (int*)&pSprite->z, &nSector, xvel[nSprite] >> 12, - yvel[nSprite] >> 12, clipDist, ceilDist, floorDist, CLIPMASK0); + moveHit = actor->hit().hit = ClipMove(&pSprite->pos, &nSector, actor->xvel() >> 12, + actor->yvel() >> 12, clipDist, ceilDist, floorDist, CLIPMASK0); pSprite->cstat = oldcstat; - if (pSprite->sectnum != nSector) { + if (pSprite->sectnum != nSector) + { if (!sectRangeIsFine(nSector)) return; - else ChangeSpriteSect(nSprite, nSector); + else ChangeActorSect(actor, nSector); } - if (sector[nSector].type >= kSectorPath && sector[nSector].type <= kSectorRotate) { - short nSector2 = nSector; - if (pushmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector2, clipDist, ceilDist, floorDist, CLIPMASK0) != -1) + if (sector[nSector].type >= kSectorPath && sector[nSector].type <= kSectorRotate) + { + int nSector2 = nSector; + if (pushmove(&pSprite->pos, &nSector2, clipDist, ceilDist, floorDist, CLIPMASK0) != -1) nSector = nSector2; } - if ((gSpriteHit[nXSprite].hit & 0xc000) == 0x8000) { - i = moveHit = gSpriteHit[nXSprite].hit & 0x3fff; - actWallBounceVector((int*)&xvel[nSprite], (int*)&yvel[nSprite], i, tmpFraction); + if (actor->hit().hit.type == kHitWall) + { + moveHit = actor->hit().hit; + i = moveHit.index; + actWallBounceVector(&actor->xvel(), &actor->yvel(), i, tmpFraction); } - } else if (!FindSector(pSprite->x, pSprite->y, pSprite->z, &nSector)) { + } + else if (!FindSector(pSprite->x, pSprite->y, pSprite->z, &nSector)) + { return; } - if (pSprite->sectnum != nSector) { + if (pSprite->sectnum != nSector) + { assert(nSector >= 0 && nSector < kMaxSectors); - ChangeSpriteSect(nSprite, nSector); + ChangeActorSect(actor, nSector); nSector = pSprite->sectnum; } if (sector[nSector].extra > 0) uwater = xsector[sector[nSector].extra].Underwater; - if (zvel[nSprite]) - pSprite->z += zvel[nSprite] >> 8; + if (actor->zvel()) + pSprite->z += actor->zvel() >> 8; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); GetSpriteExtents(pSprite, &top, &bottom); - if ((pXSprite->physAttr & kPhysDebrisSwim) && uwater) { - + if ((pXSprite->physAttr & kPhysDebrisSwim) && uwater) + { int vc = 0; int cz = getceilzofslope(nSector, pSprite->x, pSprite->y); int fz = getflorzofslope(nSector, pSprite->x, pSprite->y); @@ -1641,36 +1828,45 @@ void debrisMove(int listIndex) if (gLowerLink[nSector] >= 0) cz += (cz < 0) ? 0x500 : -0x500; if (top > cz && (!(pXSprite->physAttr & kPhysDebrisFloat) || fz <= bottom << 2)) - zvel[nSprite] -= DivScale((bottom - ceilZ) >> 6, mass, 8); + actor->zvel() -= DivScale((bottom - ceilZ) >> 6, mass, 8); if (fz < bottom) vc = 58254 + ((bottom - fz) * -80099) / div; - if (vc) { + if (vc) + { pSprite->z += ((vc << 2) >> 1) >> 8; - zvel[nSprite] += vc; + actor->zvel() += vc; } - } else if ((pXSprite->physAttr & kPhysGravity) && bottom < floorZ) { - + } + else if ((pXSprite->physAttr & kPhysGravity) && bottom < floorZ) + { pSprite->z += 455; - zvel[nSprite] += 58254; + actor->zvel() += 58254; } - if ((i = CheckLink(pSprite)) != 0) { - GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); - if (!(pSprite->cstat & CSTAT_SPRITE_INVISIBLE)) { - switch (i) { + if ((i = CheckLink(pSprite)) != 0) + { + GetZRange(pSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, clipDist, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); + if (!(pSprite->cstat & CSTAT_SPRITE_INVISIBLE)) + { + switch (i) + { case kMarkerUpWater: case kMarkerUpGoo: int pitch = (150000 - (actor->spriteMass.mass << 9)) + Random3(8192); sfxPlay3DSoundCP(pSprite, 720, -1, 0, pitch, 75 - Random(40)); - if (!spriteIsUnderwater(actor)) { + if (!spriteIsUnderwater(actor)) + { evKillActor(actor, kCallbackEnemeyBubble); - } else { + } + else + { evPostActor(actor, 0, kCallbackEnemeyBubble); - for (int i = 2; i <= 5; i++) { + for (int i = 2; i <= 5; i++) + { if (Chance(0x5000 * i)) evPostActor(actor, Random(5), kCallbackEnemeyBubble); } @@ -1680,30 +1876,33 @@ void debrisMove(int listIndex) } } - GetSpriteExtents(pSprite, &top, &bottom); + GetActorExtents(actor, &top, &bottom); if (floorZ <= bottom) { - gSpriteHit[nXSprite].florhit = floorHit; - int v30 = zvel[nSprite] - velFloor[pSprite->sectnum]; - - if (v30 > 0) { + actor->hit().florhit = floorColl; + int v30 = actor->zvel() - velFloor[pSprite->sectnum]; + if (v30 > 0) + { pXSprite->physAttr |= kPhysFalling; - actFloorBounceVector((int*)&xvel[nSprite], (int*)&yvel[nSprite], (int*)&v30, pSprite->sectnum, tmpFraction); - zvel[nSprite] = v30; + actFloorBounceVector(&actor->xvel(), &actor->yvel(), &v30, pSprite->sectnum, tmpFraction); + actor->zvel() = v30; - if (abs(zvel[nSprite]) < 0x10000) { - zvel[nSprite] = velFloor[pSprite->sectnum]; + if (abs(actor->zvel()) < 0x10000) + { + actor->zvel() = velFloor[pSprite->sectnum]; pXSprite->physAttr &= ~kPhysFalling; } - moveHit = floorHit; + moveHit = floorColl; DBloodActor* pFX = NULL, *pFX2 = NULL; - switch (tileGetSurfType(floorHit)) { + switch (tileGetSurfType(floorColl)) + { case kSurfLava: if ((pFX = gFX.fxSpawnActor(FX_10, pSprite->sectnum, pSprite->x, pSprite->y, floorZ, 0)) == NULL) break; - for (i = 0; i < 7; i++) { + for (i = 0; i < 7; i++) + { if ((pFX2 = gFX.fxSpawnActor(FX_14, pFX->s().sectnum, pFX->s().x, pFX->s().y, pFX->s().z, 0)) == NULL) continue; pFX2->xvel() = Random2(0x6aaaa); pFX2->yvel() = Random2(0x6aaaa); @@ -1715,52 +1914,51 @@ void debrisMove(int listIndex) break; } - } else if (zvel[nSprite] == 0) { - - pXSprite->physAttr &= ~kPhysFalling; - } - - } else { - - gSpriteHit[nXSprite].florhit = 0; + else if (actor->zvel() == 0) + { + pXSprite->physAttr &= ~kPhysFalling; + } + } + else + { + actor->hit().florhit.setNone(); if (pXSprite->physAttr & kPhysGravity) pXSprite->physAttr |= kPhysFalling; - } - if (top <= ceilZ) { - - gSpriteHit[nXSprite].ceilhit = moveHit = ceilHit; + if (top <= ceilZ) + { + actor->hit().ceilhit = moveHit = ceilColl; pSprite->z += ClipLow(ceilZ - top, 0); - if (zvel[nSprite] <= 0 && (pXSprite->physAttr & kPhysFalling)) - zvel[nSprite] = MulScale(-zvel[nSprite], 0x2000, 16); - - } else { - - gSpriteHit[nXSprite].ceilhit = 0; - GetSpriteExtents(pSprite, &top, &bottom); + if (actor->zvel() <= 0 && (pXSprite->physAttr & kPhysFalling)) + actor->zvel() = MulScale(-actor->zvel(), 0x2000, 16); } + else + { + actor->hit().ceilhit.setNone(); + GetActorExtents(actor, &top, &bottom); + } - if (moveHit && pXSprite->Impact && !pXSprite->locked && !pXSprite->isTriggered && (pXSprite->state == pXSprite->restState || pXSprite->Interrutable)) { + if (moveHit.type != kHitNone && pXSprite->Impact && !pXSprite->locked && !pXSprite->isTriggered && (pXSprite->state == pXSprite->restState || pXSprite->Interrutable)) { if (pSprite->type >= kThingBase && pSprite->type < kThingMax) - changespritestat(nSprite, kStatThing); - - trTriggerSprite(pSprite->index, pXSprite, kCmdToggle); + ChangeActorStat(actor, kStatThing); + trTriggerSprite(actor, kCmdToggle); } - if (!xvel[nSprite] && !yvel[nSprite]) return; - else if ((floorHit & 0xc000) == 0xc000) { + if (!actor->xvel() && !actor->yvel()) return; + else if (floorColl.type == kHitSprite) + { - int nHitSprite = floorHit & 0x3fff; - if ((sprite[nHitSprite].cstat & 0x30) == 0) { - xvel[nSprite] += MulScale(4, pSprite->x - sprite[nHitSprite].x, 2); - yvel[nSprite] += MulScale(4, pSprite->y - sprite[nHitSprite].y, 2); + if ((floorColl.actor->s().cstat & 0x30) == 0) + { + actor->xvel() += MulScale(4, pSprite->x - floorColl.actor->s().x, 2); + actor->yvel() += MulScale(4, pSprite->y - floorColl.actor->s().y, 2); return; - } } + } pXSprite->height = ClipLow(floorZ - bottom, 0) >> 8; if (uwater || pXSprite->height >= 0x100) @@ -1770,33 +1968,42 @@ void debrisMove(int listIndex) if (pXSprite->height > 0) nDrag -= scale(nDrag, pXSprite->height, 0x100); - xvel[nSprite] -= mulscale16r(xvel[nSprite], nDrag); - yvel[nSprite] -= mulscale16r(yvel[nSprite], nDrag); - if (approxDist(xvel[nSprite], yvel[nSprite]) < 0x1000) - xvel[nSprite] = yvel[nSprite] = 0; - + actor->xvel() -= mulscale16r(actor->xvel(), nDrag); + actor->yvel() -= mulscale16r(actor->yvel(), nDrag); + if (approxDist(actor->xvel(), actor->yvel()) < 0x1000) + actor->xvel() = actor->yvel() = 0; } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- - -bool ceilIsTooLow(spritetype* pSprite) { - if (pSprite != NULL) { - - sectortype* pSector = §or[pSprite->sectnum]; +bool ceilIsTooLow(DBloodActor* actor) +{ + if (actor != nullptr) + { + sectortype* pSector = §or[actor->s().sectnum]; int a = pSector->ceilingz - pSector->floorz; int top, bottom; - GetSpriteExtents(pSprite, &top, &bottom); + GetActorExtents(actor, &top, &bottom); int b = top - bottom; if (a > b) return true; } - return false; } -void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void aiSetGenIdleState(DBloodActor* actor) { - auto actor = &bloodActors[pXSprite->reference]; - switch (pSprite->type) { + switch (actor->s().type) + { case kDudeModernCustom: case kDudeModernCustomBurning: aiGenDudeNewState(actor, &genIdle); @@ -1807,27 +2014,39 @@ void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) } } +//--------------------------------------------------------------------------- +// // this function stops wind on all TX sectors affected by WindGen after it goes off state. -void windGenStopWindOnSectors(XSPRITE* pXSource) { - spritetype* pSource = &sprite[pXSource->reference]; - if (pXSource->txID <= 0 && xsectRangeIsFine(sector[pSource->sectnum].extra)) { +// +//--------------------------------------------------------------------------- + +void windGenStopWindOnSectors(DBloodActor* sourceactor) +{ + spritetype* pSource = &sourceactor->s(); + auto pXSource = &sourceactor->x(); + if (pXSource->txID <= 0 && xsectRangeIsFine(sector[pSource->sectnum].extra)) + { xsector[sector[pSource->sectnum].extra].windVel = 0; return; } - for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++) { + for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++) + { if (rxBucket[i].type != OBJ_SECTOR) continue; XSECTOR* pXSector = &xsector[sector[rxBucket[i].rxindex].extra]; if ((pXSector->state == 1 && !pXSector->windAlways) - || ((pSource->flags & kModernTypeFlag1) && !(pSource->flags & kModernTypeFlag2))) { + || ((pSource->flags & kModernTypeFlag1) && !(pSource->flags & kModernTypeFlag2))) + { pXSector->windVel = 0; } } // check redirected TX buckets - int rx = -1; XSPRITE* pXRedir = NULL; - while ((pXRedir = evrListRedirectors(OBJ_SPRITE, sprite[pXSource->reference].extra, pXRedir, &rx)) != NULL) { - for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) { + int rx = -1; XSPRITE* pXRedir = nullptr; + while ((pXRedir = evrListRedirectors(OBJ_SPRITE, sprite[pXSource->reference].extra, pXRedir, &rx)) != nullptr) + { + for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) + { if (rxBucket[i].type != OBJ_SECTOR) continue; XSECTOR* pXSector = &xsector[sector[rxBucket[i].rxindex].extra]; if ((pXSector->state == 1 && !pXSector->windAlways) || (pSource->flags & kModernTypeFlag2)) @@ -1836,29 +2055,35 @@ void windGenStopWindOnSectors(XSPRITE* pXSource) { } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- -void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force) { +void trPlayerCtrlStartScene(DBloodActor* sourceactor, PLAYER* pPlayer, bool force) +{ + auto pXSource = &sourceactor->x(); + TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - int nSource = pXSource->reference; TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - - if (pCtrl->qavScene.index >= 0 && !force) return; + if (pCtrl->qavScene.initiator != nullptr && !force) return; QAV* pQav = playerQavSceneLoad(pXSource->data2); - if (pQav != NULL) { - + if (pQav != nullptr) + { // save current weapon pXSource->dropMsg = pPlayer->curWeapon; - short nIndex = pCtrl->qavScene.index; - if (nIndex > -1 && nIndex != nSource && sprite[nIndex].extra >= 0) - pXSource->dropMsg = xsprite[sprite[nIndex].extra].dropMsg; + auto initiator = pCtrl->qavScene.initiator; + if (initiator != nullptr && initiator != sourceactor && initiator->hasX()) + pXSource->dropMsg = initiator->x().dropMsg; - if (nIndex < 0) + if (initiator == nullptr) WeaponLower(pPlayer); pXSource->sysData1 = ClipLow((pQav->duration * pXSource->waitTime) / 4, 0); // how many times animation should be played - pCtrl->qavScene.index = nSource; + pCtrl->qavScene.initiator = sourceactor; pCtrl->qavScene.qavResrc = pQav; pCtrl->qavScene.dummy = -1; @@ -1870,27 +2095,35 @@ void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force) { pPlayer->qavLoop = false; pPlayer->qavLastTick = I_GetTime(pCtrl->qavScene.qavResrc->ticrate); pPlayer->qavTimer = pCtrl->qavScene.qavResrc->duration; - } - } -void trPlayerCtrlStopScene(PLAYER* pPlayer) { +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- +void trPlayerCtrlStopScene(PLAYER* pPlayer) +{ TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - int scnIndex = pCtrl->qavScene.index; XSPRITE* pXSource = NULL; - if (spriRangeIsFine(scnIndex)) { - pXSource = &xsprite[sprite[scnIndex].extra]; + auto initiator = pCtrl->qavScene.initiator; + XSPRITE* pXSource = nullptr; + if (initiator->hasX()) + { + pXSource = &initiator->x(); pXSource->sysData1 = 0; } - if (pCtrl->qavScene.index >= 0) { - pCtrl->qavScene.index = -1; - pCtrl->qavScene.qavResrc = NULL; + if (pCtrl->qavScene.initiator != nullptr) + { + pCtrl->qavScene.initiator = nullptr; + pCtrl->qavScene.qavResrc = nullptr; pPlayer->sceneQav = -1; // restore weapon - if (pPlayer->pXSprite->health > 0) { + if (pPlayer->pXSprite->health > 0) + { int oldWeapon = (pXSource && pXSource->dropMsg != 0) ? pXSource->dropMsg : 1; pPlayer->newWeapon = pPlayer->curWeapon = oldWeapon; WeaponRaise(pPlayer); @@ -1899,8 +2132,15 @@ void trPlayerCtrlStopScene(PLAYER* pPlayer) { } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition) { + auto sourceactor = &bloodActors[pXSource->reference]; // save player's sprite index to let the tracking condition know it after savegame loading... pXSource->sysData1 = pPlayer->nSprite; @@ -1932,28 +2172,37 @@ void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition) { pPlayer->pXSprite->dropMsg = pXSource->dropMsg; // let's check if there is tracking condition expecting objects with this TX id - if (checkCondition && pXSource->txID >= kChannelUser) { - for (int i = 0; i < gTrackingCondsCount; i++) { - + if (checkCondition && pXSource->txID >= kChannelUser) + { + for (int i = 0; i < gTrackingCondsCount; i++) + { TRCONDITION* pCond = &gCondition[i]; - if (xsprite[pCond->xindex].rxID != pXSource->txID) + if (pCond->actor->x().rxID != pXSource->txID) continue; // search for player control sprite and replace it with actual player sprite - for (unsigned k = 0; k < pCond->length; k++) { - if (pCond->obj[k].type != OBJ_SPRITE || pCond->obj[k].index != pXSource->reference) continue; - pCond->obj[k].index = pPlayer->nSprite; + for (unsigned k = 0; k < pCond->length; k++) + { + if (pCond->obj[k].type != OBJ_SPRITE || pCond->obj[k].actor != sourceactor) continue; + pCond->obj[k].actor = pPlayer->actor(); + pCond->obj[k].index_ = 0; pCond->obj[k].cmd = (uint8_t)pPlayer->pXSprite->command; break; } - } } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlSetRace(XSPRITE* pXSource, PLAYER* pPlayer) { playerSetRace(pPlayer, pXSource->data2); - switch (pPlayer->lifeMode) { + switch (pPlayer->lifeMode) + { case kModeHuman: case kModeBeast: playerSizeReset(pPlayer); @@ -1967,11 +2216,19 @@ void trPlayerCtrlSetRace(XSPRITE* pXSource, PLAYER* pPlayer) { } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlSetMoveSpeed(XSPRITE* pXSource, PLAYER* pPlayer) { int speed = ClipRange(pXSource->data2, 0, 500); - for (int i = 0; i < kModeMax; i++) { - for (int a = 0; a < kPostureMax; a++) { + for (int i = 0; i < kModeMax; i++) + { + for (int a = 0; a < kPostureMax; a++) + { POSTURE* curPosture = &pPlayer->pPosture[i][a]; POSTURE* defPosture = &gPostureDefaults[i][a]; curPosture->frontAccel = (defPosture->frontAccel * speed) / kPercFull; curPosture->sideAccel = (defPosture->sideAccel * speed) / kPercFull; @@ -1980,16 +2237,29 @@ void trPlayerCtrlSetMoveSpeed(XSPRITE* pXSource, PLAYER* pPlayer) { } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlSetJumpHeight(XSPRITE* pXSource, PLAYER* pPlayer) { int jump = ClipRange(pXSource->data3, 0, 500); - for (int i = 0; i < kModeMax; i++) { + for (int i = 0; i < kModeMax; i++) + { POSTURE* curPosture = &pPlayer->pPosture[i][kPostureStand]; POSTURE* defPosture = &gPostureDefaults[i][kPostureStand]; curPosture->normalJumpZ = (defPosture->normalJumpZ * jump) / kPercFull; curPosture->pwupJumpZ = (defPosture->pwupJumpZ * jump) / kPercFull; } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlSetScreenEffect(XSPRITE* pXSource, PLAYER* pPlayer) { int eff = ClipLow(pXSource->data2, 0); int time = (eff > 0) ? pXSource->data3 : 0; @@ -1998,27 +2268,27 @@ void trPlayerCtrlSetScreenEffect(XSPRITE* pXSource, PLAYER* pPlayer) { case 1: // tilting pPlayer->tiltEffect = ClipRange(time, 0, 220); if (eff) break; - fallthrough__; + [[fallthrough]]; case 2: // pain pPlayer->painEffect = ClipRange(time, 0, 2048); if (eff) break; - fallthrough__; + [[fallthrough]]; case 3: // blind pPlayer->blindEffect = ClipRange(time, 0, 2048); if (eff) break; - fallthrough__; + [[fallthrough]]; case 4: // pickup pPlayer->pickupEffect = ClipRange(time, 0, 2048); if (eff) break; - fallthrough__; + [[fallthrough]]; case 5: // quakeEffect pPlayer->quakeEffect = ClipRange(time, 0, 2048); if (eff) break; - fallthrough__; + [[fallthrough]]; case 6: // visibility pPlayer->visibility = ClipRange(time, 0, 2048); if (eff) break; - fallthrough__; + [[fallthrough]]; case 7: // delirium pPlayer->pwUpTime[kPwUpDeliriumShroom] = ClipHigh(time << 1, 432000); break; @@ -2026,6 +2296,12 @@ void trPlayerCtrlSetScreenEffect(XSPRITE* pXSource, PLAYER* pPlayer) { } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlSetLookAngle(XSPRITE* pXSource, PLAYER* pPlayer) { double const upAngle = 289; double const downAngle = -347; @@ -2034,13 +2310,16 @@ void trPlayerCtrlSetLookAngle(XSPRITE* pXSource, PLAYER* pPlayer) double const look = pXSource->data2 << 5; double adjustment; - if (look > 0) { + if (look > 0) + { adjustment = min(MulScaleF(lookStepUp, look, 8), upAngle); } - else if (look < 0) { + else if (look < 0) + { adjustment = -max(MulScaleF(lookStepDown, abs(look), 8), downAngle); } - else { + else + { adjustment = 0; } @@ -2048,11 +2327,18 @@ void trPlayerCtrlSetLookAngle(XSPRITE* pXSource, PLAYER* pPlayer) pPlayer->horizon.lockinput(); } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlEraseStuff(XSPRITE* pXSource, PLAYER* pPlayer) { - switch (pXSource->data2) { + switch (pXSource->data2) + { case 0: // erase all - fallthrough__; + [[fallthrough]]; case 1: // erase weapons WeaponLower(pPlayer); @@ -2068,11 +2354,11 @@ void trPlayerCtrlEraseStuff(XSPRITE* pXSource, PLAYER* pPlayer) { WeaponRaise(pPlayer); if (pXSource->data2) break; - fallthrough__; + [[fallthrough]]; case 2: // erase all armor for (int i = 0; i < 3; i++) pPlayer->armor[i] = 0; if (pXSource->data2) break; - fallthrough__; + [[fallthrough]]; case 3: // erase all pack items for (int i = 0; i < 5; i++) { pPlayer->packSlots[i].isActive = false; @@ -2080,11 +2366,11 @@ void trPlayerCtrlEraseStuff(XSPRITE* pXSource, PLAYER* pPlayer) { } pPlayer->packItemId = -1; if (pXSource->data2) break; - fallthrough__; + [[fallthrough]]; case 4: // erase all keys for (int i = 0; i < 8; i++) pPlayer->hasKey[i] = false; if (pXSource->data2) break; - fallthrough__; + [[fallthrough]]; case 5: // erase powerups for (int i = 0; i < kMaxPowerUps; i++) pPlayer->pwUpTime[i] = 0; break; @@ -2092,20 +2378,28 @@ void trPlayerCtrlEraseStuff(XSPRITE* pXSource, PLAYER* pPlayer) { } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCtrl) { int weapon = pXSource->data3; switch (pXSource->data2) { case 1: // give N weapon and default ammo for it case 2: // give just N ammo for selected weapon - if (weapon <= 0 || weapon > 13) { + if (weapon <= 0 || weapon > 13) + { Printf(PRINT_HIGH, "Weapon #%d is out of a weapons range!", weapon); break; } else if (pXSource->data2 == 2 && pXSource->data4 == 0) { Printf(PRINT_HIGH, "Zero ammo for weapon #%d is specified!", weapon); break; } - switch (weapon) { + switch (weapon) + { case kWeapProximity: // remote bomb case kWeapRemote: // prox bomb pPlayer->hasWeapon[weapon] = true; @@ -2114,7 +2408,8 @@ void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCt weapon++; break; default: - for (int i = 0; i < 11; i++) { + for (int i = 0; i < 11; i++) + { if (gWeaponItemData[i].type != weapon) continue; const WEAPONITEMDATA* pWeaponData = &gWeaponItemData[i]; @@ -2133,13 +2428,16 @@ void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCt } break; } - if (pPlayer->hasWeapon[weapon] && pXSource->data4 == 0) { // switch on it + if (pPlayer->hasWeapon[weapon] && pXSource->data4 == 0) // switch on it + { pPlayer->nextWeapon = kWeapNone; - if (pPlayer->sceneQav >= 0 && spriRangeIsFine(pCtrl->qavScene.index)) { - XSPRITE* pXScene = &xsprite[sprite[pCtrl->qavScene.index].extra]; - pXScene->dropMsg = weapon; - } else if (pPlayer->curWeapon != weapon) { + if (pPlayer->sceneQav >= 0 && pCtrl->qavScene.initiator && pCtrl->qavScene.initiator->hasX()) + { + pCtrl->qavScene.initiator->x().dropMsg = weapon; + } + else if (pPlayer->curWeapon != weapon) + { pPlayer->newWeapon = weapon; WeaponRaise(pPlayer); } @@ -2148,9 +2446,16 @@ void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCt } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlUsePackItem(XSPRITE* pXSource, PLAYER* pPlayer, int evCmd) { unsigned int invItem = pXSource->data2 - 1; - switch (evCmd) { + switch (evCmd) + { case kCmdOn: if (!pPlayer->packSlots[invItem].isActive) packUseItem(pPlayer, invItem); break; @@ -2162,12 +2467,13 @@ void trPlayerCtrlUsePackItem(XSPRITE* pXSource, PLAYER* pPlayer, int evCmd) { break; } - switch (pXSource->data4) { + switch (pXSource->data4) + { case 2: // both case 0: // switch on it if (pPlayer->packSlots[invItem].curAmount > 0) pPlayer->packItemId = invItem; if (!pXSource->data4) break; - fallthrough__; + [[fallthrough]]; case 1: // force remove after use pPlayer->packSlots[invItem].isActive = false; pPlayer->packSlots[invItem].curAmount = 0; @@ -2175,6 +2481,12 @@ void trPlayerCtrlUsePackItem(XSPRITE* pXSource, PLAYER* pPlayer, int evCmd) { } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void trPlayerCtrlUsePowerup(XSPRITE* pXSource, PLAYER* pPlayer, int evCmd) { spritetype* pSource = &sprite[pXSource->reference]; @@ -2185,15 +2497,14 @@ void trPlayerCtrlUsePowerup(XSPRITE* pXSource, PLAYER* pPlayer, int evCmd) { if (pXSource->data3 < 0) nTime = -nTime; - - if (pPlayer->pwUpTime[nPower]) { + if (pPlayer->pwUpTime[nPower]) + { if (!relative && nTime <= 0) powerupDeactivate(pPlayer, nPower); - } - if (nTime != 0) { - + if (nTime != 0) + { if (pPlayer->pwUpTime[nPower] <= 0) powerupActivate(pPlayer, nPower); // MUST activate first for powerups like kPwUpDeathMask @@ -2290,22 +2601,32 @@ void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) { } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { spritetype* pSource = &sprite[pXSource->reference]; - switch (objType) { - case OBJ_WALL: { + switch (objType) + { + case OBJ_WALL: + { walltype* pWall = &wall[objIndex]; int old = -1; // data3 = set wall hitag - if (valueIsBetween(pXSource->data3, -1, 32767)) { + if (valueIsBetween(pXSource->data3, -1, 32767)) + { if ((pSource->flags & kModernTypeFlag1)) pWall->hitag = pWall->hitag |= pXSource->data3; else pWall->hitag = pXSource->data3; } // data4 = set wall cstat - if (valueIsBetween(pXSource->data4, -1, 65535)) { + if (valueIsBetween(pXSource->data4, -1, 65535)) + { old = pWall->cstat; // set new cstat @@ -2331,11 +2652,13 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { } break; case OBJ_SPRITE: { + auto actor = &bloodActors[objIndex]; spritetype* pSprite = &sprite[objIndex]; bool thing2debris = false; XSPRITE* pXSprite = &xsprite[pSprite->extra]; int old = -1; // data3 = set sprite hitag - if (valueIsBetween(pXSource->data3, -1, 32767)) { + if (valueIsBetween(pXSource->data3, -1, 32767)) + { old = pSprite->flags; // set new hitag @@ -2352,8 +2675,10 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { } // data2 = sprite physics settings - if (valueIsBetween(pXSource->data2, -1, 32767) || thing2debris) { - switch (pSprite->statnum) { + if (valueIsBetween(pXSource->data2, -1, 32767) || thing2debris) + { + switch (pSprite->statnum) + { case kStatDude: // dudes already treating in game case kStatFree: case kStatMarker: @@ -2364,8 +2689,8 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { int flags = (pXSprite->physAttr != 0) ? pXSprite->physAttr : 0; int oldFlags = flags; - if (thing2debris) { - + if (thing2debris) + { // converting thing to debris if ((pSprite->flags & kPhysMove) != 0) flags |= kPhysMove; else flags &= ~kPhysMove; @@ -2377,16 +2702,18 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { xvel[objIndex] = yvel[objIndex] = zvel[objIndex] = 0; pXSprite->restState = pXSprite->state; - } else { - - static char digits[6]; - memset(digits, 0, sizeof(digits)); - sprintf(digits, "%d", pXSource->data2); + } + else + { + // WTF is this?!? + char digits[6] = {}; + snprintf(digits, 6, "%d", pXSource->data2); for (unsigned int i = 0; i < sizeof(digits); i++) digits[i] = (digits[i] >= 48 && digits[i] <= 57) ? (digits[i] - 57) + 9 : 0; // first digit of data2: set main physics attributes - switch (digits[0]) { + switch (digits[0]) + { case 0: flags &= ~kPhysMove; flags &= ~(kPhysGravity | kPhysFalling); @@ -2406,7 +2733,8 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { } // second digit of data2: touch physics flags - switch (digits[1]) { + switch (digits[1]) + { case 0: flags &= ~kPhysDebrisTouch; break; @@ -2416,7 +2744,8 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { } // third digit of data2: weapon physics flags - switch (digits[2]) { + switch (digits[2]) + { case 0: flags &= ~kPhysDebrisVector; flags &= ~kPhysDebrisExplode; @@ -2436,7 +2765,8 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { } // fourth digit of data2: swimming / flying physics flags - switch (digits[3]) { + switch (digits[3]) + { case 0: flags &= ~kPhysDebrisSwim; flags &= ~kPhysDebrisFly; @@ -2473,27 +2803,27 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { flags |= kPhysDebrisFloat; break; } - } - int nIndex = debrisGetIndex(objIndex); // check if there is no sprite in list + int nIndex = debrisGetIndex(&bloodActors[objIndex]); // check if there is no sprite in list // adding physics sprite in list - if ((flags & kPhysGravity) != 0 || (flags & kPhysMove) != 0) { + if ((flags & kPhysGravity) != 0 || (flags & kPhysMove) != 0) + { if (oldFlags == 0) xvel[objIndex] = yvel[objIndex] = zvel[objIndex] = 0; - if (nIndex != -1) { - + if (nIndex != -1) + { pXSprite->physAttr = flags; // just update physics attributes - - } else if ((nIndex = debrisGetFreeIndex()) < 0) { - + } + else if ((nIndex = debrisGetFreeIndex()) < 0) + { viewSetSystemMessage("Max (%d) Physics affected sprites reached!", kMaxSuperXSprites); - - } else { - + } + else + { pXSprite->physAttr = flags; // update physics attributes // allow things to became debris, so they use different physics... @@ -2508,7 +2838,7 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { gPhysSpritesList[nIndex] = &bloodActors[objIndex]; if (nIndex >= gPhysSpritesCount) gPhysSpritesCount++; - getSpriteMassBySize(pSprite); // create physics cache + getSpriteMassBySize(actor); // create physics cache } @@ -2527,8 +2857,8 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { } // data4 = sprite cstat - if (valueIsBetween(pXSource->data4, -1, 65535)) { - + if (valueIsBetween(pXSource->data4, -1, 65535)) + { old = pSprite->cstat; // set new cstat @@ -2539,22 +2869,20 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { if ((old & 0x1000) && !(pSprite->cstat & 0x1000)) pSprite->cstat |= 0x1000; //kSpritePushable if ((old & 0x80) && !(pSprite->cstat & 0x80)) pSprite->cstat |= 0x80; // kSpriteOriginAlign - if (old & 0x6000) { - + if (old & 0x6000) + { if (!(pSprite->cstat & 0x6000)) pSprite->cstat |= 0x6000; // kSpriteMoveMask if ((old & 0x0) && !(pSprite->cstat & 0x0)) pSprite->cstat |= 0x0; // kSpriteMoveNone else if ((old & 0x2000) && !(pSprite->cstat & 0x2000)) pSprite->cstat |= 0x2000; // kSpriteMoveForward, kSpriteMoveFloor else if ((old & 0x4000) && !(pSprite->cstat & 0x4000)) pSprite->cstat |= 0x4000; // kSpriteMoveReverse, kSpriteMoveCeiling - } - } } break; - case OBJ_SECTOR: { - + case OBJ_SECTOR: + { sectortype* pSector = §or[objIndex]; XSECTOR* pXSector = &xsector[sector[objIndex].extra]; @@ -2685,6 +3013,12 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { auto actor = &bloodActors[pSprite->index]; spritetype* pSource = &sprite[pXSource->reference]; PLAYER* pPlayer = getPlayerById(pSprite->type); @@ -2707,30 +3041,33 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { if (pSprite->flags & kPhysGravity) pSprite->flags |= kPhysFalling; - if (pXSector) { + if (pXSector) + { if (pXSector->Enter && (pPlayer || (isDude && !pXSector->dudeLockout))) trTriggerSector(pSource->sectnum, pXSector, kCmdSectorEnter); - if (pXSector->Underwater) { + if (pXSector->Underwater) + { spritetype* pLink = (gLowerLink[pSource->sectnum] >= 0) ? &sprite[gLowerLink[pSource->sectnum]] : NULL; - if (pLink) { - + if (pLink) + { // must be sure we found exact same upper link for (int i = 0; i < kMaxSectors; i++) { if (gUpperLink[i] < 0 || xsprite[sprite[gUpperLink[i]].extra].data1 != xsprite[pLink->extra].data1) continue; pLink = &sprite[gUpperLink[i]]; break; } - } if (pLink) xsprite[pSprite->extra].medium = (pLink->type == kMarkerUpGoo) ? kMediumGoo : kMediumWater; - if (pPlayer) { + if (pPlayer) + { int waterPal = kMediumWater; - if (pLink) { + if (pLink) + { if (xsprite[pLink->extra].data2 > 0) waterPal = xsprite[pLink->extra].data2; else if (pLink->type == kMarkerUpGoo) waterPal = kMediumGoo; } @@ -2740,10 +3077,12 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { pPlayer->pXSprite->burnTime = 0; } - } else { - + } + else + { xsprite[pSprite->extra].medium = kMediumNormal; - if (pPlayer) { + if (pPlayer) + { pPlayer->posture = (!(pPlayer->input.actions & SB_CROUCH)) ? kPostureStand : kPostureCrouch; pPlayer->nWaterPal = 0; } @@ -2766,9 +3105,10 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { } } - if (pXSource->data2 == 1) { - - if (pPlayer) { + if (pXSource->data2 == 1) + { + if (pPlayer) + { pPlayer->angle.settarget(pSource->ang); pPlayer->angle.lockinput(); } @@ -2784,12 +3124,12 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { if (pXSource->data4 > 0) sfxPlay3DSound(pSource, pXSource->data4, -1, 0); - if (pPlayer) { + if (pPlayer) + { playerResetInertia(pPlayer); if (pXSource->data2 == 1) pPlayer->zViewVel = pPlayer->zWeaponVel = 0; } - } @@ -2803,24 +3143,25 @@ void useEffectGen(XSPRITE* pXSource, spritetype* pSprite) { if (!xspriRangeIsFine(pSprite->extra)) return; - else if (fxId >= kEffectGenCallbackBase) { - + else if (fxId >= kEffectGenCallbackBase) + { int length = sizeof(gEffectGenCallbacks) / sizeof(gEffectGenCallbacks[0]); - if (fxId < kEffectGenCallbackBase + length) { - + if (fxId < kEffectGenCallbackBase + length) + { fxId = gEffectGenCallbacks[fxId - kEffectGenCallbackBase]; evKillActor(actor, (CALLBACK_ID)fxId); evPostActor(actor, 0, (CALLBACK_ID)fxId); - } - } else if (valueIsBetween(fxId, 0, kFXMax)) { - + } + else if (valueIsBetween(fxId, 0, kFXMax)) + { int pos, top, bottom; GetSpriteExtents(pSprite, &top, &bottom); DBloodActor* pEffect = nullptr; // select where exactly effect should be spawned - switch (pXSource->data4) { + switch (pXSource->data4) + { case 1: pos = bottom; break; @@ -2837,12 +3178,13 @@ void useEffectGen(XSPRITE* pXSource, spritetype* pSprite) { break; } - if ((pEffect = gFX.fxSpawnActor((FX_ID)fxId, pSprite->sectnum, pSprite->x, pSprite->y, pos, 0)) != NULL) { - + if ((pEffect = gFX.fxSpawnActor((FX_ID)fxId, pSprite->sectnum, pSprite->x, pSprite->y, pos, 0)) != NULL) + { auto pEffectSpr = &pEffect->s(); pEffectSpr->owner = pSource->index; - if (pSource->flags & kModernTypeFlag1) { + if (pSource->flags & kModernTypeFlag1) + { pEffectSpr->pal = pSource->pal; pEffectSpr->xoffset = pSource->xoffset; pEffectSpr->yoffset = pSource->yoffset; @@ -2851,7 +3193,8 @@ void useEffectGen(XSPRITE* pXSource, spritetype* pSprite) { pEffectSpr->shade = pSource->shade; } - if (pSource->flags & kModernTypeFlag2) { + if (pSource->flags & kModernTypeFlag2) + { pEffectSpr->cstat = pSource->cstat; if (pEffectSpr->cstat & CSTAT_SPRITE_INVISIBLE) pEffectSpr->cstat &= ~CSTAT_SPRITE_INVISIBLE; @@ -2859,25 +3202,33 @@ void useEffectGen(XSPRITE* pXSource, spritetype* pSprite) { if (pEffectSpr->cstat & CSTAT_SPRITE_ONE_SIDED) pEffectSpr->cstat &= ~CSTAT_SPRITE_ONE_SIDED; - } } - } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) { spritetype* pSource = &sprite[pXSource->reference]; XSECTOR* pXSector = NULL; int nXSector = 0; - if (pSector != NULL) { + if (pSector != nullptr) + { pXSector = &xsector[pSector->extra]; nXSector = sector[pXSector->reference].extra; - } else if (xsectRangeIsFine(sector[pSource->sectnum].extra)) { + } + else if (xsectRangeIsFine(sector[pSource->sectnum].extra)) + { pXSector = &xsector[sector[pSource->sectnum].extra]; nXSector = sector[pXSector->reference].extra; - } else { + } + else + { nXSector = dbInsertXSector(pSource->sectnum); pXSector = &xsector[nXSector]; pXSector->windAlways = 1; } @@ -2887,7 +3238,8 @@ void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) { windVel = nnExtRandom(0, windVel); // process vertical wind in nnExtProcessSuperSprites(); - if ((pSource->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR)) { + if ((pSource->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR)) + { pXSource->sysData2 = windVel << 1; return; } @@ -2897,26 +3249,33 @@ void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) { pXSector->panAlways = pXSector->windAlways = 1; int ang = pSource->ang; - if (pXSource->data4 <= 0) { - if ((pXSource->data1 & 0x0002)) { + if (pXSource->data4 <= 0) + { + if ((pXSource->data1 & 0x0002)) + { while (pSource->ang == ang) pSource->ang = nnExtRandom(-kAng360, kAng360) & 2047; } } else if (pSource->cstat & 0x2000) pSource->ang += pXSource->data4; else if (pSource->cstat & 0x4000) pSource->ang -= pXSource->data4; - else if (pXSource->sysData1 == 0) { + else if (pXSource->sysData1 == 0) + { if ((ang += pXSource->data4) >= kAng180) pXSource->sysData1 = 1; pSource->ang = ClipHigh(ang, kAng180); - } else { + } + else + { if ((ang -= pXSource->data4) <= -kAng180) pXSource->sysData1 = 0; pSource->ang = ClipLow(ang, -kAng180); } pXSector->windAng = pSource->ang; - if (pXSource->data3 > 0 && pXSource->data3 < 4) { - switch (pXSource->data3) { + if (pXSource->data3 > 0 && pXSource->data3 < 4) + { + switch (pXSource->data3) + { case 1: pXSector->panFloor = true; pXSector->panCeiling = false; @@ -2946,10 +3305,11 @@ void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) { pXSector->panVel = pXSector->windVel; // add to panList if panVel was set to 0 previously - if (oldPan == 0 && pXSector->panVel != 0 && panCount < kMaxXSectors) { - + if (oldPan == 0 && pXSector->panVel != 0 && panCount < kMaxXSectors) + { int i; - for (i = 0; i < panCount; i++) { + for (i = 0; i < panCount; i++) + { if (panList[i] != nXSector) continue; break; } @@ -2959,10 +3319,15 @@ void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) { panList[panCount++] = nXSector; } } - } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void useSpriteDamager(XSPRITE* pXSource, int objType, int objIndex) { spritetype* pSource = &sprite[pXSource->reference]; @@ -2971,27 +3336,35 @@ void useSpriteDamager(XSPRITE* pXSource, int objType, int objIndex) { int top, bottom, i; bool floor, ceil, wall, enter; - switch (objType) { + switch (objType) + { case OBJ_SPRITE: damageSprites(pXSource, &sprite[objIndex]); break; case OBJ_SECTOR: + { GetSpriteExtents(pSource, &top, &bottom); - floor = (bottom >= pSector->floorz); ceil = (top <= pSector->ceilingz); - wall = (pSource->cstat & 0x10); enter = (!floor && !ceil && !wall); - for (i = headspritesect[objIndex]; i != -1; i = nextspritesect[i]) { + floor = (bottom >= pSector->floorz); + ceil = (top <= pSector->ceilingz); + wall = (pSource->cstat & 0x10); + enter = (!floor && !ceil && !wall); + for (i = headspritesect[objIndex]; i != -1; i = nextspritesect[i]) + { + auto& hit = gSpriteHit[sprite[i].extra]; + if (!IsDudeSprite(&sprite[i]) || !xspriRangeIsFine(sprite[i].extra)) continue; else if (enter) damageSprites(pXSource, &sprite[i]); - else if (floor && (gSpriteHit[sprite[i].extra].florhit & 0xc000) == 0x4000 && (gSpriteHit[sprite[i].extra].florhit & 0x3fff) == objIndex) + else if (floor && hit.florhit.type == kHitSector && hit.florhit.index == objIndex) damageSprites(pXSource, &sprite[i]); - else if (ceil && (gSpriteHit[sprite[i].extra].ceilhit & 0xc000) == 0x4000 && (gSpriteHit[sprite[i].extra].ceilhit & 0x3fff) == objIndex) + else if (ceil && hit.ceilhit.type == kHitSector && hit.ceilhit.index == objIndex) damageSprites(pXSource, &sprite[i]); - else if (wall && (gSpriteHit[sprite[i].extra].hit & 0xc000) == 0x8000 && sectorofwall(gSpriteHit[sprite[i].extra].hit & 0x3fff) == objIndex) + else if (wall && hit.hit.type == kHitWall && sectorofwall(hit.hit.index) == objIndex) damageSprites(pXSource, &sprite[i]); } break; + } case -1: for (i = headspritestat[kStatDude]; i != -1; i = nextspritestat[i]) { if (sprite[i].statnum != kStatDude) continue; @@ -3013,6 +3386,13 @@ void useSpriteDamager(XSPRITE* pXSource, int objType, int objIndex) { } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + + void damageSprites(XSPRITE* pXSource, spritetype* pSprite) { auto actor = &bloodActors[pSprite->index]; @@ -3031,7 +3411,8 @@ void damageSprites(XSPRITE* pXSource, spritetype* pSprite) bool godMode = (pPlayer && ((dmgType >= 0 && pPlayer->damageControl[dmgType]) || powerupCheck(pPlayer, kPwUpDeathMask) || pPlayer->godMode)); // kneeling if (godMode || pXSprite->locked) return; - else if (pXSource->data3) { + else if (pXSource->data3) + { if (pSource->flags & kModernTypeFlag1) dmg = ClipHigh(pXSource->data3 << 1, 65535); else if (pXSprite->sysData2 > 0) dmg = (ClipHigh(pXSprite->sysData2 << 4, 65535) * pXSource->data3) / kPercFull; else dmg = ((getDudeInfo(pSprite->type)->startHealth << 4) * pXSource->data3) / kPercFull; @@ -3039,30 +3420,28 @@ void damageSprites(XSPRITE* pXSource, spritetype* pSprite) health = pXSprite->health - dmg; } - if (dmgType >= kDmgFall) { - if (dmg < (int)pXSprite->health << 4) { - - if (!nnExtIsImmune(pSprite, dmgType, 0)) { - - if (pPlayer) { - + if (dmgType >= kDmgFall) + { + if (dmg < (int)pXSprite->health << 4) + { + if (!nnExtIsImmune(actor, dmgType, 0)) + { + if (pPlayer) + { playerDamageArmor(pPlayer, (DAMAGE_TYPE)dmgType, dmg); for (int i = 0; i < 3; armor[i] = pPlayer->armor[i], pPlayer->armor[i] = 0, i++); - actDamageSprite(sourceactor, actor, (DAMAGE_TYPE)dmgType, dmg); + actDamageSprite(sourceactor, actor, (DAMAGE_TYPE)dmgType, dmg); for (int i = 0; i < 3; pPlayer->armor[i] = armor[i], i++); } - else { - + else + { actDamageSprite(sourceactor, actor, (DAMAGE_TYPE)dmgType, dmg); - } - } - else { - - Printf(PRINT_HIGH, "Dude type %d is immune to damage type %d!", pSprite->type, dmgType); - + else + { + //Printf(PRINT_HIGH, "Dude type %d is immune to damage type %d!", pSprite->type, dmgType); } } else if (!pPlayer) actKillDude(&bloodActors[pSource->index], &bloodActors[pSprite->index], (DAMAGE_TYPE)dmgType, dmg); @@ -3072,17 +3451,18 @@ void damageSprites(XSPRITE* pXSource, spritetype* pSprite) else if (!pPlayer) actKillDude(&bloodActors[pSource->index], &bloodActors[pSprite->index], kDamageBullet, dmg); else playerDamageSprite(&bloodActors[pSource->index], pPlayer, kDamageBullet, dmg); - if (pXSprite->health > 0) { - + if (pXSprite->health > 0) + { if (!(pSource->flags & kModernTypeFlag8)) pXSprite->health = health; bool showEffects = !(pSource->flags & kModernTypeFlag2); // show it by default bool forceRecoil = (pSource->flags & kModernTypeFlag4); - if (showEffects) { - - switch (dmgType) { + if (showEffects) + { + switch (dmgType) + { case kDmgBurn: if (pXSprite->burnTime > 0) break; actBurnSprite(pSource->index, pXSprite, ClipLow(dmg >> 1, 128)); @@ -3094,8 +3474,8 @@ void damageSprites(XSPRITE* pXSource, spritetype* pSprite) break; case kDmgBullet: evKillActor(actor, kCallbackFXBloodSpurt); - for (int i = 1; i < 6; i++) { - + for (int i = 1; i < 6; i++) + { if (Chance(0x16000 >> i)) fxSpawnBlood(actor, dmg << 4); } @@ -3103,25 +3483,25 @@ void damageSprites(XSPRITE* pXSource, spritetype* pSprite) case kDmgChoke: if (!pPlayer || !Chance(0x2000)) break; else pPlayer->blindEffect += dmg << 2; - } - } - - if (forceRecoil && !pPlayer) { - + if (forceRecoil && !pPlayer) + { pXSprite->data3 = 32767; actor->dudeExtra.teslaHit = (dmgType == kDmgElectric) ? 1 : 0; if (pXSprite->aiState->stateType != kAiStateRecoil) RecoilDude(&bloodActors[pXSprite->reference]); } - } - - return; } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { if (pXSource->data2 > 0 && !getSequence(pXSource->data2)) { @@ -3129,31 +3509,41 @@ void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { return; } - spritetype* pSource = &sprite[pXSource->reference]; - switch (objType) { + auto sourceactor = &bloodActors[pXSource->reference]; + spritetype* pSource = &sourceactor->s(); + + switch (objType) + { case OBJ_SECTOR: - if (pXSource->data2 <= 0) { + if (pXSource->data2 <= 0) + { if (pXSource->data3 == 3 || pXSource->data3 == 1) seqKill(2, sector[index].extra); if (pXSource->data3 == 3 || pXSource->data3 == 2) seqKill(1, sector[index].extra); - } else { + } + else + { if (pXSource->data3 == 3 || pXSource->data3 == 1) seqSpawn(pXSource->data2, 2, sector[index].extra, -1); if (pXSource->data3 == 3 || pXSource->data3 == 2) seqSpawn(pXSource->data2, 1, sector[index].extra, -1); } return; + case OBJ_WALL: - if (pXSource->data2 <= 0) { + if (pXSource->data2 <= 0) + { if (pXSource->data3 == 3 || pXSource->data3 == 1) seqKill(0, wall[index].extra); if ((pXSource->data3 == 3 || pXSource->data3 == 2) && (wall[index].cstat & CSTAT_WALL_MASKED)) seqKill(4, wall[index].extra); - } else { - + } + else + { if (pXSource->data3 == 3 || pXSource->data3 == 1) seqSpawn(pXSource->data2, 0, wall[index].extra, -1); + if (pXSource->data3 == 3 || pXSource->data3 == 2) { if (wall[index].nextwall < 0) { @@ -3168,8 +3558,8 @@ void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { } } - if (pXSource->data4 > 0) { - + if (pXSource->data4 > 0) + { int cx, cy, cz; cx = (wall[index].x + wall[wall[index].point2].x) >> 1; cy = (wall[index].y + wall[wall[index].point2].y) >> 1; @@ -3183,69 +3573,69 @@ void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { cz = (ceilZ + floorZ) >> 1; sfxPlay3DSound(cx, cy, cz, pXSource->data4, nSector); - } - } return; + case OBJ_SPRITE: if (pXSource->data2 <= 0) seqKill(3, sprite[index].extra); else if (sectRangeIsFine(sprite[index].sectnum)) { - if (pXSource->data3 > 0) { - int nSprite = InsertSprite(sprite[index].sectnum, kStatDecoration); - int top, bottom; GetSpriteExtents(&sprite[index], &top, &bottom); - sprite[nSprite].x = sprite[index].x; - sprite[nSprite].y = sprite[index].y; - switch (pXSource->data3) { - default: - sprite[nSprite].z = sprite[index].z; - break; - case 2: - sprite[nSprite].z = bottom; - break; - case 3: - sprite[nSprite].z = top; - break; - case 4: - sprite[nSprite].z = sprite[index].z + tileHeight(sprite[index].picnum) / 2 + tileTopOffset(sprite[index].picnum); - break; - case 5: - case 6: - if (!sectRangeIsFine(sprite[index].sectnum)) sprite[nSprite].z = top; - else sprite[nSprite].z = (pXSource->data3 == 5) ? sector[sprite[nSprite].sectnum].floorz : sector[sprite[nSprite].sectnum].ceilingz; - break; - } - - if (nSprite >= 0) { - - int nXSprite = dbInsertXSprite(nSprite); - seqSpawn(pXSource->data2, 3, nXSprite, -1); - if (pSource->flags & kModernTypeFlag1) { - - sprite[nSprite].pal = pSource->pal; - sprite[nSprite].shade = pSource->shade; - sprite[nSprite].xrepeat = pSource->xrepeat; - sprite[nSprite].yrepeat = pSource->yrepeat; - sprite[nSprite].xoffset = pSource->xoffset; - sprite[nSprite].yoffset = pSource->yoffset; - - } - - if (pSource->flags & kModernTypeFlag2) { - - sprite[nSprite].cstat |= pSource->cstat; - - } - - // should be: the more is seqs, the shorter is timer - evPostActor(&bloodActors[nSprite], 1000, kCallbackRemove); - } - } else { - - seqSpawn(pXSource->data2, 3, sprite[index].extra, -1); - + if (pXSource->data3 > 0) { + int nSprite = InsertSprite(sprite[index].sectnum, kStatDecoration); + auto spawned = &bloodActors[nSprite]; + auto pSpawned = &spawned->s(); + int top, bottom; GetSpriteExtents(&sprite[index], &top, &bottom); + pSpawned->x = sprite[index].x; + pSpawned->y = sprite[index].y; + switch (pXSource->data3) { + default: + pSpawned->z = sprite[index].z; + break; + case 2: + pSpawned->z = bottom; + break; + case 3: + pSpawned->z = top; + break; + case 4: + pSpawned->z = sprite[index].z + tileHeight(sprite[index].picnum) / 2 + tileTopOffset(sprite[index].picnum); + break; + case 5: + case 6: + if (!sectRangeIsFine(sprite[index].sectnum)) pSpawned->z = top; + else pSpawned->z = (pXSource->data3 == 5) ? sector[pSpawned->sectnum].floorz : sector[pSpawned->sectnum].ceilingz; + break; } + + if (nSprite >= 0) { + + spawned->addX(); + seqSpawn(pXSource->data2, spawned, -1); + if (pSource->flags & kModernTypeFlag1) + { + pSpawned->pal = pSource->pal; + pSpawned->shade = pSource->shade; + pSpawned->xrepeat = pSource->xrepeat; + pSpawned->yrepeat = pSource->yrepeat; + pSpawned->xoffset = pSource->xoffset; + pSpawned->yoffset = pSource->yoffset; + } + + if (pSource->flags & kModernTypeFlag2) + { + pSpawned->cstat |= pSource->cstat; + } + + // should be: the more is seqs, the shorter is timer + evPostActor(spawned, 1000, kCallbackRemove); + } + } + else + { + seqSpawn(pXSource->data2, 3, sprite[index].extra, -1); + } + if (pXSource->data4 > 0) sfxPlay3DSound(&sprite[index], pXSource->data4, -1, 0); } @@ -3253,6 +3643,12 @@ void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + int condSerialize(int objType, int objIndex) { switch (objType) { case OBJ_SECTOR: return kCondSerialSector + objIndex; @@ -3962,13 +4358,13 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { case 31: if (arg1 == -1) { for (var = 0; var < kDmgMax; var++) { - if (!nnExtIsImmune(pSpr, arg1, 0)) + if (!nnExtIsImmune(spractor, arg1, 0)) return false; } return true; } - return nnExtIsImmune(pSpr, arg1, 0); + return nnExtIsImmune(spractor, arg1, 0); case 35: // hitscan: ceil? case 36: // hitscan: floor? case 37: // hitscan: wall? @@ -3982,7 +4378,7 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { if ((pPlayer = getPlayerById(pSpr->type)) != NULL) var = HitScan(pSpr, pPlayer->zWeapon, pPlayer->aim.dx, pPlayer->aim.dy, pPlayer->aim.dz, arg1, arg3 << 1); else if (IsDudeSprite(pSpr)) - var = HitScan(pSpr, pSpr->z, CosScale16(pSpr->ang), SinScale16(pSpr->ang), (!xspriRangeIsFine(pSpr->extra)) ? 0 : spractor->dudeSlope, arg1, arg3 << 1); + var = HitScan(pSpr, pSpr->z, bcos(pSpr->ang), bsin(pSpr->ang), (!xspriRangeIsFine(pSpr->extra)) ? 0 : spractor->dudeSlope, arg1, arg3 << 1); else if ((var2 & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR) { var3 = (var2 & 0x0008) ? 0x10000 << 1 : -(0x10000 << 1); @@ -3990,7 +4386,7 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { } else { - var = HitScan(pSpr, pSpr->z, CosScale16(pSpr->ang), SinScale16(pSpr->ang), 0, arg1, arg3 << 1); + var = HitScan(pSpr, pSpr->z, bcos(pSpr->ang), bsin(pSpr->ang), 0, arg1, arg3 << 1); } @@ -4038,54 +4434,63 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { else if (pSpr->type >= kThingBase && pSpr->type < kThingMax) var = thingInfo[pSpr->type - kThingBase].startHealth << 4; return condCmp((kPercFull * pXSpr->health) / ClipLow(var, 1), arg1, arg2, cmpOp); case 55: // touching ceil of sector? - if ((gSpriteHit[pSpr->extra].ceilhit & 0xc000) != 0x4000) return false; - else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].ceilhit & 0x3fff); + if (gSpriteHit[pSpr->extra].ceilhit.type != kHitSector) return false; + else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].ceilhit.index); return true; case 56: // touching floor of sector? - if ((gSpriteHit[pSpr->extra].florhit & 0xc000) != 0x4000) return false; - else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].florhit & 0x3fff); + if (gSpriteHit[pSpr->extra].florhit.type != kHitSector) return false; + else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].florhit.index); return true; case 57: // touching walls of sector? - if ((gSpriteHit[pSpr->extra].hit & 0xc000) != 0x8000) return false; - else if (PUSH) condPush(pXCond, OBJ_WALL, gSpriteHit[pSpr->extra].hit & 0x3fff); + if (gSpriteHit[pSpr->extra].hit.type != kHitWall) return false; + else if (PUSH) condPush(pXCond, OBJ_WALL, gSpriteHit[pSpr->extra].hit.index); return true; case 58: // touching another sprite? + { + DBloodActor* actorvar = nullptr; switch (arg3) { case 0: case 1: - if ((gSpriteHit[pSpr->extra].florhit & 0xc000) == 0xc000) var = gSpriteHit[pSpr->extra].florhit & 0x3fff; + if (gSpriteHit[pSpr->extra].florhit.type == kHitSprite) actorvar = gSpriteHit[pSpr->extra].florhit.actor; if (arg3 || var >= 0) break; - fallthrough__; + [[fallthrough]]; case 2: - if ((gSpriteHit[pSpr->extra].hit & 0xc000) == 0xc000) var = gSpriteHit[pSpr->extra].hit & 0x3fff; + if (gSpriteHit[pSpr->extra].hit.type == kHitSprite) actorvar = gSpriteHit[pSpr->extra].hit.actor; if (arg3 || var >= 0) break; - fallthrough__; + [[fallthrough]]; case 3: - if ((gSpriteHit[pSpr->extra].ceilhit & 0xc000) == 0xc000) var = gSpriteHit[pSpr->extra].ceilhit & 0x3fff; + if (gSpriteHit[pSpr->extra].ceilhit.type == kHitSprite) actorvar = gSpriteHit[pSpr->extra].ceilhit.actor; break; } - if (var < 0) { // check if something touching this sprite - for (int i = kMaxXSprites - 1, idx = i; i > 0; idx = xsprite[--i].reference) { + if (actorvar == nullptr) + { + // check if something touching this sprite + for (int i = kMaxXSprites - 1, idx = i; i > 0; idx = xsprite[--i].reference) + { if (idx < 0 || (sprite[idx].flags & kHitagRespawn)) continue; + auto iactor = &bloodActors[idx]; + auto objactor = &bloodActors[objIndex]; + auto& hit = gSpriteHit[i]; switch (arg3) { case 0: case 1: - if ((gSpriteHit[i].ceilhit & 0xc000) == 0xc000 && (gSpriteHit[i].ceilhit & 0x3fff) == objIndex) var = idx; - if (arg3 || var >= 0) break; - fallthrough__; + if (hit.ceilhit.type == kHitSprite && hit.ceilhit.actor == objactor) actorvar = iactor; + if (arg3 || actorvar) break; + [[fallthrough]]; case 2: - if ((gSpriteHit[i].hit & 0xc000) == 0xc000 && (gSpriteHit[i].hit & 0x3fff) == objIndex) var = idx; - if (arg3 || var >= 0) break; - fallthrough__; + if (hit.hit.type == kHitSprite && hit.hit.actor == objactor) actorvar = iactor; + if (arg3 || actorvar) break; + [[fallthrough]]; case 3: - if ((gSpriteHit[i].florhit & 0xc000) == 0xc000 && (gSpriteHit[i].florhit & 0x3fff) == objIndex) var = idx; + if (hit.florhit.type == kHitSprite && hit.florhit.actor == objactor) actorvar = iactor; break; } } } - if (var < 0) return false; - else if (PUSH) condPush(pXCond, OBJ_SPRITE, var); + if (actorvar == nullptr) return false; + else if (PUSH) condPush(pXCond, OBJ_SPRITE, actorvar->s().index); return true; + } case 65: // compare burn time (in %) var = (IsDudeSprite(pSpr)) ? 2400 : 1200; if (!condCmp((kPercFull * pXSpr->burnTime) / var, arg1, arg2, cmpOp)) return false; @@ -4109,7 +4514,7 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { return false; } case 70: - return condCmp(getSpriteMassBySize(pSpr), arg1, arg2, cmpOp); // mass of the sprite in a range? + return condCmp(getSpriteMassBySize(spractor), arg1, arg2, cmpOp); // mass of the sprite in a range? } } else { switch (cond) { @@ -4126,20 +4531,26 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { } // this updates index of object in all conditions -void condUpdateObjectIndex(int objType, int oldIndex, int newIndex) { +void condUpdateObjectIndex(int objType, int oldIndex, int newIndex) +{ + // this only gets called for player respawns + auto oldActor = &bloodActors[oldIndex]; + auto newActor = &bloodActors[newIndex]; // update index in tracking conditions first - for (int i = 0; i < gTrackingCondsCount; i++) { + for (int i = 0; i < gTrackingCondsCount; i++) + { TRCONDITION* pCond = &gCondition[i]; - for (unsigned k = 0; k < pCond->length; k++) { - if (pCond->obj[k].type != objType || pCond->obj[k].index != oldIndex) continue; - pCond->obj[k].index = newIndex; + for (unsigned k = 0; k < pCond->length; k++) + { + if (pCond->obj[k].type != objType || pCond->obj[k].actor != oldActor) continue; + pCond->obj[k].actor = newActor; break; } - } + // puke... int oldSerial = condSerialize(objType, oldIndex); int newSerial = condSerialize(objType, newIndex); @@ -4778,8 +5189,8 @@ void useCustomDudeSpawn(DBloodActor* pSource, DBloodActor* pSprite) void useDudeSpawn(XSPRITE* pXSource, spritetype* pSprite) { - if (randomSpawnDude(pXSource, pSprite, pSprite->clipdist << 1, 0) == NULL) - nnExtSpawnDude(pXSource, pSprite, pXSource->data1, pSprite->clipdist << 1, 0); + if (randomSpawnDude(&bloodActors[pXSource->reference], &bloodActors[pSprite->index], pSprite->clipdist << 1, 0) == nullptr) + nnExtSpawnDude(&bloodActors[pXSource->reference], &bloodActors[pSprite->index], pXSource->data1, pSprite->clipdist << 1, 0); } bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite, EVENT event) { @@ -4840,7 +5251,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite switch (pXSprite->aiState->stateType) { case kAiStateIdle: case kAiStateGenIdle: - aiActivateDude(&bloodActors[pXSprite->reference]); + aiActivateDude(actor); break; } break; @@ -4867,7 +5278,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite // let's allow only specific commands here to avoid this. if (pSprite->inittype < kDudeBase || pSprite->inittype >= kDudeMax) return false; else if (event.cmd != kCmdToggle && event.cmd != kCmdOff && event.cmd != kCmdSpriteImpact) return true; - DudeToGibCallback1(nSprite, &bloodActors[pSprite->extra]); // set proper gib type just in case DATAs was changed from the outside. + DudeToGibCallback1(nSprite, actor); // set proper gib type just in case DATAs was changed from the outside. return false; case kModernCondition: case kModernConditionFalse: @@ -4905,7 +5316,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case kCmdOn: evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: if (pXSprite->txID > 0) modernTypeSendCommand(nSprite, pXSprite->txID, (COMMAND_ID)pXSprite->command); else if (pXSprite->data1 == 0 && sectRangeIsFine(pSprite->sectnum)) useSpriteDamager(pXSprite, OBJ_SECTOR, pSprite->sectnum); @@ -4934,14 +5345,14 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite useTeleportTarget(pXSprite, pPlayer->pSprite); return true; } - fallthrough__; + [[fallthrough]]; case kModernObjPropertiesChanger: if (pXSprite->txID <= 0) { if (SetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1) == 1) usePropertiesChanger(pXSprite, -1, -1); return true; } - fallthrough__; + [[fallthrough]]; case kModernSlopeChanger: case kModernObjSizeChanger: case kModernObjPicnumChanger: @@ -4959,7 +5370,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); if (pSprite->type == kModernSeqSpawner) seqSpawnerOffSameTx(pXSprite); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: if (pXSprite->txID > 0) modernTypeSendCommand(nSprite, pXSprite->txID, (COMMAND_ID)pXSprite->command); else if (pSprite->type == kModernSeqSpawner) useSeqSpawnerGen(pXSprite, 3, pSprite->index); @@ -4977,13 +5388,13 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case kModernWindGenerator: switch (event.cmd) { case kCmdOff: - windGenStopWindOnSectors(pXSprite); + windGenStopWindOnSectors(actor); if (pXSprite->state == 1) SetSpriteState(nSprite, pXSprite, 0); break; case kCmdOn: evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: if (pXSprite->txID > 0) modernTypeSendCommand(nSprite, pXSprite->txID, (COMMAND_ID)pXSprite->command); else useSectorWindGen(pXSprite, NULL); @@ -5011,7 +5422,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case kCmdOn: evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: if (pXSprite->txID <= 0 || !aiFightGetDudesForBattle(pXSprite)) { aiFightFreeAllTargets(pXSprite); @@ -5038,7 +5449,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case kCmdOn: evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: // force OFF after *all* TX objects reach the goal value if (pSprite->flags == kModernTypeFlag0 && incDecGoalValueIsReached(pXSprite)) { @@ -5064,7 +5475,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case kCmdOn: evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: useRandomItemGen(pSprite, pXSprite); if (pXSprite->busyTime > 0) @@ -5084,7 +5495,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite sfxPlay3DSound(pSprite, 452, 0, 0); evPostActor(actor, 30, kCmdOff); pXSprite->state = 1; - fallthrough__; + [[fallthrough]]; case kCmdOn: sfxPlay3DSound(pSprite, 451, 0, 0); pXSprite->Proximity = 1; @@ -5140,7 +5551,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite else trPlayerCtrlSetScreenEffect(pXSprite, pPlayer); break; case 3: // 67 (start playing qav scene) - trPlayerCtrlStartScene(pXSprite, pPlayer, (pXSprite->data4 == 1) ? true : false); + trPlayerCtrlStartScene(actor, pPlayer, (pXSprite->data4 == 1) ? true : false); break; case 4: // 68 (stop playing qav scene) if (pXSprite->data2 > 0 && pXSprite->data2 != pPlayer->sceneQav) break; @@ -5167,7 +5578,8 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case 9: // 73 (set player's sprite angle, TO-DO: if tx > 0, take a look on TX ID sprite) //data4 is reserved if (pXSprite->data4 != 0) break; - else if (pSprite->flags & kModernTypeFlag1) { + else if (pSprite->flags & kModernTypeFlag1) + { pPlayer->angle.settarget(pSprite->ang); pPlayer->angle.lockinput(); } @@ -5204,7 +5616,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case kCmdOn: evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: if (pXSprite->txID) modernTypeSendCommand(nSprite, pXSprite->txID, (COMMAND_ID)pXSprite->command); else useSoundGen(pXSprite, pSprite); @@ -5226,7 +5638,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case kCmdOn: evKillActor(actor); // queue overflow protect if (pXSprite->state == 0) SetSpriteState(nSprite, pXSprite, 1); - fallthrough__; + [[fallthrough]]; case kCmdRepeat: if (pXSprite->txID) modernTypeSendCommand(nSprite, pXSprite->txID, (COMMAND_ID)pXSprite->command); else useUniMissileGen(pXSprite, pSprite); @@ -5289,7 +5701,7 @@ void seqTxSendCmdAll(XSPRITE* pXSource, int nIndex, COMMAND_ID cmd, bool modernS } } else { for (int i = 0; i <= 3; i++) { - pXSource->txID = GetDataVal(&sprite[pXSource->reference], i); + pXSource->txID = GetDataVal(&bloodActors[pXSource->reference], i); if (pXSource->txID <= 0 || pXSource->txID >= kChannelUserMax) continue; else if (!modernSend) evSendActor(actor, pXSource->txID, cmd); else modernTypeSendCommand(nIndex, pXSource->txID, cmd); @@ -5302,8 +5714,8 @@ void seqTxSendCmdAll(XSPRITE* pXSource, int nIndex, COMMAND_ID cmd, bool modernS void useRandomTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) { - - spritetype* pSource = &sprite[pXSource->reference]; + auto sourceactor = &bloodActors[pXSource->reference]; + spritetype* pSource = &sourceactor->s(); int tx = 0; int maxRetries = kMaxRandomizeRetries; if (txIsRanged(pXSource)) { @@ -5313,7 +5725,7 @@ void useRandomTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) { } } else { while (maxRetries-- >= 0) { - if ((tx = randomGetDataValue(pXSource, kRandomizeTX)) > 0 && tx != pXSource->txID) + if ((tx = randomGetDataValue(sourceactor, kRandomizeTX)) > 0 && tx != pXSource->txID) break; } } @@ -5326,7 +5738,8 @@ void useRandomTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) { void useSequentialTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) { - spritetype* pSource = &sprite[pXSource->reference]; + auto sourceactor = &bloodActors[pXSource->reference]; + spritetype* pSource = &sourceactor->s(); bool range = txIsRanged(pXSource); int cnt = 3; int tx = 0; if (range) { @@ -5348,7 +5761,7 @@ void useSequentialTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) { if (!range) { while (cnt-- >= 0) { // skip empty data fields if (pXSource->sysData1-- < 0) pXSource->sysData1 = 3; - if ((tx = GetDataVal(pSource, pXSource->sysData1)) <= 0) continue; + if ((tx = GetDataVal(sourceactor, pXSource->sysData1)) <= 0) continue; else break; } } else { @@ -5360,7 +5773,7 @@ void useSequentialTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) { if (!range) { while (cnt-- >= 0) { // skip empty data fields if (pXSource->sysData1 > 3) pXSource->sysData1 = 0; - if ((tx = GetDataVal(pSource, pXSource->sysData1++)) <= 0) continue; + if ((tx = GetDataVal(sourceactor, pXSource->sysData1++)) <= 0) continue; else break; } } else { @@ -5490,24 +5903,27 @@ void useRandomItemGen(spritetype* pSource, XSPRITE* pXSource) { } // then drop item - spritetype* pDrop = randomDropPickupObject(pSource, pXSource->dropMsg); + auto dropactor = randomDropPickupObject(&bloodActors[pSource->index], pXSource->dropMsg); - if (pDrop != NULL) { - + if (dropactor != NULL) + { + auto pDrop = &dropactor->s(); clampSprite(pDrop); // check if generator affected by physics - if (debrisGetIndex(pSource->index) != -1 && (pDrop->extra >= 0 || dbInsertXSprite(pDrop->index) > 0)) { - + if (debrisGetIndex(&bloodActors[pSource->index]) != -1) + { + dropactor->addX(); int nIndex = debrisGetFreeIndex(); - if (nIndex >= 0) { - xsprite[pDrop->extra].physAttr |= kPhysMove | kPhysGravity | kPhysFalling; // must fall always + if (nIndex >= 0) + { + dropactor->x().physAttr |= kPhysMove | kPhysGravity | kPhysFalling; // must fall always pSource->cstat &= ~CSTAT_SPRITE_BLOCK; - gPhysSpritesList[nIndex] = &bloodActors[pDrop->index]; + gPhysSpritesList[nIndex] = dropactor; if (nIndex >= gPhysSpritesCount) gPhysSpritesCount++; - getSpriteMassBySize(pDrop); // create mass cache + getSpriteMassBySize(dropactor); // create mass cache } } @@ -5532,8 +5948,8 @@ void useUniMissileGen(XSPRITE* pXSource, spritetype* pSprite) { if (pSprite->cstat & 8) dz = 0x4000; else dz = -0x4000; } else { - dx = CosScale16(pSprite->ang); - dy = SinScale16(pSprite->ang); + dx = bcos(pSprite->ang); + dy = bsin(pSprite->ang); dz = pXSource->data3 << 6; // add slope controlling if (dz > 0x10000) dz = 0x10000; else if (dz < -0x10000) dz = -0x10000; @@ -5739,7 +6155,7 @@ void useSlopeChanger(XSPRITE* pXSource, int objType, int objIndex) { } if (pXSource->data1 == 0) break; - fallthrough__; + [[fallthrough]]; case 1: if (slope == 0) pSect->ceilingstat &= ~0x0002; else if (!(pSect->ceilingstat & 0x0002)) @@ -5943,7 +6359,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) { auto actLeech = leechIsDropped(actor); if (pXSource->data4 == 3) { aiSetTarget_(pXSprite, pSprite->x, pSprite->y, pSprite->z); - aiSetGenIdleState(pSprite, pXSprite); + aiSetGenIdleState(&bloodActors[pSprite->index]); if (pSprite->type == kDudeModernCustom && actLeech) removeLeech(actLeech); } else if (pXSource->data4 == 4) { @@ -6189,27 +6605,28 @@ QAV* playerQavSceneLoad(int qavId) { return pQav; } -void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) { - int nIndex = pQavScene->index; - auto qavactor = &bloodActors[nIndex]; - if (qavactor->hasX()) { - - XSPRITE* pXSprite = &xsprite[sprite[nIndex].extra]; +void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) +{ + auto initiator = pQavScene->initiator; + if (initiator->hasX()) + { + XSPRITE* pXSprite = &initiator->x(); if (pXSprite->waitTime > 0 && --pXSprite->sysData1 <= 0) { if (pXSprite->txID >= kChannelUser) { - XSPRITE* pXSpr = NULL; - for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) { - if (rxBucket[i].type == OBJ_SPRITE) { - + for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) + { + if (rxBucket[i].type == OBJ_SPRITE) + { auto rxactor = rxBucket[i].GetActor(); - if (!rxactor || !rxactor->hasX() || rxactor == qavactor) continue; - spritetype* pSpr = &rxactor->s(); + if (!rxactor || !rxactor->hasX() || rxactor == initiator) continue; - pXSpr = &xsprite[pSpr->extra]; - if (pSpr->type == kModernPlayerControl && pXSpr->command == 67) { + spritetype* pSpr = &rxactor->s(); + auto pXSpr = &rxactor->x(); + if (pSpr->type == kModernPlayerControl && pXSpr->command == 67) + { if (pXSpr->data2 == pXSprite->data2 || pXSpr->locked) continue; - else trPlayerCtrlStartScene(pXSpr, pPlayer, true); + else trPlayerCtrlStartScene(rxactor, pPlayer, true); return; } nnExtTriggerObject(rxBucket[i].type, rxactor->s().index, pXSprite->command); @@ -6232,7 +6649,8 @@ void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) { } } else { - pQavScene->index = pPlayer->sceneQav = -1; + pQavScene->initiator = nullptr; + pPlayer->sceneQav = -1; pQavScene->qavResrc = NULL; } } @@ -6241,7 +6659,7 @@ void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5) { if (pPlayer == NULL || pPlayer->sceneQav == -1) return; QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; - spritetype* pSprite = &sprite[pQavScene->index]; + spritetype* pSprite = &pQavScene->initiator->s(); if (pQavScene->qavResrc != NULL) { @@ -6277,8 +6695,8 @@ void playerQavScenePlay(PLAYER* pPlayer) { if (pPlayer == NULL) return; QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; - if (pPlayer->sceneQav == -1 && pQavScene->index >= 0) - pPlayer->sceneQav = xsprite[sprite[pQavScene->index].extra].data2; + if (pPlayer->sceneQav == -1 && pQavScene->initiator != nullptr) + pPlayer->sceneQav = pQavScene->initiator->x().data2; if (pQavScene->qavResrc != NULL) { QAV* pQAV = pQavScene->qavResrc; @@ -6290,7 +6708,8 @@ void playerQavScenePlay(PLAYER* pPlayer) { void playerQavSceneReset(PLAYER* pPlayer) { QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; - pQavScene->index = pQavScene->dummy = pPlayer->sceneQav = -1; + pQavScene->initiator = nullptr; + pQavScene->dummy = pPlayer->sceneQav = -1; pQavScene->qavResrc = NULL; } @@ -6501,6 +6920,7 @@ bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value) { // a replacement of vanilla CanMove for patrol dudes bool nnExtCanMove(spritetype* pSprite, int nTarget, int nAngle, int nRange) { + auto actor = &bloodActors[pSprite->index]; int x = pSprite->x, y = pSprite->y, z = pSprite->z, nSector = pSprite->sectnum; HitScan(pSprite, z, Cos(nAngle) >> 16, Sin(nAngle) >> 16, 0, CLIPMASK0, nRange); int nDist = approxDist(x - gHitInfo.hitx, y - gHitInfo.hity); @@ -6515,7 +6935,7 @@ bool nnExtCanMove(spritetype* pSprite, int nTarget, int nAngle, int nRange) { if (sector[nSector].extra > 0) { XSECTOR* pXSector = &xsector[sector[nSector].extra]; - return !((sector[nSector].type == kSectorDamage || pXSector->damageType > 0) && pXSector->state && !nnExtIsImmune(pSprite, pXSector->damageType, 16)); + return !((sector[nSector].type == kSectorDamage || pXSector->damageType > 0) && pXSector->state && !nnExtIsImmune(actor, pXSector->damageType, 16)); } @@ -6968,21 +7388,20 @@ void aiPatrolMove(DBloodActor* actor) { if (abs(nAng) > goalAng || ((pXTarget->waitTime > 0 || pXTarget->data1 == pXTarget->data2) && aiPatrolMarkerReached(pSprite, pXSprite))) { - xvel[pSprite->index] = 0; - yvel[pSprite->index] = 0; + actor->xvel() = 0; + actor->yvel() = 0; return; } - if ((gSpriteHit[pSprite->extra].hit & 0xc000) == 0xc000) { - - int nHSprite = gSpriteHit[pSprite->extra].hit & 0x3fff; - XSPRITE* pXSprite2 = &xsprite[sprite[nHSprite].extra]; + if (gSpriteHit[pSprite->extra].hit.type == kHitSprite) + { + auto hitactor = gSpriteHit[pSprite->extra].hit.actor; - pXSprite2->dodgeDir = -1; + hitactor->x().dodgeDir = -1; pXSprite->dodgeDir = 1; - aiMoveDodge(&bloodActors[pXSprite->reference]); + aiMoveDodge(hitactor); } else { @@ -7112,11 +7531,12 @@ bool spritesTouching(int nXSprite1, int nXSprite2) { if (!xspriRangeIsFine(nXSprite1) || !xspriRangeIsFine(nXSprite2)) return false; - int nHSprite = -1; - if ((gSpriteHit[nXSprite1].hit & 0xc000) == 0xc000) nHSprite = gSpriteHit[nXSprite1].hit & 0x3fff; - else if ((gSpriteHit[nXSprite1].florhit & 0xc000) == 0xc000) nHSprite = gSpriteHit[nXSprite1].florhit & 0x3fff; - else if ((gSpriteHit[nXSprite1].ceilhit & 0xc000) == 0xc000) nHSprite = gSpriteHit[nXSprite1].ceilhit & 0x3fff; - return (spriRangeIsFine(nHSprite) && sprite[nHSprite].extra == nXSprite2); + DBloodActor* hitactor = nullptr; + if (gSpriteHit[nXSprite1].hit.type == kHitSprite) hitactor = gSpriteHit[nXSprite1].hit.actor; + else if (gSpriteHit[nXSprite1].florhit.type == kHitSprite) hitactor = gSpriteHit[nXSprite1].florhit.actor; + else if (gSpriteHit[nXSprite1].ceilhit.type == kHitSprite) hitactor = gSpriteHit[nXSprite1].ceilhit.actor; + else return false; + return hitactor->hasX() && hitactor->s().extra == nXSprite2; } bool aiCanCrouch(spritetype* pSprite) { @@ -7742,13 +8162,13 @@ int listTx(XSPRITE* pXRedir, int tx) { } else { if (tx == -1) { for (int i = 0; i <= 3; i++) { - if ((tx = GetDataVal(&sprite[pXRedir->reference], i)) <= 0) continue; + if ((tx = GetDataVal(&bloodActors[pXRedir->reference], i)) <= 0) continue; else return tx; } } else { int saved = tx; bool savedFound = false; for (int i = 0; i <= 3; i++) { - tx = GetDataVal(&sprite[pXRedir->reference], i); + tx = GetDataVal(&bloodActors[pXRedir->reference], i); if (savedFound && tx > 0) return tx; else if (tx != saved) continue; else savedFound = true; @@ -7998,7 +8418,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, OBJECTS_TO_TRACK& if (arc.BeginObject(keyname)) { arc("type", w.type, &nul.type) - ("index", w.index, &nul.index) + ("index", w.index_, &nul.index_) ("xrepeat", w.cmd, &nul.cmd) .EndObject(); } @@ -8012,7 +8432,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, TRCONDITION& w, TR if (arc.BeginObject(keyname)) { arc("length", w.length, &nul.length) - ("xindex", w.xindex, &nul.xindex) + ("xindex", w.actor, &nul.actor) .Array("obj", w.obj, w.length) .EndObject(); } diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index ecf07cdf3..f87421ac3 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -199,8 +199,8 @@ struct SPRITEMASS { // sprite mass info for getSpriteMassBySize(); }; struct QAVSCENE { // this one stores qavs anims that can be played by trigger - short index = -1; // index of sprite which triggered qav scene - QAV* qavResrc = NULL; + DBloodActor* initiator = nullptr; // index of sprite which triggered qav scene + QAV* qavResrc = nullptr; short dummy = -1; }; @@ -237,12 +237,13 @@ struct TRPLAYERCTRL { // this one for controlling the player using triggers (mov struct OBJECTS_TO_TRACK { int8_t type; uint8_t cmd; - int index; + unsigned int index_; + DBloodActor* actor; }; struct TRCONDITION { - signed int xindex; - unsigned int length; + DBloodActor* actor; + uint8_t length; OBJECTS_TO_TRACK obj[kMaxTracedObjects]; }; @@ -291,28 +292,23 @@ inline bool xsprIsFine(spritetype* pSpr) { return (pSpr && xspriRangeIsFine(pSpr->extra) && !(pSpr->flags & kHitagFree) && !(pSpr->flags & kHitagRespawn)); } // - FUNCTIONS ------------------------------------------------------------------ -bool nnExtEraseModernStuff(spritetype* pSprite, XSPRITE* pXSprite); +bool nnExtEraseModernStuff(DBloodActor* actor); void nnExtInitModernStuff(bool bSaveLoad); void nnExtProcessSuperSprites(void); -bool nnExtIsImmune(spritetype* pSprite, int dmgType, int minScale = 16); +bool nnExtIsImmune(DBloodActor* pSprite, int dmgType, int minScale = 16); int nnExtRandom(int a, int b); void nnExtResetGlobals(); void nnExtTriggerObject(int objType, int objIndex, int command); // ------------------------------------------------------------------------- // -spritetype* randomDropPickupObject(spritetype* pSprite, short prevItem); -spritetype* randomSpawnDude(XSPRITE* pXSource, spritetype* pSprite, int a3, int a4); -int GetDataVal(spritetype* pSprite, int data); -int randomGetDataValue(XSPRITE* pXSprite, int randType); -void sfxPlayMissileSound(spritetype* pSprite, int missileId); -void sfxPlayVectorSound(spritetype* pSprite, int vectorId); +void sfxPlayMissileSound(DBloodActor* pSprite, int missileId); +void sfxPlayVectorSound(DBloodActor* pSprite, int vectorId); // ------------------------------------------------------------------------- // -int debrisGetIndex(int nSprite); int debrisGetFreeIndex(void); -void debrisBubble(int nSprite); +void debrisBubble(DBloodActor* nSprite); void debrisMove(int listIndex); -void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg); +void debrisConcuss(DBloodActor* nOwner, int listIndex, int x, int y, int z, int dmg); // ------------------------------------------------------------------------- // -void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite); +void aiSetGenIdleState(DBloodActor*); // triggers related // ------------------------------------------------------------------------- // @@ -358,7 +354,6 @@ void seqTxSendCmdAll(XSPRITE* pXSource, int nIndex, COMMAND_ID cmd, bool modernS // ------------------------------------------------------------------------- // void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition); void trPlayerCtrlSetRace(XSPRITE* pXSource, PLAYER* pPlayer); -void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force); void trPlayerCtrlStopScene(PLAYER* pPlayer); void trPlayerCtrlSetMoveSpeed(XSPRITE* pXSource, PLAYER* pPlayer); void trPlayerCtrlSetJumpHeight(XSPRITE* pXSource, PLAYER* pPlayer); @@ -400,9 +395,8 @@ bool isActive(int nSprite); int getDataFieldOfObject(int objType, int objIndex, DBloodActor* objActor, int dataIndex); bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value); bool incDecGoalValueIsReached(XSPRITE* pXSprite); -void windGenStopWindOnSectors(XSPRITE* pXSource); -int getSpriteMassBySize(spritetype* pSprite); -bool ceilIsTooLow(spritetype* pSprite); +int getSpriteMassBySize(DBloodActor* pSprite); +bool ceilIsTooLow(DBloodActor* pSprite); void levelEndLevelCustom(int nLevel); int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event); bool condPush(XSPRITE* pXSprite, int objType, int objIndex); diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 7a6fa4688..5658c2dab 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -267,7 +267,7 @@ char powerupActivate(PLAYER *pPlayer, int nPowerUp) pPlayer->pwUpTime[kPwUpShadowCloak] = 0; } - if (ceilIsTooLow(pPlayer->pSprite)) + if (ceilIsTooLow(pPlayer->actor())) actDamageSprite(pPlayer->actor(), pPlayer->actor(), kDamageExplode, 65535); } break; @@ -315,7 +315,7 @@ void powerupDeactivate(PLAYER *pPlayer, int nPowerUp) case kItemShroomShrink: if (gModernMap) { playerSizeReset(pPlayer); - if (ceilIsTooLow(pPlayer->pSprite)) + if (ceilIsTooLow(pPlayer->actor())) actDamageSprite(pPlayer->actor(), pPlayer->actor(), kDamageExplode, 65535); } break; @@ -724,7 +724,7 @@ void playerStart(int nPlayer, int bNewLevel) pPlayer->throwPower = 0; pPlayer->deathTime = 0; pPlayer->nextWeapon = kWeapNone; - xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0; + actor->xvel() = actor->yvel() = actor->zvel() = 0; pInput->avel = 0; pInput->actions = 0; pInput->fvel = 0; @@ -1245,8 +1245,8 @@ int ActionScan(PLAYER *pPlayer, int *a2, int *a3) *a2 = 0; *a3 = 0; spritetype *pSprite = pPlayer->pSprite; - int x = CosScale16(pSprite->ang); - int y = SinScale16(pSprite->ang); + int x = bcos(pSprite->ang); + int y = bsin(pSprite->ang); int z = pPlayer->slope; int hit = HitScan(pSprite, pPlayer->zView, x, y, z, 0x10000040, 128); int hitDist = approxDist(pSprite->x-gHitInfo.hitx, pSprite->y-gHitInfo.hity)>>4; @@ -1338,8 +1338,8 @@ void doslopetilting(PLAYER* pPlayer, double const scaleAdjust = 1) { auto* const pSprite = pPlayer->pSprite; auto* const pXSprite = pPlayer->pXSprite; - int const florhit = gSpriteHit[pSprite->extra].florhit & 0xc000; - char const va = pXSprite->height < 16 && (florhit == 0x4000 || florhit == 0) ? 1 : 0; + int const florhit = gSpriteHit[pSprite->extra].florhit.type; + char const va = pXSprite->height < 16 && (florhit == kHitSector || florhit == 0) ? 1 : 0; pPlayer->horizon.calcviewpitch(pSprite->pos.vec2, buildang(pSprite->ang), va, sector[pSprite->sectnum].floorstat & 2, pSprite->sectnum, scaleAdjust); } @@ -1380,7 +1380,7 @@ void ProcessInput(PLAYER *pPlayer) } pPlayer->deathTime += 4; if (!bSeqStat) - pPlayer->horizon.addadjustment(FixedToFloat(MulScale(0x8000-(Cos(ClipHigh(pPlayer->deathTime<<3, 1024))>>15), gi->playerHorizMax(), 16) - pPlayer->horizon.horiz.asq16())); + pPlayer->horizon.addadjustment(q16horiz(MulScale(0x8000-(Cos(ClipHigh(pPlayer->deathTime<<3, 1024))>>15), gi->playerHorizMax(), 16) - pPlayer->horizon.horiz.asq16())); if (pPlayer->curWeapon) pInput->setNewWeapon(pPlayer->curWeapon); if (pInput->actions & SB_OPEN) @@ -1579,8 +1579,8 @@ void ProcessInput(PLAYER *pPlayer) spritetype* pSprite2 = &spawned->s(); pSprite2->ang = (pPlayer->pSprite->ang+1024)&2047; int nSprite = pPlayer->pSprite->index; - int x = CosScale16(pPlayer->pSprite->ang); - int y = SinScale16(pPlayer->pSprite->ang); + int x = bcos(pPlayer->pSprite->ang); + int y = bsin(pPlayer->pSprite->ang); xvel[pSprite2->index] = xvel[nSprite] + MulScale(0x155555, x, 14); yvel[pSprite2->index] = yvel[nSprite] + MulScale(0x155555, y, 14); zvel[pSprite2->index] = zvel[nSprite]; @@ -1667,8 +1667,8 @@ void playerProcess(PLAYER *pPlayer) int dw = pSprite->clipdist<<2; if (!gNoClip) { - short nSector = pSprite->sectnum; - if (pushmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, dw, dzt, dzb, CLIPMASK0) == -1) + int nSector = pSprite->sectnum; + if (pushmove(&pSprite->pos, &nSector, dw, dzt, dzb, CLIPMASK0) == -1) actDamageSprite(actor, actor, kDamageFall, 500<<4); if (pSprite->sectnum != nSector) { @@ -2123,9 +2123,9 @@ void voodooTarget(PLAYER *pPlayer) for (int i = 0; i < 4; i++) { int ang1 = (pPlayer->voodooVar1+pPlayer->vodooVar2)&2047; - actFireVector(actor, 0, dz, CosScale16(ang1), SinScale16(ang1), v4, kVectorVoodoo10); + actFireVector(actor, 0, dz, bcos(ang1), bsin(ang1), v4, kVectorVoodoo10); int ang2 = (pPlayer->voodooVar1+2048-pPlayer->vodooVar2)&2047; - actFireVector(actor, 0, dz, CosScale16(ang2), SinScale16(ang2), v4, kVectorVoodoo10); + actFireVector(actor, 0, dz, bcos(ang2), bsin(ang2), v4, kVectorVoodoo10); } pPlayer->voodooTargets = ClipLow(pPlayer->voodooTargets-1, 0); } @@ -2151,11 +2151,11 @@ void playerLandingSound(PLAYER *pPlayer) }; spritetype *pSprite = pPlayer->pSprite; SPRITEHIT *pHit = &gSpriteHit[pSprite->extra]; - if (pHit->florhit) + if (pHit->florhit.type != kHitNone) { - if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pPlayer, &sprite[pHit->florhit & 0x3fff])) + if (!gGameOptions.bFriendlyFire && pHit->florhit.type == kHitSprite && IsTargetTeammate(pPlayer, &pHit->florhit.actor->s())) return; - char nSurf = tileGetSurfType(pHit->florhit); + int nSurf = tileGetSurfType(pHit->florhit); if (nSurf) sfxPlay3DSound(pSprite, surfaceSound[nSurf], -1, 0); } @@ -2355,7 +2355,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, TRPLAYERCTRL& w, T { if (arc.BeginObject(keyname)) { - arc("index", w.qavScene.index) + arc("index", w.qavScene.initiator) ("dummy", w.qavScene.dummy) .EndObject(); } diff --git a/source/games/blood/src/prediction.cpp b/source/games/blood/src/prediction.cpp index 69403dd43..7a8c9b376 100644 --- a/source/games/blood/src/prediction.cpp +++ b/source/games/blood/src/prediction.cpp @@ -232,9 +232,9 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) #endif int nSector = predict.sectnum; - int florhit = predict.at75.florhit & 0xc000; + int florhit = predict.at75.florhit.type; char va; - if (predict.floordist < 16 && (florhit == 0x4000 || florhit == 0)) + if (predict.floordist < 16 && (florhit == kHitSector || florhit == 0)) va = 1; else va = 0; @@ -243,17 +243,17 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) int z1 = getflorzofslope(nSector, predict.x, predict.y); int x2 = predict.x+MulScale(64, Cos(predict.angle.asbuild()), 30); int y2 = predict.y+MulScale(64, Sin(predict.angle.asbuild()), 30); - short nSector2 = nSector; + int nSector2 = nSector; updatesector(x2, y2, &nSector2); if (nSector2 == nSector) { int z2 = getflorzofslope(nSector2, x2, y2); - predict.horizoff = q16horiz(interpolatedvalue(predict.horizoff.asq16(), IntToFixed(z1 - z2) >> 3, 0x4000)); + predict.horizoff = interpolatedhorizon(predict.horizoff, q16horiz((z1 - z2) << 13), 0x4000); } } else { - predict.horizoff = q16horiz(interpolatedvalue(predict.horizoff.asq16(), 0, 0x4000)); + predict.horizoff = interpolatedhorizon(predict.horizoff, q16horiz(0), 0x4000); if (abs(predict.horizoff.asq16()) < 4) predict.horizoff = q16horiz(0); } @@ -279,7 +279,7 @@ void fakePlayerProcess(PLAYER *pPlayer, InputPacket *pInput) short nSector = predict.sectnum; if (!gNoClip) { - pushmove_old((int32_t*)&predict.x, (int32_t*)&predict.y, (int32_t*)&predict.z, &predict.sectnum, dw, dzt, dzb, CLIPMASK0); + pushmove(&predict.pos, &predict.sectnum, dw, dzt, dzb, CLIPMASK0); if (predict.sectnum == -1) predict.sectnum = nSector; } @@ -383,14 +383,14 @@ static void fakeMoveDude(spritetype *pSprite) { short bakCstat = pSprite->cstat; pSprite->cstat &= ~257; - predict.at75.hit = ClipMove(&predict.x, &predict.y, &predict.z, &nSector, predict.xvel >> 12, predict.yvel >> 12, wd, tz, bz, CLIPMASK0); + predict.at75.hit = ClipMove(&predict.pos, &nSector, predict.xvel >> 12, predict.yvel >> 12, wd, tz, bz, CLIPMASK0); if (nSector == -1) nSector = predict.sectnum; if (sector[nSector].type >= kSectorPath && sector[nSector].type <= kSectorRotate) { - short nSector2 = nSector; - pushmove_old((int32_t*)&predict.x, (int32_t*)&predict.y, (int32_t*)&predict.z, &nSector2, wd, tz, bz, CLIPMASK0); + int nSector2 = nSector; + pushmove(&predict.pos, &nSector2, wd, tz, bz, CLIPMASK0); if (nSector2 != -1) nSector = nSector2; } @@ -399,11 +399,11 @@ static void fakeMoveDude(spritetype *pSprite) pSprite->cstat = bakCstat; } - switch (predict.at75.hit&0xc000) + switch (predict.at75.hit.type) { - case 0x8000: + case kHitSprite: { - int nHitWall = predict.at75.hit&0x3fff; + int nHitWall = predict.at75.hit.index; walltype *pHitWall = &wall[nHitWall]; if (pHitWall->nextsector != -1) { @@ -453,8 +453,9 @@ static void fakeMoveDude(spritetype *pSprite) pTempSprite->y = predict.y; pTempSprite->z = predict.z; pTempSprite->sectnum = predict.sectnum; - int ceilZ, ceilHit, floorZ, floorHit; - GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0); + int ceilZ, floorZ; + Collision ceilColl, floorColl; + GetZRange(pTempSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, wd, CLIPMASK0); GetSpriteExtents(pTempSprite, &top, &bottom); if (predict.at73 & 2) { @@ -493,17 +494,17 @@ static void fakeMoveDude(spritetype *pSprite) if (bottom >= floorZ) { int floorZ2 = floorZ; - int floorHit2 = floorHit; - GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist<<2, CLIPMASK0, PARALLAXCLIP_CEILING|PARALLAXCLIP_FLOOR); + auto floorHit2 = floorColl; + GetZRange(pTempSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist<<2, CLIPMASK0, PARALLAXCLIP_CEILING|PARALLAXCLIP_FLOOR); if (bottom <= floorZ && predict.z-floorZ2 < bz) { floorZ = floorZ2; - floorHit = floorHit2; + floorColl = floorHit2; } } if (floorZ <= bottom) { - predict.at75.florhit = floorHit; + predict.at75.florhit = floorColl; predict.z += floorZ-bottom; int var44 = predict.zvel-velFloor[predict.sectnum]; if (var44 > 0) @@ -523,13 +524,13 @@ static void fakeMoveDude(spritetype *pSprite) } else { - predict.at75.florhit = 0; + predict.at75.florhit.setNone(); if (predict.at73 & 2) predict.at73 |= 4; } if (top <= ceilZ) { - predict.at75.ceilhit = ceilHit; + predict.at75.ceilhit = ceilColl; predict.z += ClipLow(ceilZ-top, 0); if (predict.zvel <= 0 && (predict.at73&4)) predict.zvel = MulScale(-predict.zvel, 0x2000, 16); @@ -542,13 +543,13 @@ static void fakeMoveDude(spritetype *pSprite) predict.floordist = ClipLow(floorZ-bottom, 0)>>8; if (predict.xvel || predict.yvel) { - if ((floorHit & 0xc000) == 0xc000) + if (floorColl.type == kHitSprite) { - int nHitSprite = floorHit & 0x3fff; - if ((sprite[nHitSprite].cstat & 0x30) == 0) + auto hitactor = floorColl.actor; + if ((hitactor->s().cstat & 0x30) == 0) { - predict.xvel += MulScale(4, predict.x - sprite[nHitSprite].x, 2); - predict.yvel += MulScale(4, predict.y - sprite[nHitSprite].y, 2); + predict.xvel += MulScale(4, predict.x - hitactor->s().x, 2); + predict.yvel += MulScale(4, predict.y - hitactor->s().y, 2); return; } } diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 43f18258a..3f30a957d 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -147,14 +147,11 @@ void DrawFrame(double x, double y, double z, double a, double alpha, int picnum, } -static QAVInterpProps forcedinterpdata{qavGetInterpType("picnum")}; - void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio) { assert(ticksPerFrame > 0); - QAVInterpProps* interpdata = qavInterpProps.CheckKey(res_id); - if (!interpdata && cl_bloodqavforcedinterp) interpdata = &forcedinterpdata; + auto const interpdata = qavInterpProps.CheckKey(res_id); auto const nFrame = clamp(ticks / ticksPerFrame, 0, nFrames - 1); FRAMEINFO* const thisFrame = &frames[nFrame]; diff --git a/source/games/blood/src/sectorfx.cpp b/source/games/blood/src/sectorfx.cpp index 4d91c4529..b82e50a37 100644 --- a/source/games/blood/src/sectorfx.cpp +++ b/source/games/blood/src/sectorfx.cpp @@ -370,63 +370,5 @@ void InitSectorFX(void) } } -class CSectorListMgr -{ -public: - CSectorListMgr(); - int CreateList(short); - void AddSector(int, short); - int GetSectorCount(int); - short *GetSectorList(int); -private: - int nLists; - int nListSize[32]; - int nListStart[32]; - short nSectors[kMaxSectors]; -}; - -CSectorListMgr::CSectorListMgr() -{ - nLists = 0; -} - -int CSectorListMgr::CreateList(short nSector) -{ - int nStart = 0; - if (nLists) - nStart = nListStart[nLists-1]+nListStart[nLists-1]; - int nList = nLists; - nListStart[nList] = nStart; - nListSize[nList] = 1; - nLists++; - short *pList = GetSectorList(nList); - pList[0] = nSector; - return nList; -} - -void CSectorListMgr::AddSector(int nList, short nSector) -{ - for (int i = nLists; i > nList; i--) - { - short *pList = GetSectorList(i); - int nCount = GetSectorCount(i); - memmove(pList+1,pList,nCount*sizeof(short)); - nListStart[i]++; - } - short *pList = GetSectorList(nList); - int nCount = GetSectorCount(nList); - pList[nCount] = nSector; - nListSize[nList]++; -} - -int CSectorListMgr::GetSectorCount(int nList) -{ - return nListSize[nList]; -} - -short * CSectorListMgr::GetSectorList(int nList) -{ - return nSectors+nListStart[nList]; -} END_BLD_NS diff --git a/source/games/blood/src/seq.cpp b/source/games/blood/src/seq.cpp index 11cb2abac..3933b62c3 100644 --- a/source/games/blood/src/seq.cpp +++ b/source/games/blood/src/seq.cpp @@ -369,7 +369,8 @@ void SEQINST::Update() if (!VanillaMode() && pSequence->frames[frameIndex].surfaceSound && zvel[pSprite->index] == 0 && xvel[pSprite->index] != 0) { if (gUpperLink[pSprite->sectnum] >= 0) break; // don't play surface sound for stacked sectors - int surf = tileGetSurfType(pSprite->sectnum + 0x4000); if (!surf) break; + int surf = tileGetSurfType(sector[pSprite->sectnum].floorpicnum); + if (!surf) break; static int surfSfxMove[15][4] = { /* {snd1, snd2, gameVolume, myVolume} */ {800,801,80,25}, diff --git a/source/games/blood/src/sound.cpp b/source/games/blood/src/sound.cpp index d3a626cb5..337261ac3 100644 --- a/source/games/blood/src/sound.cpp +++ b/source/games/blood/src/sound.cpp @@ -177,7 +177,7 @@ void sndStartSample(unsigned int nSound, int nVolume, int nChannel, bool bLoop, if (nVolume < 0) { auto udata = soundEngine->GetUserData(snd); - if (udata) nVolume = std::min(Scale(udata[2], 255, 100), 255); + if (udata) nVolume = min(Scale(udata[2], 255, 100), 255); else nVolume = 255; } if (bLoop) chanflags |= CHANF_LOOP; diff --git a/source/games/blood/src/tile.cpp b/source/games/blood/src/tile.cpp index f00d2cf02..906979900 100644 --- a/source/games/blood/src/tile.cpp +++ b/source/games/blood/src/tile.cpp @@ -71,21 +71,24 @@ void GameInterface::LoadGameTextures() } } -char tileGetSurfType(int hit) +int tileGetSurfType(int hit) { - int n = hit & 0x3fff; - switch (hit&0xc000) + return surfType[hit]; +} + +int tileGetSurfType(Collision& hit) +{ + switch (hit.type) { - case 0x4000: - return surfType[sector[n].floorpicnum]; - case 0x6000: - return surfType[sector[n].ceilingpicnum]; - case 0x8000: - return surfType[wall[n].picnum]; - case 0xc000: - return surfType[sprite[n].picnum]; + default: + return 0; + case kHitSector: + return surfType[sector[hit.index].floorpicnum]; + case kHitWall: + return surfType[wall[hit.index].picnum]; + case kHitSprite: + return surfType[hit.actor->s().picnum]; } - return 0; } void GameInterface::SetTileProps(int tile, int surf, int vox, int shade) diff --git a/source/games/blood/src/trig.cpp b/source/games/blood/src/trig.cpp index e7e3b878c..34856a47a 100644 --- a/source/games/blood/src/trig.cpp +++ b/source/games/blood/src/trig.cpp @@ -27,8 +27,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -int costable[2048]; - int OctantTable[8] = { 5, 6, 2, 1, 4, 7, 3, 0 }; int GetOctant(int x, int y) @@ -53,27 +51,4 @@ void RotatePoint(int *x, int *y, int nAngle, int ox, int oy) *y = oy+dmulscale30r(dx, Sin(nAngle), dy, Cos(nAngle)); } -void trigInit() -{ - auto fr = fileSystem.OpenFileReader("cosine.dat"); - auto len = fr.Read(costable, 2048); - if (len != 2048) - I_Error("Cosine table incorrect size"); -#if B_BIG_ENDIAN == 1 - for (int i = 0; i < 512; i++) - { - costable[i] = LittleLong(costable[i]); - } -#endif - costable[512] = 0; - for (int i = 513; i <= 1024; i++) - { - costable[i] = -costable[1024-i]; - } - for (int i = 1025; i < 2048; i++) - { - costable[i] = costable[2048 - i]; - } -} - END_BLD_NS diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index 43323631f..8208366a4 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -248,8 +248,8 @@ void LifeLeechOperate(spritetype *pSprite, XSPRITE *pXSprite, EVENT event) y += (yvel[nTarget]*t)>>12; int angBak = pSprite->ang; pSprite->ang = getangle(x-pSprite->x, y-pSprite->y); - int dx = CosScale16(pSprite->ang); - int dy = SinScale16(pSprite->ang); + int dx = bcos(pSprite->ang); + int dy = bsin(pSprite->ang); int tz = pTarget->z - (pTarget->yrepeat * pDudeInfo->aimHeight) * 4; int dz = DivScale(tz - top - 256, nDist, 10); int nMissileType = kMissileLifeLeechAltNormal + (pXSprite->data3 ? 1 : 0); @@ -2258,7 +2258,7 @@ void FireballTrapSeqCallback(int, DBloodActor* actor) if (pSprite->cstat&32) actFireMissile(actor, 0, 0, 0, 0, (pSprite->cstat&8) ? 0x4000 : -0x4000, kMissileFireball); else - actFireMissile(actor, 0, 0, CosScale16(pSprite->ang), SinScale16(pSprite->ang), 0, kMissileFireball); + actFireMissile(actor, 0, 0, bcos(pSprite->ang), bsin(pSprite->ang), 0, kMissileFireball); } @@ -2274,8 +2274,8 @@ void MGunFireSeqCallback(int, DBloodActor* actor) if (pXSprite->data2 == 0) evPostActor(&bloodActors[pXSprite->reference], 1, kCmdOff); } - int dx = CosScale16(pSprite->ang)+Random2(1000); - int dy = SinScale16(pSprite->ang)+Random2(1000); + int dx = bcos(pSprite->ang)+Random2(1000); + int dy = bsin(pSprite->ang)+Random2(1000); int dz = Random2(1000); actFireVector(actor, 0, 0, dx, dy, dz, kVectorBullet); sfxPlay3DSound(pSprite, 359, -1, 0); diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index 7382172cd..2d109ca08 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -333,12 +333,12 @@ void viewUpdateDelirium(void) tilt2 = MulScale(tilt2, powerScale, 16); pitch = MulScale(pitch, powerScale, 16); } - int sin2 = costable[(2*timer-512)&2047] / 2; - int sin3 = costable[(3*timer-512)&2047] / 2; + int sin2 = Sin(2*timer) >> 1; + int sin3 = Sin(3*timer) >> 1; gScreenTilt = MulScale(sin2+sin3,tilt1, 30); - int sin4 = costable[(4*timer-512)&2047] / 2; + int sin4 = Sin(4*timer) >> 1; deliriumTurn = MulScale(sin3+sin4,tilt2, 30); - int sin5 = costable[(5*timer-512)&2047] / 2; + int sin5 = Sin(5*timer) >> 1; deliriumPitch = MulScale(sin4+sin5,pitch, 30); return; } @@ -359,43 +359,22 @@ void viewUpdateDelirium(void) void viewUpdateShake(int& cX, int& cY, int& cZ, binangle& cA, fixedhoriz& cH, double& pshakeX, double& pshakeY) { - int shakeHoriz = 0; - int shakeAngle = 0; - int shakeX = 0; - int shakeY = 0; - int shakeZ = 0; - int shakeBobX = 0; - int shakeBobY = 0; - if (gView->flickerEffect) + auto doEffect = [&](const int& effectType) { - int nValue = ClipHigh(gView->flickerEffect * 8, 2000); - shakeHoriz += QRandom2(nValue >> 8); - shakeAngle += QRandom2(nValue >> 8); - shakeX += QRandom2(nValue >> 4); - shakeY += QRandom2(nValue >> 4); - shakeZ += QRandom2(nValue); - shakeBobX += QRandom2(nValue); - shakeBobY += QRandom2(nValue); - } - if (gView->quakeEffect) - { - int nValue = ClipHigh(gView->quakeEffect * 8, 2000); - shakeHoriz += QRandom2(nValue >> 8); - shakeAngle += QRandom2(nValue >> 8); - shakeX += QRandom2(nValue >> 4); - shakeY += QRandom2(nValue >> 4); - shakeZ += QRandom2(nValue); - shakeBobX += QRandom2(nValue); - shakeBobY += QRandom2(nValue); - } - cH += buildhoriz(shakeHoriz); - cA += buildang(shakeAngle); - cX += shakeX; - cY += shakeY; - cZ += shakeZ; - pshakeX += shakeBobX; - pshakeY += shakeBobY; - + if (effectType) + { + int nValue = ClipHigh(effectType * 8, 2000); + cH += buildhoriz(QRandom2(nValue >> 8)); + cA += buildang(QRandom2(nValue >> 8)); + cX += QRandom2(nValue >> 4); + cY += QRandom2(nValue >> 4); + cZ += QRandom2(nValue); + pshakeX += QRandom2(nValue); + pshakeY += QRandom2(nValue); + } + }; + doEffect(gView->flickerEffect); + doEffect(gView->quakeEffect); } @@ -445,14 +424,8 @@ void SetupView(int &cX, int& cY, int& cZ, binangle& cA, fixedhoriz& cH, int& nSe } else { - auto oang = predictOld.angle + predictOld.look_ang; - auto ang = predict.angle + predict.look_ang; - cA = interpolatedangle(oang, ang, gInterpolate); - - fixed_t ohoriz = (predictOld.horiz + predictOld.horizoff).asq16(); - fixed_t horiz = (predict.horiz + predict.horizoff).asq16(); - cH = q16horiz(interpolatedvalue(ohoriz, horiz, gInterpolate)); - + cA = interpolatedangle(predictOld.angle + predictOld.look_ang, predict.angle + predict.look_ang, gInterpolate); + cH = interpolatedhorizon(predictOld.horiz + predictOld.horizoff, predict.horiz + predict.horizoff, gInterpolate); rotscrnang = interpolatedangle(predictOld.rotscrnang, predict.rotscrnang, gInterpolate); } } @@ -501,7 +474,7 @@ void SetupView(int &cX, int& cY, int& cZ, binangle& cA, fixedhoriz& cH, int& nSe } else { - calcChaseCamPos((int*)&cX, (int*)&cY, (int*)&cZ, gView->pSprite, (short*)&nSectnum, cA, cH, gInterpolate); + calcChaseCamPos((int*)&cX, (int*)&cY, (int*)&cZ, gView->pSprite, &nSectnum, cA, cH, gInterpolate); } CheckLink((int*)&cX, (int*)&cY, (int*)&cZ, &nSectnum); } @@ -717,8 +690,9 @@ void viewDrawScreen(bool sceneonly) bDeliriumOld = bDelirium && gDeliriumBlur; int nClipDist = gView->pSprite->clipdist << 2; - int ve8, vec, vf0, vf4; - GetZRange(gView->pSprite, &vf4, &vf0, &vec, &ve8, nClipDist, 0); + int vec, vf4; + Collision c1, c2; + GetZRange(gView->pSprite, &vf4, &c1, &vec, &c2, nClipDist, 0); if (sceneonly) return; #if 0 int tmpSect = nSectnum; @@ -806,7 +780,8 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a, double const s if (i == gView->nPlayer || gGameOptions.nGameType == 1) { int nTile = pSprite->picnum; - int ceilZ, ceilHit, floorZ, floorHit; + int ceilZ, floorZ; + Collision ceilHit, floorHit; GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR); int nTop, nBottom; GetSpriteExtents(pSprite, &nTop, &nBottom); diff --git a/source/games/blood/src/view.h b/source/games/blood/src/view.h index aefecfdb4..e0e52ad3b 100644 --- a/source/games/blood/src/view.h +++ b/source/games/blood/src/view.h @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "messages.h" #include "player.h" #include "interpolate.h" +#include "bloodactor.h" BEGIN_BLD_NS @@ -51,13 +52,17 @@ struct VIEW { int at44; int at48; // posture double spin; // spin - int x; // x - int y; // y - int z; // z + union { + struct + { + int32_t x, y, z; + }; + vec3_t pos; + }; int xvel; //xvel int yvel; //yvel int zvel; //zvel - short sectnum; // sectnum + int sectnum; // sectnum unsigned int floordist; // floordist char at6e; // look center char at6f; @@ -177,6 +182,10 @@ inline void viewBackupSpriteLoc(int nSprite, spritetype *pSprite) } } -void viewBackupSpriteLoc(DBloodActor* actor); +inline void viewBackupSpriteLoc(DBloodActor* actor) +{ + viewBackupSpriteLoc(actor->s().index, &actor->s()); +} + END_BLD_NS diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 7d7566954..4507d02cf 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -353,8 +353,8 @@ void UpdateAimVector(PLAYER * pPlayer) int y = pPSprite->y; int z = pPlayer->zWeapon; Aim aim; - aim.dx = CosScale16(pPSprite->ang); - aim.dy = SinScale16(pPSprite->ang); + aim.dx = bcos(pPSprite->ang); + aim.dy = bsin(pPSprite->ang); aim.dz = pPlayer->slope; WEAPONTRACK *pWeaponTrack = &gWeaponTrack[pPlayer->curWeapon]; int nTarget = -1; @@ -415,8 +415,8 @@ void UpdateAimVector(PLAYER * pPlayer) if (cansee(x, y, z, pPSprite->sectnum, x2, y2, z2, pSprite->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(angle); - aim.dy = SinScale16(angle); + aim.dx = bcos(angle); + aim.dy = bsin(angle); aim.dz = DivScale(dzCenter, nDist, 10); nTarget = nSprite; } @@ -464,8 +464,8 @@ void UpdateAimVector(PLAYER * pPlayer) if (cansee(x, y, z, pPSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum)) { nClosest = nDist2; - aim.dx = CosScale16(angle); - aim.dy = SinScale16(angle); + aim.dx = bcos(angle); + aim.dy = bsin(angle); aim.dz = DivScale(dz, nDist, 10); nTarget = nSprite; } @@ -740,7 +740,7 @@ void WeaponLower(PLAYER *pPlayer) if (VanillaMode() || (pPlayer->newWeapon != 0)) break; pPlayer->weaponState = 1; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); break; } break; @@ -1295,8 +1295,8 @@ void FireSpread(int nTrigger, PLAYER *pPlayer) assert(nTrigger > 0 && nTrigger <= kMaxSpread); Aim *aim = &pPlayer->aim; int angle = (getangle(aim->dx, aim->dy)+((112*(nTrigger-1))/14-56))&2047; - int dx = CosScale16(angle); - int dy = SinScale16(angle); + int dx = bcos(angle); + int dy = bsin(angle); sfxPlay3DSound(pPlayer->pSprite, 431, -1, 0); int r1, r2, r3; r1 = Random3(300); @@ -1317,8 +1317,8 @@ void AltFireSpread(int nTrigger, PLAYER *pPlayer) assert(nTrigger > 0 && nTrigger <= kMaxSpread); Aim *aim = &pPlayer->aim; int angle = (getangle(aim->dx, aim->dy)+((112*(nTrigger-1))/14-56))&2047; - int dx = CosScale16(angle); - int dy = SinScale16(angle); + int dx = bcos(angle); + int dy = bsin(angle); sfxPlay3DSound(pPlayer->pSprite, 431, -1, 0); int r1, r2, r3; r1 = Random3(300); @@ -1347,8 +1347,8 @@ void AltFireSpread2(int nTrigger, PLAYER *pPlayer) assert(nTrigger > 0 && nTrigger <= kMaxSpread); Aim *aim = &pPlayer->aim; int angle = (getangle(aim->dx, aim->dy)+((112*(nTrigger-1))/14-56))&2047; - int dx = CosScale16(angle); - int dy = SinScale16(angle); + int dx = bcos(angle); + int dy = bsin(angle); sfxPlay3DSound(pPlayer->pSprite, 431, -1, 0); if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) { @@ -2031,7 +2031,7 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->flashEffect = ClipLow(pPlayer->flashEffect - 1, 0); #ifdef NOONE_EXTENSIONS - if (gPlayerCtrl[pPlayer->nPlayer].qavScene.index >= 0 && pPlayer->pXSprite->health > 0) { + if (gPlayerCtrl[pPlayer->nPlayer].qavScene.initiator != nullptr && pPlayer->pXSprite->health > 0) { playerQavSceneProcess(pPlayer, &gPlayerCtrl[pPlayer->nPlayer].qavScene); UpdateAimVector(pPlayer); return; diff --git a/source/games/duke/src/_polymost.cpp b/source/games/duke/src/_polymost.cpp index 045c4ed41..27bf55075 100644 --- a/source/games/duke/src/_polymost.cpp +++ b/source/games/duke/src/_polymost.cpp @@ -1,9 +1,5 @@ BEGIN_DUKE_NS -extern int tempsectorz[MAXSECTORS]; -extern int tempsectorpicnum[MAXSECTORS]; - - void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedhoriz h, int smoothratio) { int i, j = 0, k = 0; @@ -17,6 +13,9 @@ void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedh tileDelete(FOF); if (!testgotpic(FOF, true)) return; + TArray tempsectorz(numsectors, true); + TArray tempsectorpicnum(numsectors, true); + floor1 = spr; if (spr->lotag == tag + 2) fofmode = tag + 0; @@ -75,17 +74,17 @@ void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedh { if (k == tag + 0) { - tempsectorz[spr->sectnum] = sector[spr->sectnum].floorz; - sector[spr->sectnum].floorz += (((z - sector[spr->sectnum].floorz) / 32768) + 1) * 32768; - tempsectorpicnum[spr->sectnum] = sector[spr->sectnum].floorpicnum; - sector[spr->sectnum].floorpicnum = 13; + tempsectorz[spr->sectnum] = spr->sector()->floorz; + spr->sector()->floorz += (((z - spr->sector()->floorz) / 32768) + 1) * 32768; + tempsectorpicnum[spr->sectnum] = spr->sector()->floorpicnum; + spr->sector()->floorpicnum = 13; } if (k == tag + 1) { - tempsectorz[spr->sectnum] = sector[spr->sectnum].ceilingz; - sector[spr->sectnum].ceilingz += (((z - sector[spr->sectnum].ceilingz) / 32768) - 1) * 32768; - tempsectorpicnum[spr->sectnum] = sector[spr->sectnum].ceilingpicnum; - sector[spr->sectnum].ceilingpicnum = 13; + tempsectorz[spr->sectnum] = spr->sector()->ceilingz; + spr->sector()->ceilingz += (((z - spr->sector()->ceilingz) / 32768) - 1) * 32768; + tempsectorpicnum[spr->sectnum] = spr->sector()->ceilingpicnum; + spr->sector()->ceilingpicnum = 13; } } } @@ -93,7 +92,7 @@ void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedh offx = x - floor1->x; offy = y - floor1->y; - renderDrawRoomsQ16(floor2->x + offx, floor2->y + offy, z, a.asq16(), h.asq16(), floor2->sectnum); + renderDrawRoomsQ16(floor2->x + offx, floor2->y + offy, z, a.asq16(), h.asq16(), floor2->sectnum, false); fi.animatesprites(pm_tsprite, pm_spritesortcnt, offx + floor2->x, offy + floor2->y, a.asbuild(), smoothratio); renderDrawMasks(); @@ -108,13 +107,13 @@ void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedh { if (k == tag + 0) { - sector[spr->sectnum].floorz = tempsectorz[spr->sectnum]; - sector[spr->sectnum].floorpicnum = tempsectorpicnum[spr->sectnum]; + spr->sector()->floorz = tempsectorz[spr->sectnum]; + spr->sector()->floorpicnum = tempsectorpicnum[spr->sectnum]; } if (k == tag + 1) { - sector[spr->sectnum].ceilingz = tempsectorz[spr->sectnum]; - sector[spr->sectnum].ceilingpicnum = tempsectorpicnum[spr->sectnum]; + spr->sector()->ceilingz = tempsectorz[spr->sectnum]; + spr->sector()->ceilingpicnum = tempsectorpicnum[spr->sectnum]; } }// end if }// end for @@ -183,7 +182,7 @@ void renderMirror(int cposx, int cposy, int cposz, binangle cang, fixedhoriz cho int j = g_visibility; g_visibility = (j >> 1) + (j >> 2); - renderDrawRoomsQ16(tposx, tposy, cposz, tang, choriz.asq16(), mirrorsector[i] + MAXSECTORS); + renderDrawRoomsQ16(tposx, tposy, cposz, tang, choriz.asq16(), mirrorsector[i], true); display_mirror = 1; fi.animatesprites(pm_tsprite, pm_spritesortcnt, tposx, tposy, tang, smoothratio); @@ -204,8 +203,8 @@ void renderMirror(int cposx, int cposy, int cposz, binangle cang, fixedhoriz cho static void geometryEffect(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int sect, int smoothratio) { - short gs, tgsect, geosect, geoid = 0; - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); + int gs, tgsect, geosect, geoid = 0; + renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect, false); fi.animatesprites(pm_tsprite, pm_spritesortcnt, cposx, cposy, cang.asbuild(), smoothratio); renderDrawMasks(); for (gs = 0; gs < geocnt; gs++) @@ -226,7 +225,7 @@ static void geometryEffect(int cposx, int cposy, int cposz, binangle cang, fixed } cposx -= geox[geoid]; cposy -= geoy[geoid]; - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); + renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect, false); cposx += geox[geoid]; cposy += geoy[geoid]; for (gs = 0; gs < geocnt; gs++) @@ -258,7 +257,7 @@ static void geometryEffect(int cposx, int cposy, int cposz, binangle cang, fixed } cposx -= geox2[geoid]; cposy -= geoy2[geoid]; - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); + renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect, false); cposx += geox2[geoid]; cposy += geoy2[geoid]; for (gs = 0; gs < geocnt; gs++) diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index f8cfbdef6..b7d2d7130 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -129,7 +129,7 @@ void checkavailinven(struct player_struct* player) void checkavailweapon(struct player_struct* player) { - short i, snum; + int i, snum; int weap; if (player->wantweaponfire >= 0) @@ -203,11 +203,11 @@ void checkavailweapon(struct player_struct* player) void clearcamera(player_struct* ps) { ps->newOwner = nullptr; - ps->posx = ps->oposx; - ps->posy = ps->oposy; - ps->posz = ps->oposz; + ps->pos.x = ps->oposx; + ps->pos.y = ps->oposy; + ps->pos.z = ps->oposz; ps->angle.restore(); - updatesector(ps->posx, ps->posy, &ps->cursectnum); + updatesector(ps->pos.x, ps->pos.y, &ps->cursectnum); DukeStatIterator it(STAT_ACTOR); while (auto k = it.Next()) @@ -283,7 +283,7 @@ void ms(DDukeActor* const actor) { //T1,T2 and T3 are used for all the sector moving stuff!!! - short startwall, endwall, x; + int startwall, endwall, x; int tx, ty; auto s = actor->s; @@ -293,8 +293,8 @@ void ms(DDukeActor* const actor) int j = actor->temp_data[1]; int k = actor->temp_data[2]; - startwall = sector[s->sectnum].wallptr; - endwall = startwall + sector[s->sectnum].wallnum; + startwall = s->sector()->wallptr; + endwall = startwall + s->sector()->wallnum; for (x = startwall; x < endwall; x++) { rotatepoint( @@ -318,30 +318,31 @@ void movecyclers(void) { for (int q = numcyclers - 1; q >= 0; q--) { - short* c = &cyclers[q][0]; - int s = c[0]; + Cycler* c = &cyclers[q]; + auto sect = c->sector(); - int t = c[3]; - int j = t + bsin(c[1], -10); - int cshade = c[2]; + int t = c->shade2; + int j = t + bsin(c->lotag, -10); + int cshade = c->shade1; if (j < cshade) j = cshade; else if (j > t) j = t; - c[1] += sector[s].extra; - if (c[5]) + c->lotag += sect->extra; + if (c->state) { - auto wal = &wall[sector[s].wallptr]; - for (int x = sector[s].wallnum; x > 0; x--, wal++) - if (wal->hitag != 1) + for (auto& wal : wallsofsector(sect)) + { + if (wal.hitag != 1) { - wal->shade = j; + wal.shade = j; - if ((wal->cstat & CSTAT_WALL_BOTTOM_SWAP) && wal->nextwall >= 0) - wall[wal->nextwall].shade = j; + if ((wal.cstat & CSTAT_WALL_BOTTOM_SWAP) && wal.nextwall >= 0) + wal.nextWall()->shade = j; } - sector[s].floorshade = sector[s].ceilingshade = j; + } + sect->floorshade = sect->ceilingshade = j; } } } @@ -363,7 +364,7 @@ void movedummyplayers(void) p = act->GetOwner()->PlayerIndex(); auto spri = act->s; - if ((!isRR() && ps[p].on_crane != nullptr) || sector[ps[p].cursectnum].lotag != 1 || ps->GetActor()->s->extra <= 0) + if ((!isRR() && ps[p].on_crane != nullptr) || ps[p].cursector()->lotag != 1 || ps->GetActor()->s->extra <= 0) { ps[p].dummyplayersprite = nullptr; deletesprite(act); @@ -371,10 +372,10 @@ void movedummyplayers(void) } else { - if (ps[p].on_ground && ps[p].on_warping_sector == 1 && sector[ps[p].cursectnum].lotag == 1) + if (ps[p].on_ground && ps[p].on_warping_sector == 1 && ps[p].cursector()->lotag == 1) { spri->cstat = CSTAT_SPRITE_BLOCK_ALL; - spri->z = sector[spri->sectnum].ceilingz + (27 << 8); + spri->z = spri->sector()->ceilingz + (27 << 8); spri->ang = ps[p].angle.ang.asbuild(); if (act->temp_data[0] == 8) act->temp_data[0] = 0; @@ -382,13 +383,13 @@ void movedummyplayers(void) } else { - if (sector[spri->sectnum].lotag != 2) spri->z = sector[spri->sectnum].floorz; - spri->cstat = (short)32768; + if (spri->sector()->lotag != 2) spri->z = spri->sector()->floorz; + spri->cstat = 32768; } } - spri->x += (ps[p].posx - ps[p].oposx); - spri->y += (ps[p].posy - ps[p].oposy); + spri->x += (ps[p].pos.x - ps[p].oposx); + spri->y += (ps[p].pos.y - ps[p].oposy); setsprite(act, spri->pos); } } @@ -459,7 +460,7 @@ void moveplayers(void) if (p->actorsqu != nullptr) { - p->angle.addadjustment(getincanglebam(p->angle.ang, bvectangbam(p->actorsqu->s->x - p->posx, p->actorsqu->s->y - p->posy)).signedbuild() >> 2); + p->angle.addadjustment(getincanglebam(p->angle.ang, bvectangbam(p->actorsqu->s->x - p->pos.x, p->actorsqu->s->y - p->pos.y)) >> 2); } if (spri->extra > 0) @@ -469,20 +470,20 @@ void moveplayers(void) act->SetHitOwner(act); if (ud.god == 0) - if (fi.ceilingspace(spri->sectnum) || fi.floorspace(spri->sectnum)) + if (fi.ceilingspace(spri->sector()) || fi.floorspace(spri->sector())) quickkill(p); } else { - p->posx = spri->x; - p->posy = spri->y; - p->posz = spri->z - (20 << 8); + p->pos.x = spri->x; + p->pos.y = spri->y; + p->pos.z = spri->z - (20 << 8); p->newOwner = nullptr; if (p->wackedbyactor != nullptr && p->wackedbyactor->s->statnum < MAXSTATUS) { - p->angle.addadjustment(getincanglebam(p->angle.ang, bvectangbam(p->wackedbyactor->s->x - p->posx, p->wackedbyactor->s->y - p->posy)).signedbuild() >> 1); + p->angle.addadjustment(getincanglebam(p->angle.ang, bvectangbam(p->wackedbyactor->s->x - p->pos.x, p->wackedbyactor->s->y - p->pos.y)) >> 1); } } spri->ang = p->angle.ang.asbuild(); @@ -509,9 +510,9 @@ void moveplayers(void) else { spri->yrepeat = 36; - if (sector[spri->sectnum].lotag != ST_2_UNDERWATER) + if (spri->sector()->lotag != ST_2_UNDERWATER) makeitfall(act); - if (spri->zvel == 0 && sector[spri->sectnum].lotag == ST_1_ABOVE_WATER) + if (spri->zvel == 0 && spri->sector()->lotag == ST_1_ABOVE_WATER) spri->z += (32 << 8); } @@ -529,10 +530,10 @@ void moveplayers(void) } } - if (sector[spri->sectnum].ceilingstat & 1) - spri->shade += (sector[spri->sectnum].ceilingshade - spri->shade) >> 1; + if (spri->sector()->ceilingstat & 1) + spri->shade += (spri->sector()->ceilingshade - spri->shade) >> 1; else - spri->shade += (sector[spri->sectnum].floorshade - spri->shade) >> 1; + spri->shade += (spri->sector()->floorshade - spri->shade) >> 1; } } @@ -595,7 +596,7 @@ void movefx(void) act->temp_data[0] = 0; } } - else if (spri->lotag < 999 && (unsigned)sector[spri->sectnum].lotag < ST_9_SLIDING_ST_DOOR && snd_ambience && sector[spri->sectnum].floorz != sector[spri->sectnum].ceilingz) + else if (spri->lotag < 999 && (unsigned)spri->sector()->lotag < ST_9_SLIDING_ST_DOOR && snd_ambience && spri->sector()->floorz != spri->sector()->ceilingz) { int flags = S_GetUserFlags(spri->lotag); if (flags & SF_MSFX) @@ -641,7 +642,7 @@ void movecrane(DDukeActor *actor, int crane) { int* t = &actor->temp_data[0]; auto spri = actor->s; - int sect = spri->sectnum; + auto sectp = spri->sector(); int x; //t[0] = state @@ -677,7 +678,7 @@ void movecrane(DDukeActor *actor, int crane) } //IFMOVING; // JBF 20040825: see my rant above about this ssp(actor, CLIPMASK0); - if (sect == t[1]) + if (spri->sectnum == t[1]) t[0]++; } else if (t[0] == 2 || t[0] == 7) @@ -686,15 +687,15 @@ void movecrane(DDukeActor *actor, int crane) if (t[0] == 2) { - if ((sector[sect].floorz - spri->z) < (64 << 8)) + if ((sectp->floorz - spri->z) < (64 << 8)) if (spri->picnum > crane) spri->picnum--; - if ((sector[sect].floorz - spri->z) < (4096 + 1024)) + if ((sectp->floorz - spri->z) < (4096 + 1024)) t[0]++; } if (t[0] == 7) { - if ((sector[sect].floorz - spri->z) < (64 << 8)) + if ((sectp->floorz - spri->z) < (64 << 8)) { if (spri->picnum > crane) spri->picnum--; else @@ -754,7 +755,7 @@ void movecrane(DDukeActor *actor, int crane) else if (t[0] == 5 || t[0] == 8) { if (t[0] == 8 && spri->picnum < (crane + 2)) - if ((sector[sect].floorz - spri->z) > 8192) + if ((sectp->floorz - spri->z) > 8192) spri->picnum++; if (spri->z < msx[t[4] + 2]) @@ -807,13 +808,13 @@ void movecrane(DDukeActor *actor, int crane) else if (actor->IsActiveCrane()) { auto ang = ps[p].angle.ang.asbuild(); - ps[p].oposx = ps[p].posx; - ps[p].oposy = ps[p].posy; - ps[p].oposz = ps[p].posz; - ps[p].posx = spri->x - bcos(ang, -6); - ps[p].posy = spri->y - bsin(ang, -6); - ps[p].posz = spri->z + (2 << 8); - setsprite(ps[p].GetActor(), ps[p].posx, ps[p].posy, ps[p].posz); + ps[p].oposx = ps[p].pos.x; + ps[p].oposy = ps[p].pos.y; + ps[p].oposz = ps[p].pos.z; + ps[p].pos.x = spri->x - bcos(ang, -6); + ps[p].pos.y = spri->y - bsin(ang, -6); + ps[p].pos.z = spri->z + (2 << 8); + setsprite(ps[p].GetActor(), ps[p].pos.x, ps[p].pos.y, ps[p].pos.z); ps[p].cursectnum = ps[p].GetActor()->s->sectnum; } } @@ -904,7 +905,7 @@ void moveflammable(DDukeActor* actor, int tire, int box, int pool) if (box >= 0 && spri->picnum == box) { makeitfall(actor); - actor->ceilingz = sector[spri->sectnum].ceilingz; + actor->ceilingz = spri->sector()->ceilingz; } } @@ -1091,11 +1092,11 @@ void movewaterdrip(DDukeActor *actor, int drip) void movedoorshock(DDukeActor* actor) { auto s = actor->s; - int sect = s->sectnum; - int j = abs(sector[sect].ceilingz - sector[sect].floorz) >> 9; + auto sectp = s->sector(); + int j = abs(sectp->ceilingz - sectp->floorz) >> 9; s->yrepeat = j + 4; s->xrepeat = 16; - s->z = sector[sect].floorz; + s->z = sectp->floorz; } //--------------------------------------------------------------------------- @@ -1108,41 +1109,41 @@ void movetouchplate(DDukeActor* actor, int plate) { auto s = actor->s; int* t = &actor->temp_data[0]; - int sect = s->sectnum; + auto sectp = s->sector(); int x; int p; if (t[1] == 1 && s->hitag >= 0) //Move the sector floor { - x = sector[sect].floorz; + x = sectp->floorz; if (t[3] == 1) { if (x >= t[2]) { - sector[sect].floorz = x; + sectp->floorz = x; t[1] = 0; } else { - sector[sect].floorz += sector[sect].extra; - p = checkcursectnums(sect); - if (p >= 0) ps[p].posz += sector[sect].extra; + sectp->floorz += sectp->extra; + p = checkcursectnums(s->sectnum); + if (p >= 0) ps[p].pos.z += sectp->extra; } } else { if (x <= s->z) { - sector[sect].floorz = s->z; + sectp->floorz = s->z; t[1] = 0; } else { - sector[sect].floorz -= sector[sect].extra; - p = checkcursectnums(sect); + sectp->floorz -= sectp->extra; + p = checkcursectnums(s->sectnum); if (p >= 0) - ps[p].posz -= sector[sect].extra; + ps[p].pos.z -= sectp->extra; } } return; @@ -1150,7 +1151,7 @@ void movetouchplate(DDukeActor* actor, int plate) if (t[5] == 1) return; - p = checkcursectnums(sect); + p = checkcursectnums(s->sectnum); if (p >= 0 && (ps[p].on_ground || s->ang == 512)) { if (t[0] == 0 && !check_activator_motion(s->lotag)) @@ -1297,16 +1298,16 @@ void bounce(DDukeActor* actor) int yvect = MulScale(s->xvel, bsin(s->ang), 10); int zvect = s->zvel; - int hitsect = s->sectnum; + auto sectp = s->sector(); - int k = sector[hitsect].wallptr; + int k = sectp->wallptr; int l = wall[k].point2; int daang = getangle(wall[l].x - wall[k].x, wall[l].y - wall[k].y); if (s->z < (actor->floorz + actor->ceilingz) >> 1) - k = sector[hitsect].ceilingheinum; + k = sectp->ceilingheinum; else - k = sector[hitsect].floorheinum; + k = sectp->floorheinum; int dax = MulScale(k, bsin(daang), 14); int day = MulScale(k, -bcos(daang), 14); @@ -1503,10 +1504,13 @@ bool queball(DDukeActor *actor, int pocket, int queball, int stripeball) } Collision coll; - int j = clipmove_ex(&s->x, &s->y, &s->z, &s->sectnum, + static_assert(sizeof(s->sectnum) != sizeof(int)); // this will error out when sectnum gets expanded. + int sect = s->sectnum; + int j = clipmove_ex(&s->pos, §, (MulScale(s->xvel, bcos(s->ang), 14) * TICSPERFRAME) << 11, (MulScale(s->xvel, bsin(s->ang), 14) * TICSPERFRAME) << 11, 24L, (4 << 8), (4 << 8), CLIPMASK1, coll); + s->sectnum = sect; if (j == kHitWall) { @@ -1539,7 +1543,7 @@ bool queball(DDukeActor *actor, int pocket, int queball, int stripeball) { // if(s->pal == 12) { - int j = getincangle(ps[p].angle.ang.asbuild(), getangle(s->x - ps[p].posx, s->y - ps[p].posy)); + int j = getincangle(ps[p].angle.ang.asbuild(), getangle(s->x - ps[p].pos.x, s->y - ps[p].pos.y)); if (j > -64 && j < 64 && PlayerInput(p, SB_OPEN)) if (ps[p].toggle_key_flag == 1) { @@ -1550,7 +1554,7 @@ bool queball(DDukeActor *actor, int pocket, int queball, int stripeball) auto sa = act2->s; if (sa->picnum == queball || sa->picnum == stripeball) { - j = getincangle(ps[p].angle.ang.asbuild(), getangle(sa->x - ps[p].posx, sa->y - ps[p].posy)); + j = getincangle(ps[p].angle.ang.asbuild(), getangle(sa->x - ps[p].pos.x, sa->y - ps[p].pos.y)); if (j > -64 && j < 64) { int l; @@ -1572,7 +1576,7 @@ bool queball(DDukeActor *actor, int pocket, int queball, int stripeball) } if (x < 512 && s->sectnum == ps[p].cursectnum) { - s->ang = getangle(s->x - ps[p].posx, s->y - ps[p].posy); + s->ang = getangle(s->x - ps[p].pos.x, s->y - ps[p].pos.y); s->xvel = 48; } } @@ -1589,7 +1593,7 @@ void forcesphere(DDukeActor* actor, int forcesphere) { auto s = actor->s; int* t = &actor->temp_data[0]; - int sect = s->sectnum; + auto sectp = s->sector(); if (s->yvel == 0) { s->yvel = 1; @@ -1612,8 +1616,8 @@ void forcesphere(DDukeActor* actor, int forcesphere) if (s->zvel < 6144) s->zvel += 192; s->z += s->zvel; - if (s->z > sector[sect].floorz) - s->z = sector[sect].floorz; + if (s->z > sectp->floorz) + s->z = sectp->floorz; t[3]--; if (t[3] == 0) { @@ -1643,23 +1647,23 @@ void recon(DDukeActor *actor, int explosion, int firelaser, int attacksnd, int p { auto s = actor->s; int* t = &actor->temp_data[0]; - int sect = s->sectnum; + auto sectp = s->sector(); int a; getglobalz(actor); - if (sector[s->sectnum].ceilingstat & 1) - s->shade += (sector[s->sectnum].ceilingshade - s->shade) >> 1; - else s->shade += (sector[s->sectnum].floorshade - s->shade) >> 1; + if (sectp->ceilingstat & 1) + s->shade += (sectp->ceilingshade - s->shade) >> 1; + else s->shade += (sectp->floorshade - s->shade) >> 1; - if (s->z < sector[sect].ceilingz + (32 << 8)) - s->z = sector[sect].ceilingz + (32 << 8); + if (s->z < sectp->ceilingz + (32 << 8)) + s->z = sectp->ceilingz + (32 << 8); if (ud.multimode < 2) { if (actor_tog == 1) { - s->cstat = (short)32768; + s->cstat = 32768; return; } else if (actor_tog == 2) s->cstat = 257; @@ -1719,13 +1723,13 @@ void recon(DDukeActor *actor, int explosion, int firelaser, int attacksnd, int p fi.shoot(actor, firelaser); s->ang = a; } - if (t[2] > (26 * 3) || !cansee(s->x, s->y, s->z - (16 << 8), s->sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum)) + if (t[2] > (26 * 3) || !cansee(s->x, s->y, s->z - (16 << 8), s->sectnum, ps[p].pos.x, ps[p].pos.y, ps[p].pos.z, ps[p].cursectnum)) { t[0] = 0; t[2] = 0; } else actor->tempang += - getincangle(actor->tempang, getangle(ps[p].posx - s->x, ps[p].posy - s->y)) / 3; + getincangle(actor->tempang, getangle(ps[p].pos.x - s->x, ps[p].pos.y - s->y)) / 3; } else if (t[0] == 2 || t[0] == 3) { @@ -1735,14 +1739,14 @@ void recon(DDukeActor *actor, int explosion, int firelaser, int attacksnd, int p if (t[0] == 2) { - int l = ps[p].posz - s->z; + int l = ps[p].pos.z - s->z; if (abs(l) < (48 << 8)) t[0] = 3; - else s->z += Sgn(ps[p].posz - s->z) << shift; // The shift here differs between Duke and RR. + else s->z += Sgn(ps[p].pos.z - s->z) << shift; // The shift here differs between Duke and RR. } else { t[2]++; - if (t[2] > (26 * 3) || !cansee(s->x, s->y, s->z - (16 << 8), s->sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum)) + if (t[2] > (26 * 3) || !cansee(s->x, s->y, s->z - (16 << 8), s->sectnum, ps[p].pos.x, ps[p].pos.y, ps[p].pos.z, ps[p].cursectnum)) { t[0] = 1; t[2] = 0; @@ -1753,7 +1757,7 @@ void recon(DDukeActor *actor, int explosion, int firelaser, int attacksnd, int p fi.shoot(actor, firelaser); } } - s->ang += getincangle(s->ang, getangle(ps[p].posx - s->x, ps[p].posy - s->y)) >> 2; + s->ang += getincangle(s->ang, getangle(ps[p].pos.x - s->x, ps[p].pos.y - s->y)) >> 2; } if (t[0] != 2 && t[0] != 3 && Owner) @@ -1858,11 +1862,11 @@ void reactor(DDukeActor* actor, int REACTOR, int REACTOR2, int REACTORBURNT, int { spritetype* s = actor->s; int* t = &actor->temp_data[0]; - int sect = actor->s->sectnum; + auto sectp = s->sector(); if (t[4] == 1) { - DukeSectIterator it(sect); + DukeSectIterator it(s->sectnum); while (auto act2 = it.Next()) { auto sprj = act2->s; @@ -1870,8 +1874,8 @@ void reactor(DDukeActor* actor, int REACTOR, int REACTOR2, int REACTORBURNT, int { if (sprj->lotag == 1) { - sprj->lotag = (short)65535; - sprj->hitag = (short)65535; + sprj->lotag = -1; + sprj->hitag = -1; } } else if (sprj->picnum == REACTOR) @@ -1884,7 +1888,7 @@ void reactor(DDukeActor* actor, int REACTOR, int REACTOR2, int REACTORBURNT, int } else if (sprj->picnum == REACTORSPARK || sprj->picnum == REACTOR2SPARK) { - sprj->cstat = (short)32768; + sprj->cstat = 32768; } } return; @@ -1925,7 +1929,7 @@ void reactor(DDukeActor* actor, int REACTOR, int REACTOR2, int REACTORBURNT, int t[1]++; t[4] = s->z; - s->z = sector[sect].floorz - (krand() % (sector[sect].floorz - sector[sect].ceilingz)); + s->z = sectp->floorz - (krand() % (sectp->floorz - sectp->ceilingz)); switch (t[1]) { @@ -1953,7 +1957,7 @@ void reactor(DDukeActor* actor, int REACTOR, int REACTOR2, int REACTORBURNT, int case 10: case 15: { - DukeSectIterator it(sect); + DukeSectIterator it(s->sectnum); while (auto a2 = it.Next()) { if (a2 != actor) @@ -2003,7 +2007,7 @@ void camera(DDukeActor *actor) if (j >= 0) { t[0] = 1; // static - s->cstat = (short)32768; + s->cstat = 32768; for (int x = 0; x < 5; x++) RANDOMSCRAP(actor); return; @@ -2109,12 +2113,12 @@ void forcesphereexplode(DDukeActor *actor) void watersplash2(DDukeActor* actor) { - int sect = actor->s->sectnum; + auto sectp = actor->getSector(); int* t = &actor->temp_data[0]; t[0]++; if (t[0] == 1) { - if (sector[sect].lotag != 1 && sector[sect].lotag != 2) + if (sectp->lotag != 1 && sectp->lotag != 2) { deletesprite(actor); return; @@ -2166,14 +2170,14 @@ void frameeffect1(DDukeActor *actor) bool money(DDukeActor* actor, int BLOODPOOL) { auto s = actor->s; - int sect = s->sectnum; + auto sectp = s->sector(); int* t = &actor->temp_data[0]; s->xvel = (krand() & 7) + bsin(actor->temp_data[0], -9); actor->temp_data[0] += (krand() & 63); if ((actor->temp_data[0] & 2047) > 512 && (actor->temp_data[0] & 2047) < 1596) { - if (sector[sect].lotag == 2) + if (sectp->lotag == 2) { if (s->zvel < 64) s->zvel += (gs.gravity >> 5) + (krand() & 7); @@ -2225,7 +2229,7 @@ bool money(DDukeActor* actor, int BLOODPOOL) bool jibs(DDukeActor *actor, int JIBS6, bool timeout, bool callsetsprite, bool floorcheck, bool zcheck1, bool zcheck2) { spritetype* s = actor->s; - int sect = s->sectnum; + auto sectp = s->sector(); int* t = &actor->temp_data[0]; if (s->xvel > 0) s->xvel--; @@ -2245,14 +2249,21 @@ bool jibs(DDukeActor *actor, int JIBS6, bool timeout, bool callsetsprite, bool f if (s->zvel > 1024 && s->zvel < 1280) { setsprite(actor, s->pos); - sect = s->sectnum; + sectp = s->sector(); } if (callsetsprite) setsprite(actor, s->pos); - int l = getflorzofslope(sect, s->x, s->y); - int x = getceilzofslope(sect, s->x, s->y); - if (x == l || sect < 0 || sect >= MAXSECTORS) + // this was after the slope calls, but we should avoid calling that for invalid sectors. + if (s->sectnum < 0 || s->sectnum >= MAXSECTORS) + { + deletesprite(actor); + return false; + } + + int l = getflorzofslopeptr(sectp, s->x, s->y); + int x = getceilzofslopeptr(sectp, s->x, s->y); + if (x == l) { deletesprite(actor); return false; @@ -2261,7 +2272,7 @@ bool jibs(DDukeActor *actor, int JIBS6, bool timeout, bool callsetsprite, bool f if (s->z < l - (2 << 8)) { if (t[1] < 2) t[1]++; - else if (sector[sect].lotag != 2) + else if (sectp->lotag != 2) { t[1] = 0; if (zcheck1) @@ -2279,7 +2290,7 @@ bool jibs(DDukeActor *actor, int JIBS6, bool timeout, bool callsetsprite, bool f if (s->zvel < 6144) { - if (sector[sect].lotag == 2) + if (sectp->lotag == 2) { if (s->zvel < 1024) s->zvel += 48; @@ -2292,7 +2303,7 @@ bool jibs(DDukeActor *actor, int JIBS6, bool timeout, bool callsetsprite, bool f s->y += MulScale(s->xvel, bsin(s->ang), 14); s->z += s->zvel; - if (floorcheck && s->z >= sector[s->sectnum].floorz) + if (floorcheck && s->z >= s->sector()->floorz) { deletesprite(actor); return false; @@ -2312,7 +2323,7 @@ bool jibs(DDukeActor *actor, int JIBS6, bool timeout, bool callsetsprite, bool f deletesprite(actor); return false; } - if ((sector[s->sectnum].floorstat & 2)) + if ((s->sector()->floorstat & 2)) { deletesprite(actor); return false; @@ -2349,13 +2360,13 @@ bool jibs(DDukeActor *actor, int JIBS6, bool timeout, bool callsetsprite, bool f bool bloodpool(DDukeActor* actor, bool puke, int TIRE) { spritetype* s = actor->s; - int sect = s->sectnum; + auto sectp = s->sector(); int* t = &actor->temp_data[0]; if (t[0] == 0) { t[0] = 1; - if (sector[sect].floorstat & 2) + if (sectp->floorstat & 2) { deletesprite(actor); return false; @@ -2435,18 +2446,18 @@ bool bloodpool(DDukeActor* actor, bool puke, int TIRE) void shell(DDukeActor* actor, bool morecheck) { spritetype* s = actor->s; - int sect = s->sectnum; + auto sectp = s->sector(); int* t = &actor->temp_data[0]; ssp(actor, CLIPMASK0); - if (sect < 0 || morecheck) + if (s->sectnum < 0 || morecheck) { deletesprite(actor); return; } - if (sector[sect].lotag == 2) + if (sectp->lotag == 2) { t[1]++; if (t[1] > 8) @@ -2489,13 +2500,13 @@ void shell(DDukeActor* actor, bool morecheck) void glasspieces(DDukeActor* actor) { spritetype* s = actor->s; - int sect = s->sectnum; + auto sectp = s->sector(); int* t = &actor->temp_data[0]; makeitfall(actor); if (s->zvel > 4096) s->zvel = 4096; - if (sect < 0) + if (s->sectnum < 0) { deletesprite(actor); return; @@ -2504,7 +2515,7 @@ void glasspieces(DDukeActor* actor) if (s->z == actor->floorz - (FOURSLEIGHT) && t[0] < 3) { s->zvel = -((3 - t[0]) << 8) - (krand() & 511); - if (sector[sect].lotag == 2) + if (sectp->lotag == 2) s->zvel >>= 1; s->xrepeat >>= 1; s->yrepeat >>= 1; @@ -2537,7 +2548,7 @@ void glasspieces(DDukeActor* actor) void scrap(DDukeActor* actor, int SCRAP1, int SCRAP6) { spritetype* s = actor->s; - int sect = s->sectnum; + auto sectp = s->sector(); int* t = &actor->temp_data[0]; if (s->xvel > 0) @@ -2547,10 +2558,10 @@ void scrap(DDukeActor* actor, int SCRAP1, int SCRAP6) if (s->zvel > 1024 && s->zvel < 1280) { setsprite(actor, s->pos); - sect = s->sectnum; + sectp = s->sector(); } - if (s->z < sector[sect].floorz - (2 << 8)) + if (s->z < sectp->floorz - (2 << 8)) { if (t[1] < 1) t[1]++; else @@ -2594,7 +2605,7 @@ void scrap(DDukeActor* actor, int SCRAP1, int SCRAP6) // //--------------------------------------------------------------------------- -void gutsdir(DDukeActor* actor, short gtype, short n, short p) +void gutsdir(DDukeActor* actor, int gtype, int n, int p) { int sx, sy; @@ -2630,7 +2641,7 @@ void handle_se00(DDukeActor* actor, int LASERLINE) { auto s = actor->s; int* t = &actor->temp_data[0]; - sectortype *sect = §or[s->sectnum]; + sectortype *sect = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -2741,16 +2752,16 @@ void handle_se00(DDukeActor* actor, int LASERLINE) { ps[p].angle.addadjustment(l * q); - ps[p].posz += zchange; + ps[p].pos.z += zchange; int m, x; - rotatepoint(Owner->s->x, Owner->s->y, ps[p].posx, ps[p].posy, (q * l), &m, &x); + rotatepoint(Owner->s->x, Owner->s->y, ps[p].pos.x, ps[p].pos.y, (q * l), &m, &x); - ps[p].bobposx += m - ps[p].posx; - ps[p].bobposy += x - ps[p].posy; + ps[p].bobposx += m - ps[p].pos.x; + ps[p].bobposy += x - ps[p].pos.y; - ps[p].posx = m; - ps[p].posy = x; + ps[p].pos.x = m; + ps[p].pos.y = x; auto psp = ps[p].GetActor(); if (psp->s->extra <= 0) @@ -2820,7 +2831,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -2876,7 +2887,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) if (x < 20480) { j = s->ang; - s->ang = getangle(s->x - ps[p].posx, s->y - ps[p].posy); + s->ang = getangle(s->x - ps[p].pos.x, s->y - ps[p].pos.y); fi.shoot(actor, RPG); s->ang = j; } @@ -2894,12 +2905,12 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) auto psp = ps[p].GetActor(); if (psp->s->extra > 0) { - short k = ps[p].cursectnum; - updatesector(ps[p].posx, ps[p].posy, &k); + int k = ps[p].cursectnum; + updatesector(ps[p].pos.x, ps[p].pos.y, &k); if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) { - ps[p].posx = s->x; - ps[p].posy = s->y; + ps[p].pos.x = s->x; + ps[p].pos.y = s->y; ps[p].cursectnum = s->sectnum; setsprite(ps[p].GetActor(), s->pos); @@ -2915,7 +2926,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) for (int p = connecthead; p >= 0; p = connectpoint2[p]) { auto psp = ps[p].GetActor(); - if (sector[ps[p].cursectnum].lotag != 2) + if (ps[p].cursector()->lotag != 2) { if (po[p].os == s->sectnum) { @@ -2925,10 +2936,10 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) if (s->sectnum == psp->s->sectnum) { - rotatepoint(s->x, s->y, ps[p].posx, ps[p].posy, q, &ps[p].posx, &ps[p].posy); + rotatepoint(s->x, s->y, ps[p].pos.x, ps[p].pos.y, q, &ps[p].pos.x, &ps[p].pos.y); - ps[p].posx += m; - ps[p].posy += x; + ps[p].pos.x += m; + ps[p].pos.y += x; ps[p].bobposx += m; ps[p].bobposy += x; @@ -2937,13 +2948,13 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) if (numplayers > 1) { - ps[p].oposx = ps[p].posx; - ps[p].oposy = ps[p].posy; + ps[p].oposx = ps[p].pos.x; + ps[p].oposy = ps[p].pos.y; } if (psp->s->extra <= 0) { - psp->s->x = ps[p].posx; - psp->s->y = ps[p].posy; + psp->s->x = ps[p].pos.x; + psp->s->y = ps[p].pos.y; } } } @@ -2952,7 +2963,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) while (auto a2 = it.Next()) { auto sj = a2->s; - if (sj->statnum != 10 && sector[sj->sectnum].lotag != 2 && sj->picnum != SECTOREFFECTOR && sj->picnum != LOCATORS) + if (sj->statnum != 10 && sj->sector()->lotag != 2 && sj->picnum != SECTOREFFECTOR && sj->picnum != LOCATORS) { rotatepoint(s->x, s->y, sj->x, sj->y, q, &sj->x, &sj->y); @@ -2978,12 +2989,12 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) { if (ps[p].GetActor()->s->extra > 0) { - short k = ps[p].cursectnum; - updatesector(ps[p].posx, ps[p].posy, &k); + int k = ps[p].cursectnum; + updatesector(ps[p].pos.x, ps[p].pos.y, &k); if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) { - ps[p].oposx = ps[p].posx = s->x; - ps[p].oposy = ps[p].posy = s->y; + ps[p].oposx = ps[p].pos.x = s->x; + ps[p].oposy = ps[p].pos.y = s->y; ps[p].cursectnum = s->sectnum; setsprite(ps[p].GetActor(), s->pos); @@ -3000,7 +3011,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) { if (a2->s->statnum == 1 && badguy(a2) && a2->s->picnum != SECTOREFFECTOR && a2->s->picnum != LOCATORS) { - short k = a2->s->sectnum; + int k = a2->s->sectnum; updatesector(a2->s->x, a2->s->y, &k); if (a2->s->extra >= 0 && k == s->sectnum) { @@ -3025,7 +3036,7 @@ void handle_se30(DDukeActor *actor, int JIBS6) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3083,12 +3094,12 @@ void handle_se30(DDukeActor *actor, int JIBS6) auto psp = ps[p].GetActor(); if (psp->s->extra > 0) { - short k = ps[p].cursectnum; - updatesector(ps[p].posx, ps[p].posy, &k); + int k = ps[p].cursectnum; + updatesector(ps[p].pos.x, ps[p].pos.y, &k); if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) { - ps[p].posx = s->x; - ps[p].posy = s->y; + ps[p].pos.x = s->x; + ps[p].pos.y = s->y; ps[p].cursectnum = s->sectnum; setsprite(ps[p].GetActor(), s->pos); @@ -3101,13 +3112,13 @@ void handle_se30(DDukeActor *actor, int JIBS6) auto psp = ps[p].GetActor(); if (psp->s->sectnum == s->sectnum) { - ps[p].posx += l; - ps[p].posy += x; + ps[p].pos.x += l; + ps[p].pos.y += x; if (numplayers > 1) { - ps[p].oposx = ps[p].posx; - ps[p].oposy = ps[p].posy; + ps[p].oposx = ps[p].pos.x; + ps[p].oposy = ps[p].pos.y; } ps[p].bobposx += l; @@ -3146,15 +3157,15 @@ void handle_se30(DDukeActor *actor, int JIBS6) for (int p = connecthead; p >= 0; p = connectpoint2[p]) if (ps[p].GetActor()->s->extra > 0) { - short k = ps[p].cursectnum; - updatesector(ps[p].posx, ps[p].posy, &k); + int k = ps[p].cursectnum; + updatesector(ps[p].pos.x, ps[p].pos.y, &k); if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) { - ps[p].posx = s->x; - ps[p].posy = s->y; + ps[p].pos.x = s->x; + ps[p].pos.y = s->y; - ps[p].oposx = ps[p].posx; - ps[p].oposy = ps[p].posy; + ps[p].oposx = ps[p].pos.x; + ps[p].oposy = ps[p].pos.y; ps[p].cursectnum = s->sectnum; @@ -3172,7 +3183,7 @@ void handle_se30(DDukeActor *actor, int JIBS6) { // if(a2->s.sectnum != s->sectnum) { - short k = a2->s->sectnum; + int k = a2->s->sectnum; updatesector(a2->s->x, a2->s->y, &k); if (a2->s->extra >= 0 && k == s->sectnum) { @@ -3198,7 +3209,7 @@ void handle_se02(DDukeActor *actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3242,8 +3253,8 @@ void handle_se02(DDukeActor *actor) for (int p = connecthead; p >= 0; p = connectpoint2[p]) if (ps[p].cursectnum == s->sectnum && ps[p].on_ground) { - ps[p].posx += m; - ps[p].posy += x; + ps[p].pos.x += m; + ps[p].pos.y += x; ps[p].bobposx += m; ps[p].bobposy += x; @@ -3275,7 +3286,7 @@ void handle_se03(DDukeActor *actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3304,16 +3315,14 @@ void handle_se03(DDukeActor *actor) sc->ceilingshade = t[0]; sc->floorshade = t[0]; - auto wal = &wall[sc->wallptr]; - - for (x = sc->wallnum; x > 0; x--, wal++) + for(auto& wal : wallsofsector(sc)) { - if (wal->hitag != 1) + if (wal.hitag != 1) { - wal->shade = t[0]; - if ((wal->cstat & 2) && wal->nextwall >= 0) + wal.shade = t[0]; + if ((wal.cstat & 2) && wal.nextwall >= 0) { - wall[wal->nextwall].shade = wal->shade; + wal.nextWall()->shade = wal.shade; } } } @@ -3329,7 +3338,7 @@ void handle_se04(DDukeActor *actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; int j; @@ -3358,18 +3367,16 @@ void handle_se04(DDukeActor *actor) sc->floorshade = t[1]; sc->ceilingshade = t[1]; - auto wal = &wall[sc->wallptr]; - - for (int x = sc->wallnum; x > 0; x--, wal++) + for (auto& wal : wallsofsector(sc)) { - if (j) wal->pal = (palvals & 0xff); - else wal->pal = s->pal; + if (j) wal.pal = (palvals & 0xff); + else wal.pal = s->pal; - if (wal->hitag != 1) + if (wal.hitag != 1) { - wal->shade = t[0]; - if ((wal->cstat & 2) && wal->nextwall >= 0) - wall[wal->nextwall].shade = wal->shade; + wal.shade = t[0]; + if ((wal.cstat & 2) && wal.nextwall >= 0) + wal.nextWall()->shade = wal.shade; } } @@ -3400,7 +3407,7 @@ void handle_se05(DDukeActor* actor, int FIRELASER) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; int j, l, m; @@ -3409,7 +3416,7 @@ void handle_se05(DDukeActor* actor, int FIRELASER) if (x < 8192) { j = s->ang; - s->ang = getangle(s->x - ps[p].posx, s->y - ps[p].posy); + s->ang = getangle(s->x - ps[p].pos.x, s->y - ps[p].pos.y); fi.shoot(actor, FIRELASER); s->ang = j; } @@ -3442,9 +3449,8 @@ void handle_se05(DDukeActor* actor, int FIRELASER) if (ldist(Owner, actor) < 1024) { - short ta; - ta = s->ang; - s->ang = getangle(ps[p].posx - s->x, ps[p].posy - s->y); + auto ta = s->ang; + s->ang = getangle(ps[p].pos.x - s->x, ps[p].pos.y - s->y); s->ang = ta; actor->SetOwner(nullptr); return; @@ -3464,7 +3470,7 @@ void handle_se05(DDukeActor* actor, int FIRELASER) else { t[2] += - getincangle(t[2] + 512, getangle(ps[p].posx - s->x, ps[p].posy - s->y)) >> 2; + getincangle(t[2] + 512, getangle(ps[p].pos.x - s->x, ps[p].pos.y - s->y)) >> 2; sc->ceilingshade = 0; } j = fi.ifhitbyweapon(actor); @@ -3496,7 +3502,7 @@ void handle_se08(DDukeActor *actor, bool checkhitag1) // work only if its moving auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3516,7 +3522,7 @@ void handle_se08(DDukeActor *actor, bool checkhitag1) if (j >= 0) { - short sn; + int sn; if ((sc->lotag & 0x8000) || actor->temp_data[4]) x = -t[3]; @@ -3531,25 +3537,23 @@ void handle_se08(DDukeActor *actor, bool checkhitag1) if (((ac->s->lotag) == st) && (ac->s->hitag) == sh) { sn = ac->s->sectnum; - auto sect = §or[sn]; + auto sect = ac->getSector(); int m = ac->s->shade; - auto wal = &wall[sect->wallptr]; - - for (int l = sect->wallnum; l > 0; l--, wal++) + for (auto& wal : wallsofsector(sect)) { - if (wal->hitag != 1) + if (wal.hitag != 1) { - wal->shade += x; + wal.shade += x; - if (wal->shade < m) - wal->shade = m; - else if (wal->shade > ac->temp_data[2]) - wal->shade = ac->temp_data[2]; + if (wal.shade < m) + wal.shade = m; + else if (wal.shade > ac->temp_data[2]) + wal.shade = ac->temp_data[2]; - if (wal->nextwall >= 0) - if (wall[wal->nextwall].hitag != 1) - wall[wal->nextwall].shade = wal->shade; + if (wal.nextwall >= 0) + if (wal.nextWall()->hitag != 1) + wal.nextWall()->shade = wal.shade; } } @@ -3584,7 +3588,7 @@ void handle_se10(DDukeActor* actor, const int* specialtags) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3604,7 +3608,7 @@ void handle_se10(DDukeActor* actor, const int* specialtags) { if (specialtags) for (int i = 0; specialtags[i]; i++) { - if (sector[s->sectnum].lotag == specialtags[i] && getanimationgoal(anim_ceilingz, s->sectnum) >= 0) + if (s->sector()->lotag == specialtags[i] && getanimationgoal(anim_ceilingz, s->sectnum) >= 0) { return; } @@ -3628,7 +3632,7 @@ void handle_se11(DDukeActor *actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; if (t[5] > 0) @@ -3644,10 +3648,10 @@ void handle_se11(DDukeActor *actor) startwall = sc->wallptr; endwall = startwall + sc->wallnum; - DukeStatIterator it(STAT_ACTOR); for (int j = startwall; j < endwall; j++) { + DukeStatIterator it(STAT_ACTOR); while (auto ac = it.Next()) { auto sk = ac->s; @@ -3664,7 +3668,7 @@ void handle_se11(DDukeActor *actor) for (int j = startwall; j < endwall; j++) { - it.Reset(STAT_PLAYER); + DukeStatIterator it(STAT_PLAYER); while (auto ac = it.Next()) { auto sk = ac->s; @@ -3700,7 +3704,7 @@ void handle_se12(DDukeActor *actor, int planeonly) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; if (t[0] == 3 || t[3] == 1) //Lights going off @@ -3708,7 +3712,7 @@ void handle_se12(DDukeActor *actor, int planeonly) sc->floorpal = 0; sc->ceilingpal = 0; - auto wal = &wall[sc->wallptr]; + auto wal = sc->firstWall(); for (int j = sc->wallnum; j > 0; j--, wal++) if (wal->hitag != 1) { @@ -3749,7 +3753,7 @@ void handle_se12(DDukeActor *actor, int planeonly) if (planeonly != 2) sc->floorshade -= 2; if (planeonly != 1) sc->ceilingshade -= 2; - auto wal = &wall[sc->wallptr]; + auto wal = sc->firstWall(); for (int j = sc->wallnum; j > 0; j--, wal++) if (wal->hitag != 1) { @@ -3782,7 +3786,7 @@ void handle_se13(DDukeActor* actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; if (t[2]) @@ -3823,7 +3827,7 @@ void handle_se13(DDukeActor* actor) if (s->ang == 512) { - auto wal = &wall[sc->wallptr]; + auto wal = sc->firstWall(); for (j = sc->wallnum; j > 0; j--, wal++) wal->shade = s->shade; @@ -3831,8 +3835,8 @@ void handle_se13(DDukeActor* actor) if (ps[0].one_parallax_sectnum >= 0) { - sc->ceilingpicnum = sector[ps[0].one_parallax_sectnum].ceilingpicnum; - sc->ceilingshade = sector[ps[0].one_parallax_sectnum].ceilingshade; + sc->ceilingpicnum = ps[0].one_parallax_sector()->ceilingpicnum; + sc->ceilingshade = ps[0].one_parallax_sector()->ceilingshade; } } } @@ -3899,7 +3903,7 @@ void handle_se16(DDukeActor* actor, int REACTOR, int REACTOR2) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); t[2] += 32; if (sc->floorz < sc->ceilingz) s->shade = 0; @@ -3944,7 +3948,7 @@ void handle_se17(DDukeActor* actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3959,11 +3963,11 @@ void handle_se17(DDukeActor* actor) if (act1->s->statnum == STAT_PLAYER && act1->GetOwner()) { int p = act1->s->yvel; - if (numplayers < 2) ps[p].oposz = ps[p].posz; - ps[p].posz += q; + if (numplayers < 2) ps[p].oposz = ps[p].pos.z; + ps[p].pos.z += q; ps[p].truefz += q; ps[p].truecz += q; - if (numplayers > 1) ps[p].oposz = ps[p].posz; + if (numplayers > 1) ps[p].oposz = ps[p].pos.z; } if (act1->s->statnum != STAT_EFFECTOR) { @@ -3998,7 +4002,7 @@ void handle_se17(DDukeActor* actor) while ((act2 = it.Next())) { if (actor != act2 && (act2->s->lotag) == 17) - if ((sc->hitag - t[0]) == (sector[act2->s->sectnum].hitag) && sh == (act2->s->hitag)) + if ((sc->hitag - t[0]) == (act2->getSector()->hitag) && sh == (act2->s->hitag)) break; } @@ -4013,16 +4017,16 @@ void handle_se17(DDukeActor* actor) { int p = spr3->yvel; - ps[p].posx += spr2->x - s->x; - ps[p].posy += spr2->y - s->y; - ps[p].posz = sector[spr2->sectnum].floorz - (sc->floorz - ps[p].posz); + ps[p].pos.x += spr2->x - s->x; + ps[p].pos.y += spr2->y - s->y; + ps[p].pos.z = spr2->sector()->floorz - (sc->floorz - ps[p].pos.z); - act3->floorz = sector[spr2->sectnum].floorz; - act3->ceilingz = sector[spr2->sectnum].ceilingz; + act3->floorz = spr2->sector()->floorz; + act3->ceilingz = spr2->sector()->ceilingz; - ps[p].bobposx = ps[p].oposx = ps[p].posx; - ps[p].bobposy = ps[p].oposy = ps[p].posy; - ps[p].oposz = ps[p].posz; + ps[p].bobposx = ps[p].oposx = ps[p].pos.x; + ps[p].bobposy = ps[p].oposy = ps[p].pos.y; + ps[p].oposz = ps[p].pos.z; ps[p].truefz = act3->floorz; ps[p].truecz = act3->ceilingz; @@ -4035,15 +4039,15 @@ void handle_se17(DDukeActor* actor) { spr3->x += spr2->x - s->x; spr3->y += spr2->y - s->y; - spr3->z = sector[spr2->sectnum].floorz - (sc->floorz - spr3->z); + spr3->z = spr2->sector()->floorz - (sc->floorz - spr3->z); spr3->backupz(); changeactorsect(act3, spr2->sectnum); setsprite(act3, spr3->pos); - act3->floorz = sector[spr2->sectnum].floorz; - act3->ceilingz = sector[spr2->sectnum].ceilingz; + act3->floorz = spr2->sector()->floorz; + act3->ceilingz = spr2->sector()->ceilingz; } } @@ -4059,7 +4063,7 @@ void handle_se17(DDukeActor* actor) void handle_se18(DDukeActor *actor, bool morecheck) { int* t = &actor->temp_data[0]; - auto sc = §or[actor->s->sectnum]; + auto sc = actor->getSector(); int st = actor->s->lotag; int sh = actor->s->hitag; @@ -4086,7 +4090,7 @@ void handle_se18(DDukeActor *actor, bool morecheck) while (auto a2 = it.Next()) { if (a2->s->picnum == TILE_APLAYER && a2->GetOwner()) - if (ps[a2->PlayerIndex()].on_ground == 1) ps[a2->PlayerIndex()].posz += sc->extra; + if (ps[a2->PlayerIndex()].on_ground == 1) ps[a2->PlayerIndex()].pos.z += sc->extra; if (a2->s->zvel == 0 && a2->s->statnum != STAT_EFFECTOR && a2->s->statnum != STAT_PROJECTILE) { a2->s->z += sc->extra; @@ -4123,7 +4127,7 @@ void handle_se18(DDukeActor *actor, bool morecheck) while (auto a2 = it.Next()) { if (a2->s->picnum == TILE_APLAYER && a2->GetOwner()) - if (ps[a2->PlayerIndex()].on_ground == 1) ps[a2->PlayerIndex()].posz -= sc->extra; + if (ps[a2->PlayerIndex()].on_ground == 1) ps[a2->PlayerIndex()].pos.z -= sc->extra; if (a2->s->zvel == 0 && a2->s->statnum != STAT_EFFECTOR && a2->s->statnum != STAT_PROJECTILE) { a2->s->z -= sc->extra; @@ -4158,7 +4162,7 @@ void handle_se18(DDukeActor *actor, bool morecheck) void handle_se19(DDukeActor *actor, int BIGFORCE) { int* t = &actor->temp_data[0]; - auto sc = §or[actor->s->sectnum]; + auto sc = actor->getSector(); int st = actor->s->lotag; int sh = actor->s->hitag; int j, x, q; @@ -4195,9 +4199,9 @@ void handle_se19(DDukeActor *actor, int BIGFORCE) auto a2Owner = a2->GetOwner(); if (a2->s->lotag == 0 && a2->s->hitag == sh && a2Owner) { - q = a2Owner->s->sectnum; - sector[a2->s->sectnum].floorpal = sector[a2->s->sectnum].ceilingpal = sector[q].floorpal; - sector[a2->s->sectnum].floorshade = sector[a2->s->sectnum].ceilingshade = sector[q].floorshade; + auto sectp = a2Owner->getSector(); + a2->getSector()->floorpal = a2->getSector()->ceilingpal = sectp->floorpal; + a2->getSector()->floorshade = a2->getSector()->ceilingshade = sectp->floorshade; a2Owner->temp_data[0] = 2; } } @@ -4221,9 +4225,9 @@ void handle_se19(DDukeActor *actor, int BIGFORCE) case 0: if (ac->s->hitag == sh && ac->GetOwner()) { - q = ac->s->sectnum; - sector[q].floorshade = sector[q].ceilingshade = ac->GetOwner()->s->shade; - sector[q].floorpal = sector[q].ceilingpal = ac->GetOwner()->s->pal; + auto sectp = ac->getSector(); + sectp->floorshade = sectp->ceilingshade = ac->GetOwner()->s->shade; + sectp->floorpal = sectp->ceilingpal = ac->GetOwner()->s->pal; } break; @@ -4256,7 +4260,7 @@ void handle_se20(DDukeActor* actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -4291,25 +4295,25 @@ void handle_se20(DDukeActor* actor) a2->s->x += x; a2->s->y += l; setsprite(a2, a2->s->pos); - if (sector[a2->s->sectnum].floorstat & 2) + if (a2->getSector()->floorstat & 2) if (a2->s->statnum == 2) makeitfall(a2); } } - dragpoint((short)t[1], wall[t[1]].x + x, wall[t[1]].y + l); - dragpoint((short)t[2], wall[t[2]].x + x, wall[t[2]].y + l); + dragpoint(t[1], wall[t[1]].x + x, wall[t[1]].y + l); + dragpoint(t[2], wall[t[2]].x + x, wall[t[2]].y + l); for (int p = connecthead; p >= 0; p = connectpoint2[p]) if (ps[p].cursectnum == s->sectnum && ps[p].on_ground) { - ps[p].posx += x; - ps[p].posy += l; + ps[p].pos.x += x; + ps[p].pos.y += l; - ps[p].oposx = ps[p].posx; - ps[p].oposy = ps[p].posy; + ps[p].oposx = ps[p].pos.x; + ps[p].oposy = ps[p].pos.y; - setsprite(ps[p].GetActor(), ps[p].posx, ps[p].posy, ps[p].posz + gs.playerheight); + setsprite(ps[p].GetActor(), ps[p].pos.x, ps[p].pos.y, ps[p].pos.z + gs.playerheight); } sc->addfloorxpan(-x / 8.f); @@ -4330,7 +4334,7 @@ void handle_se21(DDukeActor* actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; int* lp; @@ -4370,7 +4374,7 @@ void handle_se21(DDukeActor* actor) void handle_se22(DDukeActor* actor) { int* t = &actor->temp_data[0]; - auto sc = §or[actor->s->sectnum]; + auto sc = actor->getSector(); if (t[1]) { if (getanimationgoal(anim_ceilingz, t[0]) >= 0) @@ -4389,7 +4393,7 @@ void handle_se26(DDukeActor* actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int x, l; s->xvel = 32; @@ -4424,7 +4428,7 @@ void handle_se26(DDukeActor* actor) { ps[p].fric.x += l << 5; ps[p].fric.y += x << 5; - ps[p].posz += s->zvel; + ps[p].pos.z += s->zvel; } ms(actor); @@ -4441,7 +4445,7 @@ void handle_se27(DDukeActor* actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; int x, p; @@ -4460,14 +4464,14 @@ void handle_se27(DDukeActor* actor) } else if (ud.recstat == 2 && ps[p].newOwner == nullptr) { - if (cansee(s->x, s->y, s->z, s->sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum)) + if (cansee(s->x, s->y, s->z, s->sectnum, ps[p].pos.x, ps[p].pos.y, ps[p].pos.z, ps[p].cursectnum)) { if (x < sh) { ud.cameraactor = actor; t[0] = 999; - s->ang += getincangle(s->ang, getangle(ps[p].posx - s->x, ps[p].posy - s->y)) >> 3; - s->yvel = 100 + ((s->z - ps[p].posz) / 257); + s->ang += getincangle(s->ang, getangle(ps[p].pos.x - s->x, ps[p].pos.y - s->y)) >> 3; + s->yvel = 100 + ((s->z - ps[p].pos.z) / 257); } else if (t[0] == 999) @@ -4481,7 +4485,7 @@ void handle_se27(DDukeActor* actor) } else { - s->ang = getangle(ps[p].posx - s->x, ps[p].posy - s->y); + s->ang = getangle(ps[p].pos.x - s->x, ps[p].pos.y - s->y); if (t[0] == 999) { @@ -4501,11 +4505,11 @@ void handle_se27(DDukeActor* actor) // //--------------------------------------------------------------------------- -void handle_se24(DDukeActor *actor, int16_t *list1, int16_t *list2, bool scroll, int TRIPBOMB, int LASERLINE, int CRANE, int shift) +void handle_se24(DDukeActor *actor, const int16_t *list1, const int16_t *list2, bool scroll, int TRIPBOMB, int LASERLINE, int CRANE, int shift) { int* t = &actor->temp_data[0]; - auto testlist = [](int16_t* list, int val) { for (int i = 0; list[i] > 0; i++) if (list[i] == val) return true; return false; }; + auto testlist = [](const int16_t* list, int val) { for (int i = 0; list[i] > 0; i++) if (list[i] == val) return true; return false; }; if (t[4]) return; @@ -4550,7 +4554,7 @@ void handle_se24(DDukeActor *actor, int16_t *list1, int16_t *list2, bool scroll, setsprite(a2, s2->pos); - if (sector[s2->sectnum].floorstat & 2) + if (s2->sector()->floorstat & 2) if (s2->statnum == 2) makeitfall(a2); } @@ -4571,7 +4575,7 @@ void handle_se24(DDukeActor *actor, int16_t *list1, int16_t *list2, bool scroll, } } } - if (scroll) sector[actor->s->sectnum].addfloorxpan(actor->s->yvel / 128.f); + if (scroll) actor->getSector()->addfloorxpan(actor->s->yvel / 128.f); } //--------------------------------------------------------------------------- @@ -4583,7 +4587,7 @@ void handle_se24(DDukeActor *actor, int16_t *list1, int16_t *list2, bool scroll, void handle_se25(DDukeActor* actor, int t_index, int snd1, int snd2) { int* t = &actor->temp_data[0]; - auto sec = §or[actor->s->sectnum]; + auto sec = actor->getSector(); if (sec->floorz <= sec->ceilingz) actor->s->shade = 0; @@ -4622,7 +4626,7 @@ void handle_se32(DDukeActor *actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); if (t[0] == 1) { @@ -4690,7 +4694,7 @@ void handle_se35(DDukeActor *actor, int SMALLSMOKE, int EXPLOSION2) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); if (sc->ceilingz > s->z) for (int j = 0; j < 8; j++) @@ -4733,7 +4737,7 @@ void handle_se35(DDukeActor *actor, int SMALLSMOKE, int EXPLOSION2) void handle_se128(DDukeActor *actor) { int* t = &actor->temp_data[0]; - auto sc = §or[actor->s->sectnum]; + auto sc = actor->getSector(); auto wal = &wall[t[2]]; @@ -4743,22 +4747,22 @@ void handle_se128(DDukeActor *actor) wal->cstat |= 16; if (wal->nextwall >= 0) { - wall[wal->nextwall].cstat &= (255 - 32); - wall[wal->nextwall].cstat |= 16; + wal->nextWall()->cstat &= (255 - 32); + wal->nextWall()->cstat |= 16; } } // else return; wal->overpicnum++; if (wal->nextwall >= 0) - wall[wal->nextwall].overpicnum++; + wal->nextWall()->overpicnum++; if (t[0] < t[1]) t[0]++; else { wal->cstat &= (128 + 32 + 8 + 4 + 2); if (wal->nextwall >= 0) - wall[wal->nextwall].cstat &= (128 + 32 + 8 + 4 + 2); + wal->nextWall()->cstat &= (128 + 32 + 8 + 4 + 2); deletesprite(actor); } } @@ -4772,7 +4776,7 @@ void handle_se128(DDukeActor *actor) void handle_se130(DDukeActor *actor, int countmax, int EXPLOSION2) { int* t = &actor->temp_data[0]; - auto sc = §or[actor->s->sectnum]; + auto sc = actor->getSector(); if (t[0] > countmax) { @@ -4804,7 +4808,7 @@ void handle_se31(DDukeActor* actor, bool choosedir) { auto s = actor->s; int* t = &actor->temp_data[0]; - auto sec = §or[s->sectnum]; + auto sec = actor->getSector(); if (t[0] == 1) { @@ -4838,7 +4842,7 @@ void handle_se31(DDukeActor* actor, bool choosedir) { if (a2->s->picnum == TILE_APLAYER && a2->GetOwner()) if (ps[a2->PlayerIndex()].on_ground == 1) - ps[a2->PlayerIndex()].posz += l; + ps[a2->PlayerIndex()].pos.z += l; if (a2->s->zvel == 0 && a2->s->statnum != STAT_EFFECTOR && (!choosedir || a2->s->statnum != STAT_PROJECTILE)) { a2->s->z += l; @@ -4867,7 +4871,7 @@ void handle_se31(DDukeActor* actor, bool choosedir) { if (a2->s->picnum == TILE_APLAYER && a2->GetOwner()) if (ps[a2->PlayerIndex()].on_ground == 1) - ps[a2->PlayerIndex()].posz += l; + ps[a2->PlayerIndex()].pos.z += l; if (a2->s->zvel == 0 && a2->s->statnum != STAT_EFFECTOR && (!choosedir || a2->s->statnum != STAT_PROJECTILE)) { a2->s->z += l; @@ -4898,7 +4902,7 @@ void handle_se31(DDukeActor* actor, bool choosedir) { if (a2->s->picnum == TILE_APLAYER && a2->GetOwner()) if (ps[a2->PlayerIndex()].on_ground == 1) - ps[a2->PlayerIndex()].posz += l; + ps[a2->PlayerIndex()].pos.z += l; if (a2->s->zvel == 0 && a2->s->statnum != STAT_EFFECTOR && (!choosedir || a2->s->statnum != STAT_PROJECTILE)) { a2->s->z += l; @@ -4926,7 +4930,7 @@ void handle_se31(DDukeActor* actor, bool choosedir) { if (a2->s->picnum ==TILE_APLAYER && a2->GetOwner()) if (ps[a2->PlayerIndex()].on_ground == 1) - ps[a2->PlayerIndex()].posz -= l; + ps[a2->PlayerIndex()].pos.z -= l; if (a2->s->zvel == 0 && a2->s->statnum != STAT_EFFECTOR && (!choosedir || a2->s->statnum != STAT_PROJECTILE)) { a2->s->z -= l; @@ -4982,15 +4986,15 @@ void getglobalz(DDukeActor* actor) } else if(s->statnum == STAT_PROJECTILE && lz.actor->s->picnum == TILE_APLAYER && actor->GetOwner() == actor) { - actor->ceilingz = sector[s->sectnum].ceilingz; - actor->floorz = sector[s->sectnum].floorz; + actor->ceilingz = s->sector()->ceilingz; + actor->floorz = s->sector()->floorz; } } } else { - actor->ceilingz = sector[s->sectnum].ceilingz; - actor->floorz = sector[s->sectnum].floorz; + actor->ceilingz = s->sector()->ceilingz; + actor->floorz = s->sector()->floorz; } } @@ -5005,11 +5009,11 @@ void makeitfall(DDukeActor* actor) auto s = actor->s; int c; - if( fi.floorspace(s->sectnum) ) + if( fi.floorspace(s->sector()) ) c = 0; else { - if( fi.ceilingspace(s->sectnum) || sector[s->sectnum].lotag == ST_2_UNDERWATER) + if( fi.ceilingspace(s->sector()) || s->sector()->lotag == ST_2_UNDERWATER) c = gs.gravity/6; else c = gs.gravity; } @@ -5026,13 +5030,13 @@ void makeitfall(DDukeActor* actor) } else { - actor->ceilingz = sector[s->sectnum].ceilingz; - actor->floorz = sector[s->sectnum].floorz; + actor->ceilingz = s->sector()->ceilingz; + actor->floorz = s->sector()->floorz; } if( s->z < actor->floorz-(FOURSLEIGHT) ) { - if( sector[s->sectnum].lotag == 2 && s->zvel > 3122 ) + if( s->sector()->lotag == 2 && s->zvel > 3122 ) s->zvel = 3144; if(s->zvel < 6144) s->zvel += c; @@ -5095,7 +5099,7 @@ int dodge(DDukeActor* actor) int furthestangle(DDukeActor *actor, int angs) { auto s = actor->s; - short j, hitsect, hitwall, furthest_angle, angincs; + int j, hitsect, hitwall, furthest_angle, angincs; int hx, hy, hz, d, greatestd; DDukeActor* dd; @@ -5129,7 +5133,7 @@ int furthestangle(DDukeActor *actor, int angs) int furthestcanseepoint(DDukeActor *actor, DDukeActor* tosee, int* dax, int* day) { auto s = actor->s; - short j, hitsect, hitwall, angincs; + int j, hitsect, hitwall, angincs; int hx, hy, hz, d, da;//, d, cd, ca,tempx,tempy,cx,cy; DDukeActor* dd; @@ -5168,7 +5172,7 @@ int furthestcanseepoint(DDukeActor *actor, DDukeActor* tosee, int* dax, int* day void alterang(int ang, DDukeActor* actor, int playernum) { auto s = actor->s; - short aang, angdif, goalang, j; + int aang, angdif, goalang, j; int ticselapsed; int* t = actor->temp_data; @@ -5256,16 +5260,16 @@ void fall_common(DDukeActor *actor, int playernum, int JIBS6, int DRONE, int BLO int c; int sphit = fallspecial? fallspecial(actor, playernum) : 0; - if (fi.floorspace(s->sectnum)) + if (fi.floorspace(s->sector())) c = 0; else { - if (fi.ceilingspace(s->sectnum) || sector[s->sectnum].lotag == 2) + if (fi.ceilingspace(s->sector()) || s->sector()->lotag == 2) c = gs.gravity / 6; else c = gs.gravity; } - if (actor->cgg <= 0 || (sector[s->sectnum].floorstat & 2)) + if (actor->cgg <= 0 || (s->sector()->floorstat & 2)) { getglobalz(actor); actor->cgg = 6; @@ -5311,20 +5315,18 @@ void fall_common(DDukeActor *actor, int playernum, int JIBS6, int DRONE, int BLO actor->extra = 1; s->zvel = 0; } - else if (s->zvel > 2048 && sector[s->sectnum].lotag != 1) + else if (s->zvel > 2048 && s->sector()->lotag != 1) { - short j = s->sectnum; - int x = s->x, y = s->y, z = s->z; - pushmove(&x, &y, &z, &j, 128, (4 << 8), (4 << 8), CLIPMASK0); - s->x = x; s->y = y; s->z = z; + int j = s->sectnum; + pushmove(&s->pos, &j, 128, (4 << 8), (4 << 8), CLIPMASK0); if (j != s->sectnum && j >= 0 && j < MAXSECTORS) changeactorsect(actor, j); S_PlayActorSound(thud, actor); } } - if (sector[s->sectnum].lotag == 1) + if (s->sector()->lotag == 1) s->z += gs.actorinfo[s->picnum].falladjustz; else s->zvel = 0; } diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index a84cefff8..08fd5d928 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -104,11 +104,11 @@ void SerializeActorGlobals(FSerializer& arc) // //--------------------------------------------------------------------------- -bool ceilingspace_d(int sectnum) +bool ceilingspace_d(sectortype* sectp) { - if( (sector[sectnum].ceilingstat&1) && sector[sectnum].ceilingpal == 0 ) + if( (sectp->ceilingstat&1) && sectp->ceilingpal == 0 ) { - switch(sector[sectnum].ceilingpicnum) + switch(sectp->ceilingpicnum) { case MOONSKY1: case BIGORBIT1: @@ -124,11 +124,11 @@ bool ceilingspace_d(int sectnum) // //--------------------------------------------------------------------------- -bool floorspace_d(int sectnum) +bool floorspace_d(sectortype* sectp) { - if( (sector[sectnum].floorstat&1) && sector[sectnum].ceilingpal == 0 ) + if( (sectp->floorstat&1) && sectp->ceilingpal == 0 ) { - switch(sector[sectnum].floorpicnum) + switch(sectp->floorpicnum) { case MOONSKY1: case BIGORBIT1: @@ -301,13 +301,13 @@ bool ifsquished(DDukeActor* actor, int p) if (spri->picnum == APLAYER && ud.clipping) return false; - auto& sc = sector[spri->sectnum]; - int floorceildist = sc.floorz - sc.ceilingz; + auto sectp = spri->sector(); + int floorceildist = sectp->floorz - sectp->ceilingz; - if (sc.lotag != ST_23_SWINGING_DOOR) + if (sectp->lotag != ST_23_SWINGING_DOOR) { if (spri->pal == 1) - squishme = floorceildist < (32 << 8) && (sc.lotag & 32768) == 0; + squishme = floorceildist < (32 << 8) && (sectp->lotag & 32768) == 0; else squishme = floorceildist < (12 << 8); } @@ -342,9 +342,10 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h walltype* wal; int d, q, x1, y1; int sectcnt, sectend, dasect, startwall, endwall, nextsect; - short p, x, sect; + int p, x; + int sect; static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC }; - short tempshort[MAXSECTORS]; // originally hijacked a global buffer which is bad. Q: How many do we really need? RedNukem says 64. + int tempsect[128]; // originally hijacked a global buffer which is bad. Q: How many do we really need? RedNukem says 64. auto spri = actor->s; @@ -352,29 +353,30 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h if(spri->picnum != SHRINKSPARK) { - tempshort[0] = spri->sectnum; + tempsect[0] = spri->sectnum; dasect = spri->sectnum; + auto dasectp = spri->sector(); sectcnt = 0; sectend = 1; do { - dasect = tempshort[sectcnt++]; - if (((sector[dasect].ceilingz - spri->z) >> 8) < r) + dasect = tempsect[sectcnt++]; + if (((dasectp->ceilingz - spri->z) >> 8) < r) { - d = abs(wall[sector[dasect].wallptr].x - spri->x) + abs(wall[sector[dasect].wallptr].y - spri->y); + d = abs(wall[dasectp->wallptr].x - spri->x) + abs(wall[dasectp->wallptr].y - spri->y); if (d < r) fi.checkhitceiling(dasect); else { // ouch... - d = abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x - spri->x) + abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].y - spri->y); + d = abs(wall[wall[wall[dasectp->wallptr].point2].point2].x - spri->x) + abs(wall[wall[wall[dasectp->wallptr].point2].point2].y - spri->y); if (d < r) fi.checkhitceiling(dasect); } } - startwall = sector[dasect].wallptr; - endwall = startwall + sector[dasect].wallnum; + startwall = dasectp->wallptr; + endwall = startwall + dasectp->wallnum; for (x = startwall, wal = &wall[startwall]; x < endwall; x++, wal++) if ((abs(wal->x - spri->x) + abs(wal->y - spri->y)) < r) { @@ -382,8 +384,8 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h if (nextsect >= 0) { for (dasect = sectend - 1; dasect >= 0; dasect--) - if (tempshort[dasect] == nextsect) break; - if (dasect < 0) tempshort[sectend++] = nextsect; + if (tempsect[dasect] == nextsect) break; + if (dasect < 0) tempsect[sectend++] = nextsect; } x1 = (((wal->x + wall[wal->point2].x) >> 1) + spri->x) >> 1; y1 = (((wal->y + wall[wal->point2].y) >> 1) + spri->y) >> 1; @@ -391,7 +393,7 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h if (sect >= 0 && cansee(x1, y1, spri->z, sect, spri->x, spri->y, spri->z, spri->sectnum)) fi.checkhitwall(actor, x, wal->x, wal->y, spri->z, spri->picnum); } - } while (sectcnt < sectend); + } while (sectcnt < sectend && sectcnt < (int)countof(tempsect)); } SKIPWALLCHECK: @@ -538,8 +540,8 @@ SKIPWALLCHECK: int movesprite_ex_d(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision &result) { - int daz, h, oldx, oldy; - short retval, dasectnum, cd; + int clipdist; + int dasectnum; auto spri = actor->s; int bg = badguy(actor); @@ -555,71 +557,66 @@ int movesprite_ex_d(DDukeActor* actor, int xchange, int ychange, int zchange, un } dasectnum = spri->sectnum; + auto dasectp = spri->sector(); - daz = spri->z; - h = ((tileHeight(spri->picnum) * spri->yrepeat) << 1); - daz -= h; + vec3_t pos = spri->pos; + pos.z -= ((tileHeight(spri->picnum) * spri->yrepeat) << 1); if (bg) { - oldx = spri->x; - oldy = spri->y; - if (spri->xrepeat > 60) - retval = clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024L, (4 << 8), (4 << 8), cliptype); + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024, (4 << 8), (4 << 8), cliptype, result); else { if (spri->picnum == LIZMAN) - cd = 292; + clipdist = 292; else if (actorflag(actor, SFLAG_BADGUY)) - cd = spri->clipdist << 2; + clipdist = spri->clipdist << 2; else - cd = 192; + clipdist = 192; - retval = clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), cd, (4 << 8), (4 << 8), cliptype); + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), clipdist, (4 << 8), (4 << 8), cliptype, result); } // conditional code from hell... if (dasectnum < 0 || (dasectnum >= 0 && ((actor->actorstayput >= 0 && actor->actorstayput != dasectnum) || - ((spri->picnum == BOSS2) && spri->pal == 0 && sector[dasectnum].lotag != 3) || - ((spri->picnum == BOSS1 || spri->picnum == BOSS2) && sector[dasectnum].lotag == ST_1_ABOVE_WATER) || - (sector[dasectnum].lotag == ST_1_ABOVE_WATER && (spri->picnum == LIZMAN || (spri->picnum == LIZTROOP && spri->zvel == 0))) + ((spri->picnum == BOSS2) && spri->pal == 0 && dasectp->lotag != 3) || + ((spri->picnum == BOSS1 || spri->picnum == BOSS2) && dasectp->lotag == ST_1_ABOVE_WATER) || + (dasectp->lotag == ST_1_ABOVE_WATER && (spri->picnum == LIZMAN || (spri->picnum == LIZTROOP && spri->zvel == 0))) )) ) { - spri->x = oldx; - spri->y = oldy; - if (sector[dasectnum].lotag == ST_1_ABOVE_WATER && spri->picnum == LIZMAN) + if (dasectp->lotag == ST_1_ABOVE_WATER && spri->picnum == LIZMAN) spri->ang = (krand()&2047); else if ((actor->temp_data[0]&3) == 1 && spri->picnum != COMMANDER) spri->ang = (krand()&2047); - setsprite(actor,oldx,oldy,spri->z); + setsprite(actor,spri->pos); if (dasectnum < 0) dasectnum = 0; return result.setSector(dasectnum); } - if ((retval & kHitTypeMask) > kHitSector && (actor->cgg == 0)) spri->ang += 768; + if ((result.type == kHitWall || result.type == kHitSprite) && (actor->cgg == 0)) spri->ang += 768; } else { if (spri->statnum == STAT_PROJECTILE) - retval = - clipmove_ex(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8L, (4 << 8), (4 << 8), cliptype, result); + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8, (4 << 8), (4 << 8), cliptype, result); else - retval = - clipmove_ex(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), (int)(spri->clipdist << 2), (4 << 8), (4 << 8), cliptype, result); + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), (int)(spri->clipdist << 2), (4 << 8), (4 << 8), cliptype, result); } + spri->x = pos.x; + spri->y = pos.y; if (dasectnum >= 0) if ((dasectnum != spri->sectnum)) changeactorsect(actor, dasectnum); - daz = spri->z + ((zchange * TICSPERFRAME) >> 3); + int daz = spri->z + ((zchange * TICSPERFRAME) >> 3); if ((daz > actor->ceilingz) && (daz <= actor->floorz)) spri->z = daz; - else if (retval == kHitNone) + else if (result.type == kHitNone) return result.setSector(dasectnum); - return retval; + return result.type; } //--------------------------------------------------------------------------- // @@ -627,17 +624,17 @@ int movesprite_ex_d(DDukeActor* actor, int xchange, int ychange, int zchange, un // //--------------------------------------------------------------------------- -void lotsofmoney_d(DDukeActor *actor, short n) +void lotsofmoney_d(DDukeActor *actor, int n) { lotsofstuff(actor, n, MONEY); } -void lotsofmail_d(DDukeActor *actor, short n) +void lotsofmail_d(DDukeActor *actor, int n) { lotsofstuff(actor, n, MAIL); } -void lotsofpaper_d(DDukeActor *actor, short n) +void lotsofpaper_d(DDukeActor *actor, int n) { lotsofstuff(actor, n, PAPER); } @@ -648,7 +645,7 @@ void lotsofpaper_d(DDukeActor *actor, short n) // //--------------------------------------------------------------------------- -void guts_d(DDukeActor* actor, short gtype, short n, short p) +void guts_d(DDukeActor* actor, int gtype, int n, int p) { auto s = actor->s; int gutz, floorz; @@ -705,7 +702,8 @@ void guts_d(DDukeActor* actor, short gtype, short n, short p) void movefta_d(void) { int x, px, py, sx, sy; - short p, psect, ssect; + int p; + int psect, ssect; int j; DukeStatIterator iti(STAT_ZOMBIEACTOR); @@ -770,9 +768,9 @@ void movefta_d(void) case NUKEBARRELDENTED: case NUKEBARRELLEAKED: case TRIPBOMB: - if (sector[s->sectnum].ceilingstat&1) - s->shade = sector[s->sectnum].ceilingshade; - else s->shade = sector[s->sectnum].floorshade; + if (s->sector()->ceilingstat&1) + s->shade = s->sector()->ceilingshade; + else s->shade = s->sector()->floorshade; act->timetosleep = 0; changeactorstat(act, STAT_STANDABLE); @@ -789,9 +787,9 @@ void movefta_d(void) } if (badguy(act)) { - if (sector[s->sectnum].ceilingstat & 1) - s->shade = sector[s->sectnum].ceilingshade; - else s->shade = sector[s->sectnum].floorshade; + if (s->sector()->ceilingstat & 1) + s->shade = s->sector()->ceilingshade; + else s->shade = s->sector()->floorshade; } } } @@ -822,7 +820,7 @@ DDukeActor* ifhitsectors_d(int sectnum) int ifhitbyweapon_d(DDukeActor *actor) { - short p; + int p; auto spri = actor->s; auto hitowner = actor->GetHitOwner(); @@ -938,14 +936,13 @@ int ifhitbyweapon_d(DDukeActor *actor) void movefallers_d(void) { - short sect; int j, x; DukeStatIterator iti(STAT_FALLER); while (auto act = iti.Next()) { auto s = act->s; - sect = s->sectnum; + auto sectp = s->sector(); if (act->temp_data[0] == 0) { @@ -1001,23 +998,23 @@ void movefallers_d(void) ssp(act, CLIPMASK0); } - if (fi.floorspace(s->sectnum)) x = 0; + if (fi.floorspace(s->sector())) x = 0; else { - if (fi.ceilingspace(s->sectnum)) + if (fi.ceilingspace(s->sector())) x = gs.gravity / 6; else x = gs.gravity; } - if (s->z < (sector[sect].floorz - FOURSLEIGHT)) + if (s->z < (sectp->floorz - FOURSLEIGHT)) { s->zvel += x; if (s->zvel > 6144) s->zvel = 6144; s->z += s->zvel; } - if ((sector[sect].floorz - s->z) < (16 << 8)) + if ((sectp->floorz - s->z) < (16 << 8)) { j = 1 + (krand() & 7); for (x = 0; x < j; x++) RANDOMSCRAP(act); @@ -1115,8 +1112,8 @@ static void movetripbomb(DDukeActor *actor) s->z -= (3 << 8); // Laser fix from EDuke32. - int16_t const oldSectNum = s->sectnum; - int16_t curSectNum = s->sectnum; + int const oldSectNum = s->sectnum; + int curSectNum = s->sectnum; updatesectorneighbor(s->x, s->y, &curSectNum, 1024, 2048); changeactorsect(actor, curSectNum); @@ -1316,7 +1313,7 @@ static void movesidebolt(DDukeActor* actor) auto s = actor->s; int* t = &actor->temp_data[0]; int x; - int sect = s->sectnum; + auto sectp = s->sector(); auto p = findplayer(actor, &x); if (x > 20480) return; @@ -1342,7 +1339,7 @@ CLEAR_THE_BOLT2: } s->picnum++; - if ((krand() & 1) && sector[sect].floorpicnum == HURTRAIL) + if ((krand() & 1) && sectp->floorpicnum == HURTRAIL) S_PlayActorSound(SHORT_CIRCUIT, actor); if (s->picnum == SIDEBOLT1 + 4) s->picnum = SIDEBOLT1; @@ -1359,20 +1356,20 @@ static void movebolt(DDukeActor *actor) auto s = actor->s; int* t = &actor->temp_data[0]; int x; - int sect = s->sectnum; + auto sectp = s->sector(); auto p = findplayer(actor, &x); if (x > 20480) return; if (t[3] == 0) - t[3] = sector[sect].floorshade; + t[3] = sectp->floorshade; CLEAR_THE_BOLT: if (t[2]) { t[2]--; - sector[sect].floorshade = 20; - sector[sect].ceilingshade = 20; + sectp->floorshade = 20; + sectp->ceilingshade = 20; return; } if ((s->xrepeat | s->yrepeat) == 0) @@ -1395,20 +1392,20 @@ CLEAR_THE_BOLT: if (l & 1) s->cstat ^= 2; - if (s->picnum == (BOLT1+1) && (krand()&7) == 0 && sector[sect].floorpicnum == HURTRAIL) + if (s->picnum == (BOLT1+1) && (krand()&7) == 0 && sectp->floorpicnum == HURTRAIL) S_PlayActorSound(SHORT_CIRCUIT,actor); if (s->picnum==BOLT1+4) s->picnum=BOLT1; if (s->picnum & 1) { - sector[sect].floorshade = 0; - sector[sect].ceilingshade = 0; + sectp->floorshade = 0; + sectp->ceilingshade = 0; } else { - sector[sect].floorshade = 20; - sector[sect].ceilingshade = 20; + sectp->floorshade = 20; + sectp->ceilingshade = 20; } } @@ -1546,7 +1543,7 @@ static bool movefireball(DDukeActor* actor) auto s = actor->s; auto Owner = actor->GetOwner(); - if (sector[s->sectnum].lotag == 2) + if (s->sector()->lotag == 2) { deletesprite(actor); return true; @@ -1712,8 +1709,8 @@ static bool weaponhitsector(DDukeActor* proj, const vec3_t& oldpos, bool firebal if (s->zvel < 0) { - if (sector[s->sectnum].ceilingstat & 1) - if (sector[s->sectnum].ceilingpal == 0) + if (s->sector()->ceilingstat & 1) + if (s->sector()->ceilingpal == 0) { deletesprite(proj); return true; @@ -1763,7 +1760,7 @@ static void weaponcommon_d(DDukeActor* proj) int k, ll; vec3_t oldpos = s->pos; - if (s->picnum == RPG && sector[s->sectnum].lotag == 2) + if (s->picnum == RPG && s->sector()->lotag == 2) { k = s->xvel >> 1; ll = s->zvel >> 1; @@ -1779,7 +1776,7 @@ static void weaponcommon_d(DDukeActor* proj) switch (s->picnum) { case RPG: - if (proj->picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + if (proj->picnum != BOSS2 && s->xrepeat >= 10 && s->sector()->lotag != 2) { auto spawned = spawn(proj, SMALLSMOKE); spawned->s->z += (1 << 8); @@ -1814,11 +1811,11 @@ static void weaponcommon_d(DDukeActor* proj) s->zvel = -1; } else - if ((s->z > proj->floorz && sector[s->sectnum].lotag != 1) || - (s->z > proj->floorz + (16 << 8) && sector[s->sectnum].lotag == 1)) + if ((s->z > proj->floorz && s->sector()->lotag != 1) || + (s->z > proj->floorz + (16 << 8) && s->sector()->lotag == 1)) { coll.setSector(s->sectnum); - if (sector[s->sectnum].lotag != 1) + if (s->sector()->lotag != 1) s->zvel = 1; } } @@ -1913,7 +1910,7 @@ static void weaponcommon_d(DDukeActor* proj) return; } } - else if (s->picnum == RPG && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(140)) + else if (s->picnum == RPG && s->sector()->lotag == 2 && s->xrepeat >= 10 && rnd(140)) spawn(proj, WATERBUBBLE); } @@ -1999,13 +1996,13 @@ void movetransports_d(void) continue; } - int sect = spr->sectnum; - int sectlotag = sector[sect].lotag; + auto sectp = spr->sector(); + int sectlotag = sectp->lotag; int onfloorz = act->temp_data[4]; if (act->temp_data[0] > 0) act->temp_data[0]--; - DukeSectIterator itj(sect); + DukeSectIterator itj(spr->sectnum); while (auto act2 = itj.Next()) { auto spr2 = act2->s; @@ -2045,9 +2042,9 @@ void movetransports_d(void) ps[p].transporter_hold = 13; } - ps[p].bobposx = ps[p].oposx = ps[p].posx = Owner->s->x; - ps[p].bobposy = ps[p].oposy = ps[p].posy = Owner->s->y; - ps[p].oposz = ps[p].posz = Owner->s->z - gs.playerheight; + ps[p].bobposx = ps[p].oposx = ps[p].pos.x = Owner->s->x; + ps[p].bobposy = ps[p].oposy = ps[p].pos.y = Owner->s->y; + ps[p].oposz = ps[p].pos.z = Owner->s->z - gs.playerheight; changeactorsect(act2, Owner->s->sectnum); ps[p].cursectnum = spr2->sectnum; @@ -2063,17 +2060,17 @@ void movetransports_d(void) } else if (!(sectlotag == 1 && ps[p].on_ground == 1)) break; - if (onfloorz == 0 && abs(spr->z - ps[p].posz) < 6144) + if (onfloorz == 0 && abs(spr->z - ps[p].pos.z) < 6144) if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && (PlayerInput(p, SB_JUMP))) || (ps[p].jetpack_on && PlayerInput(p, SB_CROUCH))) { - ps[p].oposx = ps[p].posx += Owner->s->x - spr->x; - ps[p].oposy = ps[p].posy += Owner->s->y - spr->y; + ps[p].oposx = ps[p].pos.x += Owner->s->x - spr->x; + ps[p].oposy = ps[p].pos.y += Owner->s->y - spr->y; if (ps[p].jetpack_on && (PlayerInput(p, SB_JUMP) || ps[p].jetpack_on < 11)) - ps[p].posz = Owner->s->z - 6144; - else ps[p].posz = Owner->s->z + 6144; - ps[p].oposz = ps[p].posz; + ps[p].pos.z = Owner->s->z - 6144; + else ps[p].pos.z = Owner->s->z + 6144; + ps[p].oposz = ps[p].pos.z; auto pa = ps[p].GetActor(); pa->s->opos = ps[p].pos; @@ -2086,8 +2083,8 @@ void movetransports_d(void) int k = 0; - if (onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].on_ground && ps[p].posz > (sector[sect].floorz - (16 << 8)) && (PlayerInput(p, SB_CROUCH) || ps[p].poszv > 2048)) - // if( onfloorz && sectlotag == 1 && ps[p].posz > (sector[sect].floorz-(6<<8)) ) + if (onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].on_ground && ps[p].pos.z > (sectp->floorz - (16 << 8)) && (PlayerInput(p, SB_CROUCH) || ps[p].poszv > 2048)) + // if( onfloorz && sectlotag == 1 && ps[p].pos.z > (sectp->floorz-(6<<8)) ) { k = 1; if (screenpeek == p) @@ -2096,15 +2093,15 @@ void movetransports_d(void) } if (ps[p].GetActor()->s->extra > 0) S_PlayActorSound(DUKE_UNDERWATER, act2); - ps[p].oposz = ps[p].posz = - sector[Owner->s->sectnum].ceilingz + (7 << 8); + ps[p].oposz = ps[p].pos.z = + Owner->getSector()->ceilingz + (7 << 8); ps[p].posxv = 4096 - (krand() & 8192); ps[p].posyv = 4096 - (krand() & 8192); } - if (onfloorz && sectlotag == ST_2_UNDERWATER && ps[p].posz < (sector[sect].ceilingz + (6 << 8))) + if (onfloorz && sectlotag == ST_2_UNDERWATER && ps[p].pos.z < (sectp->ceilingz + (6 << 8))) { k = 1; // if( spr2->extra <= 0) break; @@ -2114,8 +2111,8 @@ void movetransports_d(void) } S_PlayActorSound(DUKE_GASP, act2); - ps[p].oposz = ps[p].posz = - sector[Owner->s->sectnum].floorz - (7 << 8); + ps[p].oposz = ps[p].pos.z = + Owner->getSector()->floorz - (7 << 8); ps[p].jumping_toggle = 1; ps[p].jumping_counter = 0; @@ -2123,15 +2120,15 @@ void movetransports_d(void) if (k == 1) { - ps[p].oposx = ps[p].posx += Owner->s->x - spr->x; - ps[p].oposy = ps[p].posy += Owner->s->y - spr->y; + ps[p].oposx = ps[p].pos.x += Owner->s->x - spr->x; + ps[p].oposy = ps[p].pos.y += Owner->s->y - spr->y; if (!Owner || Owner->GetOwner() != Owner) ps[p].transporter_hold = -2; ps[p].cursectnum = Owner->s->sectnum; changeactorsect(act2, Owner->s->sectnum); - setsprite(ps[p].GetActor(), ps[p].posx, ps[p].posy, ps[p].posz + gs.playerheight); + setsprite(ps[p].GetActor(), ps[p].pos.x, ps[p].pos.y, ps[p].pos.z + gs.playerheight); if ((krand() & 255) < 32) spawn(act2, WATERSPLASH2); @@ -2172,10 +2169,10 @@ void movetransports_d(void) { warpspriteto = 0; - if (ll && sectlotag == 2 && spr2->z < (sector[sect].ceilingz + ll)) + if (ll && sectlotag == 2 && spr2->z < (sectp->ceilingz + ll)) warpspriteto = 1; - if (ll && sectlotag == 1 && spr2->z > (sector[sect].floorz - ll)) + if (ll && sectlotag == 1 && spr2->z > (sectp->floorz - ll)) warpspriteto = 1; if (sectlotag == 0 && (onfloorz || abs(spr2->z - spr->z) < 4096)) @@ -2232,11 +2229,11 @@ void movetransports_d(void) case 0: if (onfloorz) { - if (spr2->statnum == STAT_PROJECTILE || (checkcursectnums(sect) == -1 && checkcursectnums(Owner->s->sectnum) == -1)) + if (spr2->statnum == STAT_PROJECTILE || (checkcursectnums(spr->sectnum) == -1 && checkcursectnums(Owner->s->sectnum) == -1)) { spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z -= spr->z - sector[Owner->s->sectnum].floorz; + spr2->z -= spr->z - Owner->getSector()->floorz; spr2->ang = Owner->s->ang; spr2->backupang(); @@ -2273,7 +2270,7 @@ void movetransports_d(void) case 1: spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z = sector[Owner->s->sectnum].ceilingz + ll; + spr2->z = Owner->getSector()->ceilingz + ll; spr2->backupz(); @@ -2283,7 +2280,7 @@ void movetransports_d(void) case 2: spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z = sector[Owner->s->sectnum].floorz - ll; + spr2->z = Owner->getSector()->floorz - ll; spr2->backupz(); @@ -2313,7 +2310,7 @@ static void greenslime(DDukeActor *actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - int sect = s->sectnum; + auto sectp = s->sector(); int j; // #ifndef isShareware() @@ -2321,7 +2318,7 @@ static void greenslime(DDukeActor *actor) { if (actor_tog == 1) { - s->cstat = (short)32768; + s->cstat = 32768; return; } else if (actor_tog == 2) s->cstat = 257; @@ -2330,7 +2327,7 @@ static void greenslime(DDukeActor *actor) t[1] += 128; - if (sector[sect].floorstat & 1) + if (sectp->floorstat & 1) { deletesprite(actor); return; @@ -2380,7 +2377,7 @@ static void greenslime(DDukeActor *actor) } else if (x < 1024 && ps[p].quick_kick == 0) { - j = getincangle(ps[p].angle.ang.asbuild(), getangle(s->x - ps[p].posx, s->y - ps[p].posy)); + j = getincangle(ps[p].angle.ang.asbuild(), getangle(s->x - ps[p].pos.x, s->y - ps[p].pos.y)); if (j > -128 && j < 128) ps[p].quick_kick = 14; } @@ -2409,7 +2406,7 @@ static void greenslime(DDukeActor *actor) { for (x = 0; x < 8; x++) { - auto j = EGS(sect, s->x, s->y, s->z - (8 << 8), SCRAP3 + (krand() & 3), -8, 48, 48, krand() & 2047, (krand() & 63) + 64, -(krand() & 4095) - (s->zvel >> 2), actor, 5); + auto j = EGS(s->sectnum, s->x, s->y, s->z - (8 << 8), SCRAP3 + (krand() & 3), -8, 48, 48, krand() & 2047, (krand() & 63) + 64, -(krand() & 4095) - (s->zvel >> 2), actor, 5); j->s->pal = 6; } @@ -2428,7 +2425,7 @@ static void greenslime(DDukeActor *actor) return; } - s->z = ps[p].posz + ps[p].pyoff - t[2] + (8 << 8); + s->z = ps[p].pos.z + ps[p].pyoff - t[2] + (8 << 8); s->z += -ps[p].horizon.horiz.asq16() >> 12; @@ -2441,12 +2438,12 @@ static void greenslime(DDukeActor *actor) if (ps[p].newOwner != nullptr) { ps[p].newOwner = nullptr; - ps[p].posx = ps[p].oposx; - ps[p].posy = ps[p].oposy; - ps[p].posz = ps[p].oposz; + ps[p].pos.x = ps[p].oposx; + ps[p].pos.y = ps[p].oposy; + ps[p].pos.z = ps[p].oposz; ps[p].angle.restore(); - updatesector(ps[p].posx, ps[p].posy, &ps[p].cursectnum); + updatesector(ps[p].pos.x, ps[p].pos.y, &ps[p].cursectnum); DukeStatIterator it(STAT_ACTOR); while (auto ac = it.Next()) @@ -2457,7 +2454,7 @@ static void greenslime(DDukeActor *actor) if (t[3] > 0) { - short frames[] = { 5,5,6,6,7,7,6,5 }; + static const uint8_t frames[] = { 5,5,6,6,7,7,6,5 }; s->picnum = GREENSLIME + frames[t[3]]; @@ -2482,8 +2479,8 @@ static void greenslime(DDukeActor *actor) s->xrepeat = 20 + bsin(t[1], -13); s->yrepeat = 15 + bsin(t[1], -13); - s->x = ps[p].posx + ps[p].angle.ang.bcos(-7); - s->y = ps[p].posy + ps[p].angle.ang.bsin(-7); + s->x = ps[p].pos.x + ps[p].angle.ang.bcos(-7); + s->y = ps[p].pos.y + ps[p].angle.ang.bsin(-7); return; } @@ -2524,7 +2521,7 @@ static void greenslime(DDukeActor *actor) for (x = 0; x < 8; x++) { - auto j = EGS(sect, s->x, s->y, s->z - (8 << 8), SCRAP3 + (krand() & 3), -8, 48, 48, krand() & 2047, (krand() & 63) + 64, -(krand() & 4095) - (s->zvel >> 2), actor, 5); + auto j = EGS(s->sectnum, s->x, s->y, s->z - (8 << 8), SCRAP3 + (krand() & 3), -8, 48, 48, krand() & 2047, (krand() & 63) + 64, -(krand() & 4095) - (s->zvel >> 2), actor, 5); j->s->pal = 6; } t[0] = -3; @@ -2589,7 +2586,7 @@ static void greenslime(DDukeActor *actor) //Check randomly to see of there is an actor near if (rnd(32)) { - DukeSectIterator it(sect); + DukeSectIterator it(s->sectnum); while (auto a2 = it.Next()) { if (gs.actorinfo[a2->s->picnum].flags & SFLAG_GREENSLIMEFOOD) @@ -2619,7 +2616,7 @@ static void greenslime(DDukeActor *actor) s->zvel = 0; s->cstat &= (65535 - 8); - if ((sector[sect].ceilingstat & 1) || (actor->ceilingz + 6144) < s->z) + if ((sectp->ceilingstat & 1) || (actor->ceilingz + 6144) < s->z) { s->z += 2048; t[0] = 3; @@ -2645,14 +2642,14 @@ static void greenslime(DDukeActor *actor) s->xvel = 64 - bcos(t[1], -9); s->ang += getincangle(s->ang, - getangle(ps[p].posx - s->x, ps[p].posy - s->y)) >> 3; + getangle(ps[p].pos.x - s->x, ps[p].pos.y - s->y)) >> 3; // TJR } s->xrepeat = 36 + bcos(t[1], -11); s->yrepeat = 16 + bsin(t[1], -13); - if (rnd(4) && (sector[sect].ceilingstat & 1) == 0 && + if (rnd(4) && (sectp->ceilingstat & 1) == 0 && abs(actor->floorz - actor->ceilingz) < (192 << 8)) { @@ -2714,12 +2711,12 @@ static void flamethrowerflame(DDukeActor *actor) { auto s = actor->s; int* t = &actor->temp_data[0]; - int sect = s->sectnum; + auto sectp = s->sector(); int x; int p = findplayer(actor, &x); execute(actor, p, x); t[0]++; - if (sector[sect].lotag == 2) + if (sectp->lotag == 2) { spawn(actor, EXPLOSION2)->s->shade = 127; deletesprite(actor); @@ -2764,11 +2761,11 @@ static void flamethrowerflame(DDukeActor *actor) coll.setSector(s->sectnum); s->zvel = -1; } - else if ((s->z > actor->floorz && sector[s->sectnum].lotag != 1) - || (s->z > actor->floorz + (16 << 8) && sector[s->sectnum].lotag == 1)) + else if ((s->z > actor->floorz && s->sector()->lotag != 1) + || (s->z > actor->floorz + (16 << 8) && s->sector()->lotag == 1)) { coll.setSector(s->sectnum); - if (sector[s->sectnum].lotag != 1) + if (s->sector()->lotag != 1) s->zvel = 1; } } @@ -2817,7 +2814,7 @@ static void heavyhbomb(DDukeActor *actor) auto s = actor->s; auto t = &actor->temp_data[0]; auto Owner = actor->GetOwner(); - int sect = s->sectnum; + auto sectp = s->sector(); int x, l; if ((s->cstat & 32768)) @@ -2854,16 +2851,16 @@ static void heavyhbomb(DDukeActor *actor) { makeitfall(actor); - if (sector[sect].lotag != 1 && s->z >= actor->floorz - (FOURSLEIGHT) && s->yvel < 3) + if (sectp->lotag != 1 && s->z >= actor->floorz - (FOURSLEIGHT) && s->yvel < 3) { - if (s->yvel > 0 || (s->yvel == 0 && actor->floorz == sector[sect].floorz)) + if (s->yvel > 0 || (s->yvel == 0 && actor->floorz == sectp->floorz)) S_PlayActorSound(PIPEBOMB_BOUNCE, actor); s->zvel = -((4 - s->yvel) << 8); - if (sector[s->sectnum].lotag == 2) + if (s->sector()->lotag == 2) s->zvel >>= 2; s->yvel++; } - if (s->z < actor->ceilingz) // && sector[sect].lotag != 2 ) + if (s->z < actor->ceilingz) // && sectp->lotag != 2 ) { s->z = actor->ceilingz + (3 << 8); s->zvel = 0; @@ -2876,7 +2873,7 @@ static void heavyhbomb(DDukeActor *actor) MulScale(s->xvel, bsin(s->ang), 14), s->zvel, CLIPMASK0, coll); - if (sector[s->sectnum].lotag == 1 && s->zvel == 0) + if (s->sector()->lotag == 1 && s->zvel == 0) { s->z += (32 << 8); if (t[5] == 0) @@ -2903,7 +2900,7 @@ static void heavyhbomb(DDukeActor *actor) if (s->xvel > 0) { s->xvel -= 5; - if (sector[sect].lotag == 2) + if (sectp->lotag == 2) s->xvel -= 10; if (s->xvel < 0) @@ -2975,14 +2972,14 @@ DETONATEB: { t[2] = gs.respawnitemtime; spawn(actor, RESPAWNMARKERRED); - s->cstat = (short)32768; + s->cstat = 32768; s->yrepeat = 9; return; } } } else if (s->picnum == HEAVYHBOMB && x < 788 && t[0] > 7 && s->xvel == 0) - if (cansee(s->x, s->y, s->z - (8 << 8), s->sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum)) + if (cansee(s->x, s->y, s->z - (8 << 8), s->sectnum, ps[p].pos.x, ps[p].pos.y, ps[p].pos.z, ps[p].cursectnum)) if (ps[p].ammo_amount[HANDBOMB_WEAPON] < gs.max_ammo_amount[HANDBOMB_WEAPON]) { if (ud.coop >= 1 && Owner == actor) @@ -3018,7 +3015,7 @@ DETONATEB: { t[2] = gs.respawnitemtime; spawn(actor, RESPAWNMARKERRED); - s->cstat = (short)32768; + s->cstat = 32768; } } @@ -3190,7 +3187,7 @@ void moveactors_d(void) { if (actor_tog == 1) { - s->cstat = (short)32768; + s->cstat = 32768; continue; } else if (actor_tog == 2) s->cstat = 257; @@ -3255,22 +3252,22 @@ static void fireflyflyingeffect(DDukeActor *actor) void moveexplosions_d(void) // STATNUM 5 { - int sect, p; + int p; int x; DukeStatIterator it(STAT_MISC); while (auto act = it.Next()) { auto s = act->s; - int* t = &act->temp_data[0]; - sect = s->sectnum; - if (sect < 0 || s->xrepeat == 0) + if (s->sectnum < 0 || s->xrepeat == 0) { deletesprite(act); continue; } + int* t = &act->temp_data[0]; + auto sectp = s->sector(); switch (s->picnum) { @@ -3415,7 +3412,7 @@ void moveexplosions_d(void) // STATNUM 5 case SHELL: case SHOTGUNSHELL: - shell(act, (sector[sect].floorz + (24 << 8)) < s->z); + shell(act, (sectp->floorz + (24 << 8)) < s->z); continue; case GLASSPIECES: @@ -3443,7 +3440,7 @@ void handle_se06_d(DDukeActor* actor) auto s = actor->s; auto t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3497,7 +3494,7 @@ void handle_se06_d(DDukeActor* actor) static void handle_se28(DDukeActor* actor) { auto s = actor->s; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; int* t = &actor->temp_data[0]; @@ -3542,7 +3539,7 @@ static void handle_se28(DDukeActor* actor) } else if (t[2] > (t[1] >> 3) && t[2] < (t[1] >> 2)) { - int j = !!cansee(s->x, s->y, s->z, s->sectnum, ps[screenpeek].posx, ps[screenpeek].posy, ps[screenpeek].posz, ps[screenpeek].cursectnum); + int j = !!cansee(s->x, s->y, s->z, s->sectnum, ps[screenpeek].pos.x, ps[screenpeek].pos.y, ps[screenpeek].pos.z, ps[screenpeek].cursectnum); if (rnd(192) && (t[2] & 1)) { @@ -3596,7 +3593,7 @@ void moveeffectors_d(void) //STATNUM 3 DukeStatIterator it(STAT_EFFECTOR); while (auto act = it.Next()) { - auto sc = §or[act->s->sectnum]; + auto sc = act->getSector(); switch (act->s->lotag) { case SE_0_ROTATING_SECTOR: @@ -3696,8 +3693,8 @@ void moveeffectors_d(void) //STATNUM 3 case SE_24_CONVEYOR: case SE_34: { - static int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, FOOTPRINTS4, BULLETHOLE, BLOODSPLAT1, BLOODSPLAT2, BLOODSPLAT3, BLOODSPLAT4, -1 }; - static int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, SIDEBOLT1, SIDEBOLT1 + 1, SIDEBOLT1 + 2, SIDEBOLT1 + 3, -1 }; + static const int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, FOOTPRINTS4, BULLETHOLE, BLOODSPLAT1, BLOODSPLAT2, BLOODSPLAT3, BLOODSPLAT4, -1 }; + static const int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, SIDEBOLT1, SIDEBOLT1 + 1, SIDEBOLT1 + 2, SIDEBOLT1 + 3, -1 }; handle_se24(act, list1, list2, true, TRIPBOMB, LASERLINE, CRANE, 2); break; } @@ -3768,10 +3765,10 @@ void moveeffectors_d(void) //STATNUM 3 while (auto act = it.Next()) { if (act->s->lotag != SE_29_WAVES) continue; - auto sc = §or[act->s->sectnum]; + auto sc = act->getSector(); if (sc->wallnum != 4) continue; auto wal = &wall[sc->wallptr + 2]; - alignflorslope(act->s->sectnum, wal->x, wal->y, sector[wal->nextsector].floorz); + alignflorslope(act->s->sectnum, wal->x, wal->y, wal->nextSector()->floorz); } } @@ -3786,7 +3783,7 @@ void move_d(DDukeActor *actor, int playernum, int xvel) auto spr = actor->s; auto t = actor->temp_data; int l; - short goalang, angdif; + int goalang, angdif; int daxvel; int a = spr->hitag; @@ -3799,7 +3796,7 @@ void move_d(DDukeActor *actor, int playernum, int xvel) { if (ps[playernum].newOwner != nullptr) goalang = getangle(ps[playernum].oposx - spr->x, ps[playernum].oposy - spr->y); - else goalang = getangle(ps[playernum].posx - spr->x, ps[playernum].posy - spr->y); + else goalang = getangle(ps[playernum].pos.x - spr->x, ps[playernum].pos.y - spr->y); angdif = getincangle(spr->ang, goalang) >> 2; if (angdif > -8 && angdif < 0) angdif = 0; spr->ang += angdif; @@ -3812,7 +3809,7 @@ void move_d(DDukeActor *actor, int playernum, int xvel) { if (ps[playernum].newOwner != nullptr) goalang = getangle(ps[playernum].oposx - spr->x, ps[playernum].oposy - spr->y); - else goalang = getangle(ps[playernum].posx - spr->x, ps[playernum].posy - spr->y); + else goalang = getangle(ps[playernum].pos.x - spr->x, ps[playernum].pos.y - spr->y); angdif = Sgn(getincangle(spr->ang, goalang)) << 5; if (angdif > -32 && angdif < 0) { @@ -3833,8 +3830,8 @@ void move_d(DDukeActor *actor, int playernum, int xvel) { int newx, newy; - newx = ps[playernum].posx + (ps[playernum].posxv / 768); - newy = ps[playernum].posy + (ps[playernum].posyv / 768); + newx = ps[playernum].pos.x + (ps[playernum].posxv / 768); + newy = ps[playernum].pos.y + (ps[playernum].posyv / 768); goalang = getangle(newx - spr->x, newy - spr->y); angdif = getincangle(spr->ang, goalang) >> 2; if (angdif > -8 && angdif < 0) angdif = 0; @@ -3935,7 +3932,7 @@ void move_d(DDukeActor *actor, int playernum, int xvel) { daxvel = -(1024 - xvel); - angdif = getangle(ps[playernum].posx - spr->x, ps[playernum].posy - spr->y); + angdif = getangle(ps[playernum].pos.x - spr->x, ps[playernum].pos.y - spr->y); if (xvel < 512) { @@ -3971,11 +3968,11 @@ void move_d(DDukeActor *actor, int playernum, int xvel) if (a) { - if (sector[spr->sectnum].ceilingstat & 1) - spr->shade += (sector[spr->sectnum].ceilingshade - spr->shade) >> 1; - else spr->shade += (sector[spr->sectnum].floorshade - spr->shade) >> 1; + if (spr->sector()->ceilingstat & 1) + spr->shade += (spr->sector()->ceilingshade - spr->shade) >> 1; + else spr->shade += (spr->sector()->floorshade - spr->shade) >> 1; - if (sector[spr->sectnum].floorpicnum == MIRROR) + if (spr->sector()->floorpicnum == MIRROR) deletesprite(actor); } } diff --git a/source/games/duke/src/actors_lava.cpp b/source/games/duke/src/actors_lava.cpp index 396269616..87cb045d4 100644 --- a/source/games/duke/src/actors_lava.cpp +++ b/source/games/duke/src/actors_lava.cpp @@ -38,7 +38,7 @@ static int jaildoorcnt; static int minecartcnt; static int lightnincnt; -static short torchsector[64]; +static int torchsector[64]; static short torchsectorshade[64]; static short torchtype[64]; @@ -49,18 +49,18 @@ static short jaildoorsecthtag[32]; static int jaildoordist[32]; static short jaildoordir[32]; static short jaildooropen[32]; -static short jaildoorsect[32]; +static int jaildoorsect[32]; static short minecartdir[16]; static int minecartspeed[16]; -static short minecartchildsect[16]; +static int minecartchildsect[16]; static short minecartsound[16]; static int minecartdist[16]; static int minecartdrag[16]; static short minecartopen[16]; -static short minecartsect[16]; +static int minecartsect[16]; -static short lightninsector[64]; +static int lightninsector[64]; static short lightninsectorshade[64]; static uint8_t brightness; @@ -128,7 +128,7 @@ void addtorch(spritetype* s) I_Error("Too many torch effects"); torchsector[torchcnt] = s->sectnum; - torchsectorshade[torchcnt] = sector[s->sectnum].floorshade; + torchsectorshade[torchcnt] = s->sector()->floorshade; torchtype[torchcnt] = s->lotag; torchcnt++; } @@ -139,7 +139,7 @@ void addlightning(spritetype* s) I_Error("Too many lightnin effects"); lightninsector[lightnincnt] = s->sectnum; - lightninsectorshade[lightnincnt] = sector[s->sectnum].floorshade; + lightninsectorshade[lightnincnt] = s->sector()->floorshade; lightnincnt++; } @@ -189,34 +189,35 @@ void addminecart(int p1, int p2, int i, int iht, int p3, int childsectnum) void dotorch(void) { int ds; - short j; - short startwall, endwall; - char shade; + int j; + int startwall, endwall; + uint8_t shade; ds = krand()&8; for (int i = 0; i < torchcnt; i++) { + auto sect = §or[torchsector[i]]; shade = torchsectorshade[i] - ds; switch (torchtype[i]) { case 0: - sector[torchsector[i]].floorshade = shade; - sector[torchsector[i]].ceilingshade = shade; + sect->floorshade = shade; + sect->ceilingshade = shade; break; case 1: - sector[torchsector[i]].ceilingshade = shade; + sect->ceilingshade = shade; break; case 2: - sector[torchsector[i]].floorshade = shade; + sect->floorshade = shade; break; case 4: - sector[torchsector[i]].ceilingshade = shade; + sect->ceilingshade = shade; break; case 5: - sector[torchsector[i]].floorshade = shade; + sect->floorshade = shade; break; } - startwall = sector[torchsector[i]].wallptr; - endwall = startwall + sector[torchsector[i]].wallnum; + startwall = sect->wallptr; + endwall = startwall + sect->wallnum; for (j = startwall; j < endwall; j++) { if (wall[j].lotag != 1) @@ -255,6 +256,7 @@ void dojaildoor(void) int speed; for (int i = 0; i < jaildoorcnt; i++) { + auto sectp = §or[jaildoorsect[i]]; if (numplayers > 2) speed = jaildoorspeed[i]; else @@ -286,8 +288,8 @@ void dojaildoor(void) } else { - startwall = sector[jaildoorsect[i]].wallptr; - endwall = startwall + sector[jaildoorsect[i]].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (j = startwall; j < endwall; j++) { x = wall[j].x; @@ -336,27 +338,28 @@ void dojaildoor(void) } else { - startwall = sector[jaildoorsect[i]].wallptr; - endwall = startwall + sector[jaildoorsect[i]].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (j = startwall; j < endwall; j++) { + auto wal = &wall[j]; switch (jaildoordir[i]) { case 10: - x = wall[j].x; - y = wall[j].y + speed; + x = wal->x; + y = wal->y + speed; break; case 20: - x = wall[j].x - speed; - y = wall[j].y; + x = wal->x - speed; + y = wal->y; break; case 30: - x = wall[j].x; - y = wall[j].y - speed; + x = wal->x; + y = wal->y - speed; break; case 40: - x = wall[j].x + speed; - y = wall[j].y; + x = wal->x + speed; + y = wal->y; break; } dragpoint(j,x,y); @@ -374,11 +377,11 @@ void dojaildoor(void) void moveminecart(void) { - short i; - short j; - short csect; - short startwall; - short endwall; + int i; + int j; + int csect; + int startwall; + int endwall; int speed; int y; int x; @@ -390,6 +393,7 @@ void moveminecart(void) int min_x; for (i = 0; i < minecartcnt; i++) { + auto sectp = §or[minecartsect[i]]; speed = minecartspeed[i]; if (speed < 2) speed = 2; @@ -419,8 +423,8 @@ void moveminecart(void) } else { - startwall = sector[minecartsect[i]].wallptr; - endwall = startwall + sector[minecartsect[i]].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (j = startwall; j < endwall; j++) { switch (minecartdir[i]) @@ -471,27 +475,28 @@ void moveminecart(void) } else { - startwall = sector[minecartsect[i]].wallptr; - endwall = startwall + sector[minecartsect[i]].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (j = startwall; j < endwall; j++) { + auto wal = &wall[j]; switch (minecartdir[i]) { case 10: - x = wall[j].x; - y = wall[j].y + speed; + x = wal->x; + y = wal->y + speed; break; case 20: - x = wall[j].x - speed; - y = wall[j].y; + x = wal->x - speed; + y = wal->y; break; case 30: - x = wall[j].x; - y = wall[j].y - speed; + x = wal->x; + y = wal->y - speed; break; case 40: - x = wall[j].x + speed; - y = wall[j].y; + x = wal->x + speed; + y = wal->y; break; } dragpoint(j,x,y); @@ -556,7 +561,7 @@ void thunder(void) { struct player_struct* p; int r1, r2; - short startwall, endwall, i, j; + int startwall, endwall, i, j; uint8_t shade; p = &ps[screenpeek]; @@ -610,10 +615,11 @@ void thunder(void) winderflash = 0; for (i = 0; i < lightnincnt; i++) { - startwall = sector[lightninsector[i]].wallptr; - endwall = startwall + sector[lightninsector[i]].wallnum; - sector[lightninsector[i]].floorshade = (int8_t)lightninsectorshade[i]; - sector[lightninsector[i]].ceilingshade = (int8_t)lightninsectorshade[i]; + auto sectp = §or[lightninsector[i]]; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; + sectp->floorshade = (int8_t)lightninsectorshade[i]; + sectp->ceilingshade = (int8_t)lightninsectorshade[i]; for (j = startwall; j < endwall; j++) wall[j].shade = (int8_t)lightninsectorshade[i]; } @@ -651,10 +657,11 @@ void thunder(void) shade = torchsectorshade[i] + r2; for (i = 0; i < lightnincnt; i++) { - startwall = sector[lightninsector[i]].wallptr; - endwall = startwall + sector[lightninsector[i]].wallnum; - sector[lightninsector[i]].floorshade = lightninsectorshade[i] - shade; - sector[lightninsector[i]].ceilingshade = lightninsectorshade[i] - shade; + auto sectp = §or[lightninsector[i]]; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; + sectp->floorshade = lightninsectorshade[i] - shade; + sectp->ceilingshade = lightninsectorshade[i] - shade; for (j = startwall; j < endwall; j++) wall[j].shade = lightninsectorshade[i] - shade; } diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 070fc2239..3d6b20ca5 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -38,10 +38,10 @@ void dojaildoor(); void moveminecart(); void ballreturn(DDukeActor* spr); -short pinsectorresetdown(short sect); -short pinsectorresetup(short sect); -short checkpins(short sect); -void resetpins(short sect); +void pinsectorresetdown(int sect); +int pinsectorresetup(int sect); +int checkpins(int sect); +void resetpins(int sect); void resetlanepics(void); @@ -51,11 +51,11 @@ void resetlanepics(void); // //--------------------------------------------------------------------------- -bool ceilingspace_r(int sectnum) +bool ceilingspace_r(sectortype* sectp) { - if( (sector[sectnum].ceilingstat&1) && sector[sectnum].ceilingpal == 0 ) + if( (sectp->ceilingstat&1) && sectp->ceilingpal == 0 ) { - switch(sector[sectnum].ceilingpicnum) + switch(sectp->ceilingpicnum) { case MOONSKY1: case BIGORBIT1: @@ -65,17 +65,18 @@ bool ceilingspace_r(int sectnum) return 0; } + //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- -bool floorspace_r(int sectnum) +bool floorspace_r(sectortype* sectp) { - if( (sector[sectnum].floorstat&1) && sector[sectnum].ceilingpal == 0 ) + if( (sectp->floorstat&1) && sectp->ceilingpal == 0 ) { - switch(sector[sectnum].floorpicnum) + switch(sectp->floorpicnum) { case MOONSKY1: case BIGORBIT1: @@ -115,7 +116,7 @@ void check_fta_sounds_r(DDukeActor* actor) void addweapon_r(struct player_struct* p, int weapon) { - short cw = p->curr_weapon; + int cw = p->curr_weapon; if (p->OnMotorcycle || p->OnBoat) { p->gotweapon[weapon] = true;; @@ -217,11 +218,13 @@ void addweapon_r(struct player_struct* p, int weapon) void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4) { walltype* wal; + sectortype* dasectp; int d, q, x1, y1; int sectcnt, sectend, dasect, startwall, endwall, nextsect; - short p, x, sect; + int p, x; + int sect; static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC }; - short tempshort[MAXSECTORS]; // originally hijacked a global buffer which is bad. Q: How many do we really need? RedNukem says 64. + int tempsect[128]; // originally hijacked a global buffer which is bad. Q: How many do we really need? RedNukem says 64. auto spri = actor->s; @@ -230,29 +233,30 @@ void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h if (spri->picnum == RPG || ((isRRRA()) && spri->picnum == RPG2)) goto SKIPWALLCHECK; } - tempshort[0] = spri->sectnum; + tempsect[0] = spri->sectnum; dasect = spri->sectnum; + dasectp = spri->sector(); sectcnt = 0; sectend = 1; do { - dasect = tempshort[sectcnt++]; - if (((sector[dasect].ceilingz - spri->z) >> 8) < r) + dasect = tempsect[sectcnt++]; + if (((dasectp->ceilingz - spri->z) >> 8) < r) { - d = abs(wall[sector[dasect].wallptr].x - spri->x) + abs(wall[sector[dasect].wallptr].y - spri->y); + d = abs(wall[dasectp->wallptr].x - spri->x) + abs(wall[dasectp->wallptr].y - spri->y); if (d < r) fi.checkhitceiling(dasect); else { // ouch... - d = abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x - spri->x) + abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].y - spri->y); + d = abs(wall[wall[wall[dasectp->wallptr].point2].point2].x - spri->x) + abs(wall[wall[wall[dasectp->wallptr].point2].point2].y - spri->y); if (d < r) fi.checkhitceiling(dasect); } } - startwall = sector[dasect].wallptr; - endwall = startwall + sector[dasect].wallnum; + startwall = dasectp->wallptr; + endwall = startwall + dasectp->wallnum; for (x = startwall, wal = &wall[startwall]; x < endwall; x++, wal++) if ((abs(wal->x - spri->x) + abs(wal->y - spri->y)) < r) { @@ -260,8 +264,8 @@ void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h if (nextsect >= 0) { for (dasect = sectend - 1; dasect >= 0; dasect--) - if (tempshort[dasect] == nextsect) break; - if (dasect < 0) tempshort[sectend++] = nextsect; + if (tempsect[dasect] == nextsect) break; + if (dasect < 0) tempsect[sectend++] = nextsect; } x1 = (((wal->x + wall[wal->point2].x) >> 1) + spri->x) >> 1; y1 = (((wal->y + wall[wal->point2].y) >> 1) + spri->y) >> 1; @@ -269,7 +273,7 @@ void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h if (sect >= 0 && cansee(x1, y1, spri->z, sect, spri->x, spri->y, spri->z, spri->sectnum)) fi.checkhitwall(actor, x, wal->x, wal->y, spri->z, spri->picnum); } - } while (sectcnt < sectend); + } while (sectcnt < sectend && sectcnt < (int)countof(tempsect)); SKIPWALLCHECK: @@ -381,8 +385,8 @@ SKIPWALLCHECK: int movesprite_ex_r(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision &result) { - int daz, h, oldx, oldy; - short retval, dasectnum, cd; + int dasectnum; + int clipdist; auto spri = actor->s; int bg = badguy(actor); @@ -397,58 +401,53 @@ int movesprite_ex_r(DDukeActor* actor, int xchange, int ychange, int zchange, un } dasectnum = spri->sectnum; + auto dasectp = spri->sector(); - daz = spri->z; - h = ((tileHeight(spri->picnum) * spri->yrepeat) << 1); - daz -= h; + vec3_t pos = spri->pos; + pos.z -= ((tileHeight(spri->picnum) * spri->yrepeat) << 1); if (bg) { - oldx = spri->x; - oldy = spri->y; - if (spri->xrepeat > 60) - retval = clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024L, (4 << 8), (4 << 8), cliptype); + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024, (4 << 8), (4 << 8), cliptype, result); else { - cd = 192; - retval = clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), cd, (4 << 8), (4 << 8), cliptype); + clipdist = 192; + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), clipdist, (4 << 8), (4 << 8), cliptype, result); } if (dasectnum < 0 || (dasectnum >= 0 && actor->actorstayput >= 0 && actor->actorstayput != dasectnum)) { - spri->x = oldx; - spri->y = oldy; - if (sector[dasectnum].lotag == ST_1_ABOVE_WATER) + if (dasectp->lotag == ST_1_ABOVE_WATER) spri->ang = (krand() & 2047); else if ((actor->temp_data[0] & 3) == 1) spri->ang = (krand() & 2047); - setsprite(actor, oldx, oldy, spri->z); + setsprite(actor, spri->pos); if (dasectnum < 0) dasectnum = 0; return result.setSector(dasectnum); } - if ((retval & kHitTypeMask) > kHitSector && (actor->cgg == 0)) spri->ang += 768; + if ((result.type == kHitSector || result.type == kHitSprite) && (actor->cgg == 0)) spri->ang += 768; } else { if (spri->statnum == STAT_PROJECTILE) - retval = - clipmove_ex(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8L, (4 << 8), (4 << 8), cliptype, result); + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8, (4 << 8), (4 << 8), cliptype, result); else - retval = - clipmove_ex(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 128, (4 << 8), (4 << 8), cliptype, result); + clipmove_ex(&pos, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 128, (4 << 8), (4 << 8), cliptype, result); } + spri->x = pos.x; + spri->y = pos.y; if (dasectnum >= 0) if ((dasectnum != spri->sectnum)) changeactorsect(actor, dasectnum); - daz = spri->z + ((zchange * TICSPERFRAME) >> 3); + int daz = spri->z + ((zchange * TICSPERFRAME) >> 3); if ((daz > actor->ceilingz) && (daz <= actor->floorz)) spri->z = daz; - else if (retval == 0) + else if (result.type == kHitNone) return result.setSector(dasectnum); - return retval; + return result.type; } //--------------------------------------------------------------------------- @@ -457,7 +456,7 @@ int movesprite_ex_r(DDukeActor* actor, int xchange, int ychange, int zchange, un // //--------------------------------------------------------------------------- -void lotsoffeathers_r(DDukeActor *actor, short n) +void lotsoffeathers_r(DDukeActor *actor, int n) { lotsofstuff(actor, n, MONEY); } @@ -469,7 +468,7 @@ void lotsoffeathers_r(DDukeActor *actor, short n) // //--------------------------------------------------------------------------- -void guts_r(DDukeActor* actor, short gtype, short n, short p) +void guts_r(DDukeActor* actor, int gtype, int n, int p) { auto s = actor->s; int gutz, floorz; @@ -526,7 +525,8 @@ void guts_r(DDukeActor* actor, short gtype, short n, short p) void movefta_r(void) { int x, px, py, sx, sy; - short j, p, psect, ssect; + int j, p; + int psect, ssect; DukeStatIterator it(STAT_ZOMBIEACTOR); while(auto act = it.Next()) @@ -592,9 +592,9 @@ void movefta_r(void) case NUKEBARREL: case NUKEBARRELDENTED: case NUKEBARRELLEAKED: - if (sector[s->sectnum].ceilingstat & 1) - s->shade = sector[s->sectnum].ceilingshade; - else s->shade = sector[s->sectnum].floorshade; + if (s->sector()->ceilingstat & 1) + s->shade = s->sector()->ceilingshade; + else s->shade = s->sector()->floorshade; act->timetosleep = 0; changeactorstat(act, STAT_STANDABLE); @@ -602,7 +602,7 @@ void movefta_r(void) default: #if 0 // TRANSITIONAL: RedNukem has this here. Needed? - if (actorflag(act, SFLAG_USEACTIVATOR) && sector[act->s.lotag & 16384) break; + if (actorflag(act, SFLAG_USEACTIVATOR) && sector [act->s.lotag & 16384) break; #endif act->timetosleep = 0; check_fta_sounds_r(act); @@ -614,9 +614,9 @@ void movefta_r(void) } if (/*!j &&*/ badguy(act)) // this is like RedneckGDX. j is uninitialized here, i.e. most likely not 0. { - if (sector[s->sectnum].ceilingstat & 1) - s->shade = sector[s->sectnum].ceilingshade; - else s->shade = sector[s->sectnum].floorshade; + if (s->sector()->ceilingstat & 1) + s->shade = s->sector()->ceilingshade; + else s->shade = s->sector()->floorshade; if (s->picnum == HEN || s->picnum == COW || s->picnum == PIG || s->picnum == DOGRUN || ((isRRRA()) && s->picnum == RABBIT)) { @@ -801,7 +801,7 @@ void movefallers_r(void) while (auto act = it.Next()) { auto s = act->s; - int sect = s->sectnum; + auto sectp = s->sector(); if (act->temp_data[0] == 0) { @@ -855,23 +855,23 @@ void movefallers_r(void) } int x; - if (fi.floorspace(s->sectnum)) x = 0; + if (fi.floorspace(s->sector())) x = 0; else { - if (fi.ceilingspace(s->sectnum)) + if (fi.ceilingspace(s->sector())) x = gs.gravity / 6; else x = gs.gravity; } - if (s->z < (sector[sect].floorz - FOURSLEIGHT)) + if (s->z < (sectp->floorz - FOURSLEIGHT)) { s->zvel += x; if (s->zvel > 6144) s->zvel = 6144; s->z += s->zvel; } - if ((sector[sect].floorz - s->z) < (16 << 8)) + if ((sectp->floorz - s->z) < (16 << 8)) { int j = 1 + (krand() & 7); for (x = 0; x < j; x++) RANDOMSCRAP(act); @@ -934,20 +934,20 @@ static void movebolt(DDukeActor* actor) auto s = actor->s; int* t = &actor->temp_data[0]; int x; - int sect = s->sectnum; + auto sectp = s->sector(); auto p = findplayer(actor, &x); if (x > 20480) return; if (t[3] == 0) - t[3] = sector[sect].floorshade; + t[3] = sectp->floorshade; CLEAR_THE_BOLT: if (t[2]) { t[2]--; - sector[sect].floorshade = 20; - sector[sect].ceilingshade = 20; + sectp->floorshade = 20; + sectp->ceilingshade = 20; return; } if ((s->xrepeat | s->yrepeat) == 0) @@ -970,20 +970,20 @@ CLEAR_THE_BOLT: if (l & 1) s->cstat ^= 2; - if (s->picnum == (BOLT1 + 1) && (krand() & 1) && sector[sect].floorpicnum == HURTRAIL) + if (s->picnum == (BOLT1 + 1) && (krand() & 1) && sectp->floorpicnum == HURTRAIL) S_PlayActorSound(SHORT_CIRCUIT, actor); if (s->picnum == BOLT1 + 4) s->picnum = BOLT1; if (s->picnum & 1) { - sector[sect].floorshade = 0; - sector[sect].ceilingshade = 0; + sectp->floorshade = 0; + sectp->ceilingshade = 0; } else { - sector[sect].floorshade = 20; - sector[sect].ceilingshade = 20; + sectp->floorshade = 20; + sectp->ceilingshade = 20; } } @@ -1098,7 +1098,7 @@ static void chickenarrow(DDukeActor* actor) { auto s = actor->s; s->hitag++; - if (actor->picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + if (actor->picnum != BOSS2 && s->xrepeat >= 10 && s->sector()->lotag != 2) { auto spawned = spawn(actor, SMALLSMOKE); spawned->s->z += (1 << 8); @@ -1320,8 +1320,8 @@ bool weaponhitsector(DDukeActor *proj, const vec3_t& oldpos) if (s->zvel < 0) { - if (sector[s->sectnum].ceilingstat & 1) - if (sector[s->sectnum].ceilingpal == 0) + if (s->sector()->ceilingstat & 1) + if (s->sector()->ceilingpal == 0) { deletesprite(proj); return true; @@ -1359,12 +1359,12 @@ static void weaponcommon_r(DDukeActor *proj) p = -1; - if (s->picnum == RPG && sector[s->sectnum].lotag == 2) + if (s->picnum == RPG && s->sector()->lotag == 2) { k = s->xvel >> 1; ll = s->zvel >> 1; } - else if (isRRRA() && s->picnum == RPG2 && sector[s->sectnum].lotag == 2) + else if (isRRRA() && s->picnum == RPG2 && s->sector()->lotag == 2) { k = s->xvel >> 1; ll = s->zvel >> 1; @@ -1382,7 +1382,7 @@ static void weaponcommon_r(DDukeActor *proj) switch (s->picnum) { case RPG: - if (proj->picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + if (proj->picnum != BOSS2 && s->xrepeat >= 10 && s->sector()->lotag != 2) { spawn(proj, SMALLSMOKE)->s->z += (1 << 8); } @@ -1401,7 +1401,7 @@ static void weaponcommon_r(DDukeActor *proj) } else makeitfall(proj); - if (s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + if (s->xrepeat >= 10 && s->sector()->lotag != 2) { spawn(proj, SMALLSMOKE)->s->z += (1 << 8); } @@ -1417,7 +1417,7 @@ static void weaponcommon_r(DDukeActor *proj) if (FindDistance2D(s->x - proj->temp_actor->s->x, s->y - proj->temp_actor->s->y) < 256) coll.setSprite(proj->temp_actor); - if (s->sectnum < 0) // || (isRR() && sector[s->sectnum].filler == 800)) + if (s->sectnum < 0) // || (isRR() && s->sector()->filler == 800)) { deletesprite(proj); return; @@ -1434,7 +1434,7 @@ static void weaponcommon_r(DDukeActor *proj) if (s->z > proj->floorz) { coll.setSector(s->sectnum); - if (sector[s->sectnum].lotag != 1) + if (s->sector()->lotag != 1) s->zvel = 1; } } @@ -1493,7 +1493,7 @@ static void weaponcommon_r(DDukeActor *proj) deletesprite(proj); return; } - if ((s->picnum == RPG || (isRRRA() && s->picnum == RPG2)) && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(184)) + if ((s->picnum == RPG || (isRRRA() && s->picnum == RPG2)) && s->sector()->lotag == 2 && s->xrepeat >= 10 && rnd(184)) spawn(proj, WATERBUBBLE); } @@ -1567,8 +1567,8 @@ void moveweapons_r(void) void movetransports_r(void) { - char warpdir, warpspriteto; - short k, p, sect, sectlotag; + uint8_t warpdir, warpspriteto; + int k, p, sectlotag; int ll2, ll, onfloorz; Collision coll; @@ -1578,8 +1578,8 @@ void movetransports_r(void) while (auto act = iti.Next()) { auto spr = act->s; - sect = spr->sectnum; - sectlotag = sector[sect].lotag; + auto sectp = spr->sector(); + sectlotag = sectp->lotag; auto Owner = act->GetOwner(); if (Owner == act || Owner == nullptr) @@ -1591,7 +1591,7 @@ void movetransports_r(void) if (act->temp_data[0] > 0) act->temp_data[0]--; - DukeSectIterator itj(sect); + DukeSectIterator itj(spr->sectnum); while (auto act2 = itj.Next()) { auto spr2 = act2->s; @@ -1628,9 +1628,9 @@ void movetransports_r(void) ps[p].transporter_hold = 13; } - ps[p].bobposx = ps[p].oposx = ps[p].posx = Owner->s->x; - ps[p].bobposy = ps[p].oposy = ps[p].posy = Owner->s->y; - ps[p].oposz = ps[p].posz = Owner->s->z - (gs.playerheight - (4 << 8)); + ps[p].bobposx = ps[p].oposx = ps[p].pos.x = Owner->s->x; + ps[p].bobposy = ps[p].oposy = ps[p].pos.y = Owner->s->y; + ps[p].oposz = ps[p].pos.z = Owner->s->z - (gs.playerheight - (4 << 8)); changeactorsect(act2, Owner->s->sectnum); ps[p].cursectnum = spr2->sectnum; @@ -1643,17 +1643,17 @@ void movetransports_r(void) } else break; - if (onfloorz == 0 && abs(spr->z - ps[p].posz) < 6144) + if (onfloorz == 0 && abs(spr->z - ps[p].pos.z) < 6144) if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && PlayerInput(p, SB_JUMP)) || (ps[p].jetpack_on && PlayerInput(p, SB_CROUCH))) { - ps[p].oposx = ps[p].posx += Owner->s->x - spr->x; - ps[p].oposy = ps[p].posy += Owner->s->y - spr->y; + ps[p].oposx = ps[p].pos.x += Owner->s->x - spr->x; + ps[p].oposy = ps[p].pos.y += Owner->s->y - spr->y; if (ps[p].jetpack_on && (PlayerInput(p, SB_JUMP) || ps[p].jetpack_on < 11)) - ps[p].posz = Owner->s->z - 6144; - else ps[p].posz = Owner->s->z + 6144; - ps[p].oposz = ps[p].posz; + ps[p].pos.z = Owner->s->z - 6144; + else ps[p].pos.z = Owner->s->z + 6144; + ps[p].oposz = ps[p].pos.z; changeactorsect(act2, Owner->s->sectnum); ps[p].cursectnum = Owner->s->sectnum; @@ -1665,23 +1665,23 @@ void movetransports_r(void) if (isRRRA()) { - if (onfloorz && sectlotag == 160 && ps[p].posz > (sector[sect].floorz - (48 << 8))) + if (onfloorz && sectlotag == 160 && ps[p].pos.z > (sectp->floorz - (48 << 8))) { k = 2; - ps[p].oposz = ps[p].posz = - sector[Owner->s->sectnum].ceilingz + (7 << 8); + ps[p].oposz = ps[p].pos.z = + Owner->getSector()->ceilingz + (7 << 8); } - if (onfloorz && sectlotag == 161 && ps[p].posz < (sector[sect].ceilingz + (6 << 8))) + if (onfloorz && sectlotag == 161 && ps[p].pos.z < (sectp->ceilingz + (6 << 8))) { k = 2; if (ps[p].GetActor()->s->extra <= 0) break; - ps[p].oposz = ps[p].posz = - sector[Owner->s->sectnum].floorz - (49 << 8); + ps[p].oposz = ps[p].pos.z = + Owner->getSector()->floorz - (49 << 8); } } - if ((onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].posz > (sector[sect].floorz - (6 << 8))) || + if ((onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].pos.z > (sectp->floorz - (6 << 8))) || (onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].OnMotorcycle)) { if (ps[p].OnBoat) break; @@ -1691,13 +1691,13 @@ void movetransports_r(void) FX_StopAllSounds(); } S_PlayActorSound(DUKE_UNDERWATER, ps[p].GetActor()); - ps[p].oposz = ps[p].posz = - sector[Owner->s->sectnum].ceilingz + (7 << 8); + ps[p].oposz = ps[p].pos.z = + Owner->getSector()->ceilingz + (7 << 8); if (ps[p].OnMotorcycle) ps[p].moto_underwater = 1; } - if (onfloorz && sectlotag == ST_2_UNDERWATER && ps[p].posz < (sector[sect].ceilingz + (6 << 8))) + if (onfloorz && sectlotag == ST_2_UNDERWATER && ps[p].pos.z < (sectp->ceilingz + (6 << 8))) { k = 1; if (ps[p].GetActor()->s->extra <= 0) break; @@ -1707,14 +1707,14 @@ void movetransports_r(void) } S_PlayActorSound(DUKE_GASP, ps[p].GetActor()); - ps[p].oposz = ps[p].posz = - sector[Owner->s->sectnum].floorz - (7 << 8); + ps[p].oposz = ps[p].pos.z = + Owner->getSector()->floorz - (7 << 8); } if (k == 1) { - ps[p].oposx = ps[p].posx += Owner->s->x - spr->x; - ps[p].oposy = ps[p].posy += Owner->s->y - spr->y; + ps[p].oposx = ps[p].pos.x += Owner->s->x - spr->x; + ps[p].oposy = ps[p].pos.y += Owner->s->y - spr->y; if (Owner->GetOwner() != Owner) ps[p].transporter_hold = -2; @@ -1727,8 +1727,8 @@ void movetransports_r(void) } else if (isRRRA() && k == 2) { - ps[p].oposx = ps[p].posx += Owner->s->x - spr->x; - ps[p].oposy = ps[p].posy += Owner->s->y - spr->y; + ps[p].oposx = ps[p].pos.x += Owner->s->x - spr->x; + ps[p].oposy = ps[p].pos.y += Owner->s->y - spr->y; if (Owner->GetOwner() != Owner) ps[p].transporter_hold = -2; @@ -1758,31 +1758,31 @@ void movetransports_r(void) { warpspriteto = 0; - if (ll && sectlotag == ST_2_UNDERWATER && spr2->z < (sector[sect].ceilingz + ll)) + if (ll && sectlotag == ST_2_UNDERWATER && spr2->z < (sectp->ceilingz + ll)) warpspriteto = 1; - if (ll && sectlotag == ST_1_ABOVE_WATER && spr2->z > (sector[sect].floorz - ll)) + if (ll && sectlotag == ST_1_ABOVE_WATER && spr2->z > (sectp->floorz - ll)) if (!isRRRA() || (spr2->picnum != CHEERBOAT && spr2->picnum != HULKBOAT && spr2->picnum != MINIONBOAT)) warpspriteto = 1; if (isRRRA()) { - if (ll && sectlotag == 161 && spr2->z < (sector[sect].ceilingz + ll) && warpdir == 1) + if (ll && sectlotag == 161 && spr2->z < (sectp->ceilingz + ll) && warpdir == 1) { warpspriteto = 1; - ll2 = ll - abs(spr2->z - sector[sect].ceilingz); + ll2 = ll - abs(spr2->z - sectp->ceilingz); } - else if (sectlotag == 161 && spr2->z < (sector[sect].ceilingz + 1000) && warpdir == 1) + else if (sectlotag == 161 && spr2->z < (sectp->ceilingz + 1000) && warpdir == 1) { warpspriteto = 1; ll2 = 1; } - if (ll && sectlotag == 160 && spr2->z > (sector[sect].floorz - ll) && warpdir == 2) + if (ll && sectlotag == 160 && spr2->z > (sectp->floorz - ll) && warpdir == 2) { warpspriteto = 1; - ll2 = ll - abs(sector[sect].floorz - spr2->z); + ll2 = ll - abs(sectp->floorz - spr2->z); } - else if (sectlotag == 160 && spr2->z > (sector[sect].floorz - 1000) && warpdir == 2) + else if (sectlotag == 160 && spr2->z > (sectp->floorz - 1000) && warpdir == 2) { warpspriteto = 1; ll2 = 1; @@ -1839,11 +1839,11 @@ void movetransports_r(void) case ST_0_NO_EFFECT: if (onfloorz) { - if (checkcursectnums(sect) == -1 && checkcursectnums(Owner->s->sectnum) == -1) + if (checkcursectnums(spr->sectnum) == -1 && checkcursectnums(Owner->s->sectnum) == -1) { spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z -= spr->z - sector[Owner->s->sectnum].floorz; + spr2->z -= spr->z - Owner->getSector()->floorz; spr2->ang = Owner->s->ang; spr2->backupang(); @@ -1877,7 +1877,7 @@ void movetransports_r(void) case ST_1_ABOVE_WATER: spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z = sector[Owner->s->sectnum].ceilingz + ll; + spr2->z = Owner->getSector()->ceilingz + ll; spr2->backupz(); @@ -1887,7 +1887,7 @@ void movetransports_r(void) case ST_2_UNDERWATER: spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z = sector[Owner->s->sectnum].floorz - ll; + spr2->z = Owner->getSector()->floorz - ll; spr2->backupz(); @@ -1899,7 +1899,7 @@ void movetransports_r(void) if (!isRRRA()) break; spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z = sector[Owner->s->sectnum].ceilingz + ll2; + spr2->z = Owner->getSector()->ceilingz + ll2; spr2->backupz(); @@ -1913,7 +1913,7 @@ void movetransports_r(void) if (!isRRRA()) break; spr2->x += (Owner->s->x - spr->x); spr2->y += (Owner->s->y - spr->y); - spr2->z = sector[Owner->s->sectnum].floorz - ll2; + spr2->z = Owner->getSector()->floorz - ll2; spr2->backupz(); @@ -2089,7 +2089,7 @@ static void rrra_specialstats() s->extra = 1; } movesprite_ex(act, 0, 0, -300, CLIPMASK0, coll); - if (sector[s->sectnum].ceilingz + (4 << 8) > s->z) + if (s->sector()->ceilingz + (4 << 8) > s->z) { s->picnum = 0; s->extra = 100; @@ -2097,7 +2097,7 @@ static void rrra_specialstats() } else if (s->extra == 200) { - setsprite(act, s->x, s->y, sector[s->sectnum].floorz - 10); + setsprite(act, s->x, s->y, s->sector()->floorz - 10); s->extra = 1; s->picnum = PIG + 11; spawn(act, TRANSPORTERSTAR); @@ -2326,8 +2326,8 @@ void rr_specialstats() if (s->hitag == 100) { s->z += (4 << 8); - if (s->z >= sector[s->sectnum].floorz + 15168) - s->z = sector[s->sectnum].floorz + 15168; + if (s->z >= s->sector()->floorz + 15168) + s->z = s->sector()->floorz + 15168; } if (s->picnum == LUMBERBLADE) @@ -2336,7 +2336,7 @@ void rr_specialstats() if (s->extra == 192) { s->hitag = 0; - s->z = sector[s->sectnum].floorz - 15168; + s->z = s->sector()->floorz - 15168; s->extra = 0; s->picnum = RRTILE3410; DukeStatIterator it2(STAT_DEFAULT); @@ -2482,9 +2482,9 @@ void rr_specialstats() if (act2->s->picnum == RRTILE297) { ps[p].angle.ang = buildang(act2->s->ang); - ps[p].bobposx = ps[p].oposx = ps[p].posx = act2->s->x; - ps[p].bobposy = ps[p].oposy = ps[p].posy = act2->s->y; - ps[p].oposz = ps[p].posz = act2->s->z - (36 << 8); + ps[p].bobposx = ps[p].oposx = ps[p].pos.x = act2->s->x; + ps[p].bobposy = ps[p].oposy = ps[p].pos.y = act2->s->y; + ps[p].oposz = ps[p].pos.z = act2->s->z - (36 << 8); auto pact = ps[p].GetActor(); changeactorsect(pact, act2->s->sectnum); ps[p].cursectnum = pact->s->sectnum; @@ -2507,7 +2507,7 @@ static void heavyhbomb(DDukeActor *actor) { auto s = actor->s; auto t = &actor->temp_data[0]; - int sect = s->sectnum; + auto sectp = s->sector(); int x, l; auto Owner = actor->GetOwner(); @@ -2543,9 +2543,9 @@ static void heavyhbomb(DDukeActor *actor) makeitfall(actor); - if (sector[sect].lotag != 1 && (!isRRRA() || sector[sect].lotag != 160) && s->z >= actor->floorz - (FOURSLEIGHT) && s->yvel < 3) + if (sectp->lotag != 1 && (!isRRRA() || sectp->lotag != 160) && s->z >= actor->floorz - (FOURSLEIGHT) && s->yvel < 3) { - if (s->yvel > 0 || (s->yvel == 0 && actor->floorz == sector[sect].floorz)) + if (s->yvel > 0 || (s->yvel == 0 && actor->floorz == sectp->floorz)) { if (s->picnum != CHEERBOMB) S_PlayActorSound(PIPEBOMB_BOUNCE, actor); @@ -2558,11 +2558,11 @@ static void heavyhbomb(DDukeActor *actor) } } s->zvel = -((4 - s->yvel) << 8); - if (sector[s->sectnum].lotag == 2) + if (s->sector()->lotag == 2) s->zvel >>= 2; s->yvel++; } - if (s->picnum != CHEERBOMB && s->z < actor->ceilingz + (16 << 8) && sector[sect].lotag != 2) + if (s->picnum != CHEERBOMB && s->z < actor->ceilingz + (16 << 8) && sectp->lotag != 2) { s->z = actor->ceilingz + (16 << 8); s->zvel = 0; @@ -2574,7 +2574,7 @@ static void heavyhbomb(DDukeActor *actor) MulScale(s->xvel, bsin(s->ang), 14), s->zvel, CLIPMASK0, coll); - if (sector[s->sectnum].lotag == 1 && s->zvel == 0) + if (s->sector()->lotag == 1 && s->zvel == 0) { s->z += (32 << 8); if (t[5] == 0) @@ -2612,7 +2612,7 @@ static void heavyhbomb(DDukeActor *actor) if (s->xvel > 0) { s->xvel -= 5; - if (sector[sect].lotag == 2) + if (sectp->lotag == 2) s->xvel -= 10; if (s->xvel < 0) @@ -2660,7 +2660,7 @@ DETONATEB: case CHEERBOMB: m = gs.morterblastradius; break; } - if (sector[s->sectnum].lotag != 800) + if (s->sector()->lotag != 800) { fi.hitradius(actor, m, x >> 2, x >> 1, x - (x >> 2), x); spawn(actor, EXPLOSION2); @@ -2691,7 +2691,7 @@ DETONATEB: } } else if (s->picnum == HEAVYHBOMB && x < 788 && t[0] > 7 && s->xvel == 0) - if (cansee(s->x, s->y, s->z - (8 << 8), s->sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum)) + if (cansee(s->x, s->y, s->z - (8 << 8), s->sectnum, ps[p].pos.x, ps[p].pos.y, ps[p].pos.z, ps[p].cursectnum)) if (ps[p].ammo_amount[DYNAMITE_WEAPON] < gs.max_ammo_amount[DYNAMITE_WEAPON]) if (s->pal == 0) { @@ -2728,7 +2728,7 @@ DETONATEB: { t[2] = gs.respawnitemtime; spawn(actor, RESPAWNMARKERRED); - s->cstat = (short)32768; + s->cstat = 32768; } } @@ -2745,7 +2745,6 @@ static int henstand(DDukeActor *actor) { auto s = actor->s; auto t = &actor->temp_data[0]; - int sect = s->sectnum; if (s->picnum == HENSTAND || s->picnum == HENSTAND + 1) { @@ -2757,7 +2756,7 @@ static int henstand(DDukeActor *actor) return 1; } } - if (sector[s->sectnum].lotag == 900) + if (s->sector()->lotag == 900) s->xvel = 0; if (s->xvel) { @@ -2815,7 +2814,7 @@ static int henstand(DDukeActor *actor) return 2;//deletesprite(actor); still needs to run a script but should not do on a deleted object } } - else if (sector[s->sectnum].lotag == 900) + else if (s->sector()->lotag == 900) { if (s->picnum == BOWLINGBALL) ballreturn(actor); @@ -2851,14 +2850,14 @@ void moveactors_r(void) { auto s = act->s; bool deleteafterexecute = false; // taking a cue here from RedNukem to not run scripts on deleted sprites. - auto sect = s->sectnum; - if( s->xrepeat == 0 || sect < 0 || sect >= MAXSECTORS) + if( s->xrepeat == 0 || s->sectnum < 0 || s->sectnum >= MAXSECTORS) { deletesprite(act); continue; } + auto sectp = s->sector(); auto t = &act->temp_data[0]; switch(s->picnum) @@ -2879,13 +2878,13 @@ void moveactors_r(void) deletesprite(act); continue; } - if (sector[sect].lotag == 903) + if (sectp->lotag == 903) makeitfall(act); movesprite_ex(act, MulScale(s->xvel, bcos(s->ang), 14), MulScale(s->xvel, bsin(s->ang), 14), s->zvel,CLIPMASK0, coll); - switch (sector[sect].lotag) + switch (sectp->lotag) { case 901: s->picnum = RRTILE3191; @@ -2894,7 +2893,7 @@ void moveactors_r(void) s->picnum = RRTILE3192; break; case 903: - if (s->z >= sector[sect].floorz - (8<<8)) + if (s->z >= sectp->floorz - (8<<8)) { deletesprite(act); continue; @@ -2931,15 +2930,15 @@ void moveactors_r(void) deletesprite(act); continue; } - if (sector[sect].lotag == 903) + if (sectp->lotag == 903) { - if (s->z >= sector[sect].floorz - (4<<8)) + if (s->z >= sectp->floorz - (4<<8)) { deletesprite(act); continue; } } - else if (sector[sect].lotag == 904) + else if (sectp->lotag == 904) { deletesprite(act); continue; @@ -2957,12 +2956,12 @@ void moveactors_r(void) MulScale(s->xvel, bcos(s->ang), 14), MulScale(s->xvel, bsin(s->ang), 14), s->zvel,CLIPMASK0, coll); - if (s->z >= sector[sect].floorz - (8<<8)) + if (s->z >= sectp->floorz - (8<<8)) { - if (sector[sect].lotag == 1) + if (sectp->lotag == 1) { auto j = spawn(act, WATERSPLASH2); - j->s->z = sector[j->s->sectnum].floorz; + j->s->z = j->getSector()->floorz; } deletesprite(act); continue; @@ -2980,7 +2979,7 @@ void moveactors_r(void) deletesprite(act); continue; } - if (sector[s->sectnum].lotag == 900) + if (s->sector()->lotag == 900) { S_StopSound(356, nullptr); } @@ -3036,7 +3035,7 @@ void moveactors_r(void) if (!isRRRA()) break; makeitfall(act); getglobalz(act); - if (sector[sect].lotag == 1) + if (sectp->lotag == 1) { setsprite(act,s->x,s->y,act->floorz+(16<<8)); } @@ -3049,7 +3048,7 @@ void moveactors_r(void) break; case TRIPBOMBSPRITE: - if (!isRRRA() || (sector[sect].lotag != 1 && sector[sect].lotag != 160)) + if (!isRRRA() || (sectp->lotag != 1 && sectp->lotag != 160)) if (s->xvel) { movesprite_ex(act, @@ -3087,7 +3086,7 @@ void moveactors_r(void) { if( actor_tog == 1) { - s->cstat = (short)32768; + s->cstat = 32768; continue; } else if(actor_tog == 2) s->cstat = 257; @@ -3110,7 +3109,7 @@ void moveactors_r(void) void moveexplosions_r(void) // STATNUM 5 { - int sect, p; + int p; int x, * t; @@ -3119,9 +3118,9 @@ void moveexplosions_r(void) // STATNUM 5 { auto s = act->s; t = &act->temp_data[0]; - sect = s->sectnum; + auto sectp = s->sector(); - if (sect < 0 || s->xrepeat == 0) + if (s->sectnum < 0 || s->xrepeat == 0) { deletesprite(act); continue; @@ -3130,8 +3129,8 @@ void moveexplosions_r(void) // STATNUM 5 switch (s->picnum) { case SHOTGUNSPRITE: - if (sector[s->sectnum].lotag == 800) - if (s->z >= sector[s->sectnum].floorz - (8 << 8)) + if (s->sector()->lotag == 800) + if (s->z >= s->sector()->floorz - (8 << 8)) { deletesprite(act); continue; @@ -3169,7 +3168,7 @@ void moveexplosions_r(void) // STATNUM 5 t[0]++; if (t[0] == 1) { - if (sector[sect].floorpicnum != 3073) + if (sectp->floorpicnum != 3073) { deletesprite(act); continue; @@ -3220,7 +3219,7 @@ void moveexplosions_r(void) // STATNUM 5 continue; case FEATHER + 1: // feather act->floorz = s->z = getflorzofslope(s->sectnum, s->x, s->y); - if (sector[s->sectnum].lotag == 800) + if (s->sector()->lotag == 800) { deletesprite(act); continue; @@ -3229,8 +3228,8 @@ void moveexplosions_r(void) // STATNUM 5 case FEATHER: if (!money(act, BLOODPOOL)) continue; - if (sector[s->sectnum].lotag == 800) - if (s->z >= sector[s->sectnum].floorz - (8 << 8)) + if (s->sector()->lotag == 800) + if (s->z >= s->sector()->floorz - (8 << 8)) { deletesprite(act); continue; @@ -3283,8 +3282,8 @@ void moveexplosions_r(void) // STATNUM 5 if (!jibs(act, JIBS6, false, true, true, s->picnum == DUKELEG || s->picnum == DUKETORSO || s->picnum == DUKEGUN, isRRRA() && (s->picnum == RRTILE2465 || s->picnum == RRTILE2560))) continue; - if (sector[s->sectnum].lotag == 800) - if (s->z >= sector[s->sectnum].floorz - (8 << 8)) + if (s->sector()->lotag == 800) + if (s->z >= s->sector()->floorz - (8 << 8)) { deletesprite(act); continue; @@ -3295,8 +3294,8 @@ void moveexplosions_r(void) // STATNUM 5 case BLOODPOOL: if (!bloodpool(act, false, TIRE)) continue; - if (sector[s->sectnum].lotag == 800) - if (s->z >= sector[s->sectnum].floorz - (8 << 8)) + if (s->sector()->lotag == 800) + if (s->z >= s->sector()->floorz - (8 << 8)) { deletesprite(act); } @@ -3346,7 +3345,7 @@ void handle_se06_r(DDukeActor *actor) auto s = actor->s; auto t = &actor->temp_data[0]; - auto sc = §or[s->sectnum]; + auto sc = actor->getSector(); int st = s->lotag; int sh = s->hitag; @@ -3369,11 +3368,11 @@ void handle_se06_r(DDukeActor *actor) { hulkspawn--; auto ns = spawn(actor, HULK); - ns->s->z = sector[ns->s->sectnum].ceilingz; + ns->s->z = ns->getSector()->ceilingz; ns->s->pal = 33; if (!hulkspawn) { - ns = EGS(s->sectnum, s->x, s->y, sector[s->sectnum].ceilingz + 119428, 3677, -8, 16, 16, 0, 0, 0, actor, 5); + ns = EGS(s->sectnum, s->x, s->y, s->sector()->ceilingz + 119428, 3677, -8, 16, 16, 0, 0, 0, actor, 5); ns->s->cstat = 514; ns->s->pal = 7; ns->s->xrepeat = 80; @@ -3381,7 +3380,7 @@ void handle_se06_r(DDukeActor *actor) ns = spawn(actor, 296); ns->s->cstat = 0; ns->s->cstat |= 32768; - ns->s->z = sector[s->sectnum].floorz - 6144; + ns->s->z = s->sector()->floorz - 6144; deletesprite(actor); return; } @@ -3420,7 +3419,7 @@ void handle_se06_r(DDukeActor *actor) } else pn = UFO1_RRRA; auto ns = spawn(actor, pn); - ns->s->z = sector[ns->s->sectnum].ceilingz; + ns->s->z = ns->getSector()->ceilingz; } } } @@ -3460,7 +3459,7 @@ void moveeffectors_r(void) //STATNUM 3 DukeStatIterator it(STAT_EFFECTOR); while (auto act = it.Next()) { - auto sc = §or[act->s->sectnum]; + auto sc = act->getSector(); int st = act->s->lotag; int sh = act->s->hitag; @@ -3574,8 +3573,8 @@ void moveeffectors_r(void) //STATNUM 3 case SE_24_CONVEYOR: case SE_34: { - static int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, -1 }; - static int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, -1 }; + static const int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, -1 }; + static const int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, -1 }; handle_se24(act, list1, list2, st != 156, BULLETHOLE, -1, CRANE, 1); break; } @@ -3646,10 +3645,10 @@ void moveeffectors_r(void) //STATNUM 3 { auto s = act->s; if (act->s->lotag != SE_29_WAVES) continue; - auto sc = §or[act->s->sectnum]; + auto sc = act->getSector(); if (sc->wallnum != 4) continue; auto wal = &wall[sc->wallptr + 2]; - alignflorslope(act->s->sectnum, wal->x, wal->y, sector[wal->nextsector].floorz); + alignflorslope(act->s->sectnum, wal->x, wal->y, wal->nextSector()->floorz); } } @@ -3680,7 +3679,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) auto spr = actor->s; auto t = actor->temp_data; int l; - short goalang, angdif; + int goalang, angdif; int daxvel; int a = spr->hitag; @@ -3693,7 +3692,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) { if (ps[pnum].newOwner != nullptr) goalang = getangle(ps[pnum].oposx - spr->x, ps[pnum].oposy - spr->y); - else goalang = getangle(ps[pnum].posx - spr->x, ps[pnum].posy - spr->y); + else goalang = getangle(ps[pnum].pos.x - spr->x, ps[pnum].pos.y - spr->y); angdif = getincangle(spr->ang, goalang) >> 2; if (angdif > -8 && angdif < 0) angdif = 0; spr->ang += angdif; @@ -3706,7 +3705,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) { if (ps[pnum].newOwner != nullptr) goalang = getangle(ps[pnum].oposx - spr->x, ps[pnum].oposy - spr->y); - else goalang = getangle(ps[pnum].posx - spr->x, ps[pnum].posy - spr->y); + else goalang = getangle(ps[pnum].pos.x - spr->x, ps[pnum].pos.y - spr->y); angdif = Sgn(getincangle(spr->ang, goalang)) << 5; if (angdif > -32 && angdif < 0) { @@ -3722,7 +3721,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) { if (ps[pnum].newOwner != nullptr) goalang = (getangle(ps[pnum].oposx - spr->x, ps[pnum].oposy - spr->y) + 1024) & 2047; - else goalang = (getangle(ps[pnum].posx - spr->x, ps[pnum].posy - spr->y) + 1024) & 2047; + else goalang = (getangle(ps[pnum].pos.x - spr->x, ps[pnum].pos.y - spr->y) + 1024) & 2047; angdif = Sgn(getincangle(spr->ang, goalang)) << 5; if (angdif > -32 && angdif < 0) { @@ -3788,8 +3787,8 @@ void move_r(DDukeActor *actor, int pnum, int xvel) { int newx, newy; - newx = ps[pnum].posx + (ps[pnum].posxv / 768); - newy = ps[pnum].posy + (ps[pnum].posyv / 768); + newx = ps[pnum].pos.x + (ps[pnum].posxv / 768); + newy = ps[pnum].pos.y + (ps[pnum].posyv / 768); goalang = getangle(newx - spr->x, newy - spr->y); angdif = getincangle(spr->ang, goalang) >> 2; if (angdif > -8 && angdif < 0) angdif = 0; @@ -3805,7 +3804,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) } if (badguy(actor) && spr->extra <= 0) { - if (sector[spr->sectnum].ceilingstat & 1) + if (spr->sector()->ceilingstat & 1) { if (shadedsector[spr->sectnum] == 1) { @@ -3813,12 +3812,12 @@ void move_r(DDukeActor *actor, int pnum, int xvel) } else { - spr->shade += (sector[spr->sectnum].ceilingshade - spr->shade) >> 1; + spr->shade += (spr->sector()->ceilingshade - spr->shade) >> 1; } } else { - spr->shade += (sector[spr->sectnum].floorshade - spr->shade) >> 1; + spr->shade += (spr->sector()->floorshade - spr->shade) >> 1; } } return; @@ -3894,7 +3893,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) { daxvel = -(1024 - xvel); - angdif = getangle(ps[pnum].posx - spr->x, ps[pnum].posy - spr->y); + angdif = getangle(ps[pnum].pos.x - spr->x, ps[pnum].pos.y - spr->y); if (xvel < 512) { @@ -3925,7 +3924,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) } if (isRRRA()) { - if (sector[spr->sectnum].lotag != 1) + if (spr->sector()->lotag != 1) { switch (spr->picnum) { @@ -3936,7 +3935,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) break; } } - else if (sector[spr->sectnum].lotag == 1) + else if (spr->sector()->lotag == 1) { switch (spr->picnum) { @@ -3957,7 +3956,7 @@ void move_r(DDukeActor *actor, int pnum, int xvel) if (a) { - if (sector[spr->sectnum].ceilingstat & 1) + if (spr->sector()->ceilingstat & 1) { if (shadedsector[spr->sectnum] == 1) { @@ -3965,12 +3964,12 @@ void move_r(DDukeActor *actor, int pnum, int xvel) } else { - spr->shade += (sector[spr->sectnum].ceilingshade - spr->shade) >> 1; + spr->shade += (spr->sector()->ceilingshade - spr->shade) >> 1; } } - else spr->shade += (sector[spr->sectnum].floorshade - spr->shade) >> 1; + else spr->shade += (spr->sector()->floorshade - spr->shade) >> 1; - if (sector[spr->sectnum].floorpicnum == MIRROR) + if (spr->sector()->floorpicnum == MIRROR) deletesprite(actor); } } @@ -4010,7 +4009,7 @@ static int fallspecial(DDukeActor *actor, int playernum) int sphit = 0; if (isRRRA()) { - if (sector[s->sectnum].lotag == 801) + if (s->sector()->lotag == 801) { if (s->picnum == ROCK) { @@ -4020,7 +4019,7 @@ static int fallspecial(DDukeActor *actor, int playernum) } return 0; } - else if (sector[s->sectnum].lotag == 802) + else if (s->sector()->lotag == 802) { if (s->picnum != APLAYER && badguy(actor) && s->z == actor->floorz - FOURSLEIGHT) { @@ -4030,14 +4029,14 @@ static int fallspecial(DDukeActor *actor, int playernum) } return 0; } - else if (sector[s->sectnum].lotag == 803) + else if (s->sector()->lotag == 803) { if (s->picnum == ROCK2) addspritetodelete(); return 0; } } - if (sector[s->sectnum].lotag == 800) + if (s->sector()->lotag == 800) { if (s->picnum == 40) { @@ -4061,7 +4060,7 @@ static int fallspecial(DDukeActor *actor, int playernum) actor->picnum = SHOTSPARK1; actor->extra = 1; } - else if (isRRRA() && (sector[s->sectnum].floorpicnum == RRTILE7820 || sector[s->sectnum].floorpicnum == RRTILE7768)) + else if (isRRRA() && (s->sector()->floorpicnum == RRTILE7820 || s->sector()->floorpicnum == RRTILE7768)) { if (s->picnum != MINION && s->pal != 19) { @@ -4133,10 +4132,14 @@ void destroyit(DDukeActor *actor) if (lotag == a2->s->lotag) { sectnum = spr->s->sectnum; - wallstart = sector[sectnum].wallptr; - wallend = wallstart + sector[sectnum].wallnum; - wallstart2 = sector[it_sect].wallptr; - wallend2 = wallstart2 + sector[it_sect].wallnum; + + auto destsect = spr->getSector(); + auto srcsect = §or[it_sect]; + + wallstart = destsect->wallptr; + wallend = wallstart + destsect->wallnum; + wallstart2 = srcsect->wallptr; + wallend2 = wallstart2 + srcsect->wallnum; for (wi = wallstart, wj = wallstart2; wi < wallend; wi++, wj++) { wall[wi].picnum = wall[wj].picnum; @@ -4152,27 +4155,27 @@ void destroyit(DDukeActor *actor) wall[wall[wi].nextwall].cstat = 0; } } - sector[sectnum].floorz = sector[it_sect].floorz; - sector[sectnum].ceilingz = sector[it_sect].ceilingz; - sector[sectnum].ceilingstat = sector[it_sect].ceilingstat; - sector[sectnum].floorstat = sector[it_sect].floorstat; - sector[sectnum].ceilingpicnum = sector[it_sect].ceilingpicnum; - sector[sectnum].ceilingheinum = sector[it_sect].ceilingheinum; - sector[sectnum].ceilingshade = sector[it_sect].ceilingshade; - sector[sectnum].ceilingpal = sector[it_sect].ceilingpal; - sector[sectnum].ceilingxpan_ = sector[it_sect].ceilingxpan_; - sector[sectnum].ceilingypan_ = sector[it_sect].ceilingypan_; - sector[sectnum].floorpicnum = sector[it_sect].floorpicnum; - sector[sectnum].floorheinum = sector[it_sect].floorheinum; - sector[sectnum].floorshade = sector[it_sect].floorshade; - sector[sectnum].floorpal = sector[it_sect].floorpal; - sector[sectnum].floorxpan_ = sector[it_sect].floorxpan_; - sector[sectnum].floorypan_ = sector[it_sect].floorypan_; - sector[sectnum].visibility = sector[it_sect].visibility; + destsect->floorz = srcsect->floorz; + destsect->ceilingz = srcsect->ceilingz; + destsect->ceilingstat = srcsect->ceilingstat; + destsect->floorstat = srcsect->floorstat; + destsect->ceilingpicnum = srcsect->ceilingpicnum; + destsect->ceilingheinum = srcsect->ceilingheinum; + destsect->ceilingshade = srcsect->ceilingshade; + destsect->ceilingpal = srcsect->ceilingpal; + destsect->ceilingxpan_ = srcsect->ceilingxpan_; + destsect->ceilingypan_ = srcsect->ceilingypan_; + destsect->floorpicnum = srcsect->floorpicnum; + destsect->floorheinum = srcsect->floorheinum; + destsect->floorshade = srcsect->floorshade; + destsect->floorpal = srcsect->floorpal; + destsect->floorxpan_ = srcsect->floorxpan_; + destsect->floorypan_ = srcsect->floorypan_; + destsect->visibility = srcsect->visibility; sectorextra[sectnum] = sectorextra[it_sect]; // TRANSITIONAL: at least rename this. - sector[sectnum].lotag = sector[it_sect].lotag; - sector[sectnum].hitag = sector[it_sect].hitag; - sector[sectnum].extra = sector[it_sect].extra; + destsect->lotag = srcsect->lotag; + destsect->hitag = srcsect->hitag; + destsect->extra = srcsect->extra; } } it1.Reset(actor->s->sectnum); diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index 1797ae32f..93554f006 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -47,7 +47,6 @@ BEGIN_DUKE_NS void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio) { int i, j, k, p; - short sect; int l, t1, t3, t4; spritetype* s; tspritetype* t; @@ -134,10 +133,10 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int continue; } - if (sector[t->sectnum].ceilingstat & 1) - l = sector[t->sectnum].ceilingshade; + if (t->sector()->ceilingstat & 1) + l = t->sector()->ceilingshade; else - l = sector[t->sectnum].floorshade; + l = t->sector()->floorshade; if (l < -127) l = -127; if (l > 128) l = 127; @@ -176,9 +175,9 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int if (t->statnum == 99) continue; if (s->statnum != STAT_ACTOR && s->picnum == APLAYER && ps[s->yvel].newOwner == nullptr && h->GetOwner()) { - t->x -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].posx - ps[s->yvel].oposx, 16); - t->y -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].posy - ps[s->yvel].oposy, 16); - t->z = interpolatedvalue(ps[s->yvel].oposz, ps[s->yvel].posz, smoothratio); + t->x -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].pos.x - ps[s->yvel].oposx, 16); + t->y -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].pos.y - ps[s->yvel].oposy, 16); + t->z = interpolatedvalue(ps[s->yvel].oposz, ps[s->yvel].pos.z, smoothratio); t->z += PHEIGHT_DUKE; } else if (s->picnum != CRANEPOLE) @@ -186,7 +185,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int t->pos = s->interpolatedvec3(smoothratio); } - sect = s->sectnum; + auto sectp = s->sector(); t1 = h->temp_data[1]; t3 = h->temp_data[3]; t4 = h->temp_data[4]; @@ -216,13 +215,11 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int case FORCESPHERE: if (t->statnum == STAT_MISC && Owner) { - short sqa, sqb; - - sqa = + int sqa = getangle( - Owner->x - ps[screenpeek].posx, - Owner->y - ps[screenpeek].posy); - sqb = + Owner->x - ps[screenpeek].pos.x, + Owner->y - ps[screenpeek].pos.y); + int sqb = getangle( Owner->x - t->x, Owner->y - t->y); @@ -369,7 +366,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int } if (h->GetOwner()) - newtspr->z = ps[p].posz - (12 << 8); + newtspr->z = ps[p].pos.z - (12 << 8); else newtspr->z = s->z - (51 << 8); if (ps[p].curr_weapon == HANDBOMB_WEAPON) { @@ -403,7 +400,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int else t->cstat &= ~4; } - if (sector[t->sectnum].lotag == 2) k += 1795 - 1405; + if (t->sector()->lotag == 2) k += 1795 - 1405; else if ((h->floorz - s->z) > (64 << 8)) k += 60; t->picnum += k; @@ -412,11 +409,11 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int goto PALONLY; } - if (ps[p].on_crane == nullptr && (sector[s->sectnum].lotag & 0x7ff) != 1) + if (ps[p].on_crane == nullptr && (s->sector()->lotag & 0x7ff) != 1) { l = s->z - ps[p].GetActor()->floorz + (3 << 8); if (l > 1024 && s->yrepeat > 32 && s->extra > 0) - s->yoffset = (signed char)(l / (s->yrepeat << 2)); + s->yoffset = (int8_t)(l / (s->yrepeat << 2)); else s->yoffset = 0; } @@ -438,8 +435,8 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int PALONLY: - if (sector[sect].floorpal) - copyfloorpal(t, §or[sect]); + if (sectp->floorpal) + copyfloorpal(t, sectp); if (!h->GetOwner()) continue; @@ -484,20 +481,20 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int else t->picnum += h->temp_data[0]; t->shade -= 6; - if (sector[sect].floorpal) - copyfloorpal(t, §or[sect]); + if (sectp->floorpal) + copyfloorpal(t, sectp); break; case WATERBUBBLE: - if (sector[t->sectnum].floorpicnum == FLOORSLIME) + if (t->sector()->floorpicnum == FLOORSLIME) { t->pal = 7; break; } default: - if (sector[sect].floorpal) - copyfloorpal(t, §or[sect]); + if (sectp->floorpal) + copyfloorpal(t, sectp); break; } @@ -584,13 +581,13 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int { int daz; - if ((sector[sect].lotag & 0xff) > 2 || s->statnum == 4 || s->statnum == 5 || s->picnum == DRONE || s->picnum == COMMANDER) - daz = sector[sect].floorz; + if ((sectp->lotag & 0xff) > 2 || s->statnum == 4 || s->statnum == 5 || s->picnum == DRONE || s->picnum == COMMANDER) + daz = sectp->floorz; else daz = h->floorz; - if ((s->z - daz) < (8 << 8) && ps[screenpeek].posz < daz) + if ((s->z - daz) < (8 << 8) && ps[screenpeek].pos.z < daz) { auto shadowspr = &tsprite[spritesortcnt]; *shadowspr = *t; @@ -616,7 +613,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int else { // Alter the shadow's position so that it appears behind the sprite itself. - int look = getangle(shadowspr->x - ps[screenpeek].posx, shadowspr->y - ps[screenpeek].posy); + int look = getangle(shadowspr->x - ps[screenpeek].pos.x, shadowspr->y - ps[screenpeek].pos.y); shadowspr->x += bcos(look, -9); shadowspr->y += bsin(look, -9); } @@ -636,7 +633,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int { case LASERLINE: if (!Owner) break; - if (sector[t->sectnum].lotag == 2) t->pal = 8; + if (t->sector()->lotag == 2) t->pal = 8; t->z = Owner->z - (3 << 8); if (gs.lasermode == 2 && ps[screenpeek].heat_on == 0) t->yrepeat = 0; @@ -665,7 +662,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int case BURNING2: if (!Owner) break; if (Owner->picnum != TREE1 && Owner->picnum != TREE2) - t->z = sector[t->sectnum].floorz; + t->z = t->sector()->floorz; t->shade = -127; break; case COOLEXPLOSION1: @@ -748,7 +745,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int } h->dispicnum = t->picnum; - if (sector[t->sectnum].floorpicnum == MIRROR) + if (t->sector()->floorpicnum == MIRROR) t->xrepeat = t->yrepeat = 0; } } diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index dd2d2cb44..d167f3cfa 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -40,7 +40,6 @@ BEGIN_DUKE_NS void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio) { int i, j, k, p; - short sect; int l, t1, t3, t4; spritetype* s; tspritetype* t; @@ -119,7 +118,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int } } - if (sector[t->sectnum].ceilingstat & 1) + if (t->sector()->ceilingstat & 1) { if (badguy(s)) l = s->shade; @@ -127,7 +126,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int l = s->shade; } else - l = sector[t->sectnum].floorshade; + l = t->sector()->floorshade; if (l < -127) l = -127; if (l > 128) l = 127; @@ -162,9 +161,9 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int if (t->statnum == 99) continue; if (s->statnum != STAT_ACTOR && s->picnum == APLAYER && ps[s->yvel].newOwner == nullptr && h->GetOwner()) { - t->x -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].posx - ps[s->yvel].oposx, 16); - t->y -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].posy - ps[s->yvel].oposy, 16); - t->z = interpolatedvalue(ps[s->yvel].oposz, ps[s->yvel].posz, smoothratio); + t->x -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].pos.x - ps[s->yvel].oposx, 16); + t->y -= MulScale(MaxSmoothRatio - smoothratio, ps[s->yvel].pos.y - ps[s->yvel].oposy, 16); + t->z = interpolatedvalue(ps[s->yvel].oposz, ps[s->yvel].pos.z, smoothratio); t->z += PHEIGHT_RR; s->xrepeat = 24; s->yrepeat = 17; @@ -174,7 +173,8 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int t->pos = s->interpolatedvec3(smoothratio); } - sect = s->sectnum; + //sect = s->sectnum; + auto sectp = s->sector(); t1 = h->temp_data[1]; t3 = h->temp_data[3]; t4 = h->temp_data[4]; @@ -215,13 +215,11 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int case FORCESPHERE: if (t->statnum == STAT_MISC && Owner) { - short sqa, sqb; - - sqa = + int sqa = getangle( - Owner->x - ps[screenpeek].posx, - Owner->y - ps[screenpeek].posy); - sqb = + Owner->x - ps[screenpeek].pos.x, + Owner->y - ps[screenpeek].pos.y); + int sqb = getangle( Owner->x - t->x, Owner->y - t->y); @@ -414,7 +412,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int } if (h->GetOwner()) - newtspr->z = ps[p].posz - (12 << 8); + newtspr->z = ps[p].pos.z - (12 << 8); else newtspr->z = s->z - (51 << 8); if (ps[p].curr_weapon == HANDBOMB_WEAPON) { @@ -452,7 +450,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int else t->cstat &= ~4; } - if (sector[t->sectnum].lotag == 2) k += 1795 - 1405; + if (t->sector()->lotag == 2) k += 1795 - 1405; else if ((h->floorz - s->z) > (64 << 8)) k += 60; t->picnum += k; @@ -461,11 +459,11 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int goto PALONLY; } - if (ps[p].on_crane == nullptr && (sector[s->sectnum].lotag & 0x7ff) != 1) + if (ps[p].on_crane == nullptr && (s->sector()->lotag & 0x7ff) != 1) { l = s->z - ps[p].GetActor()->floorz + (3 << 8); if (l > 1024 && s->yrepeat > 32 && s->extra > 0) - s->yoffset = (signed char)(l / (s->yrepeat << 2)); + s->yoffset = (int8_t)(l / (s->yrepeat << 2)); else s->yoffset = 0; } @@ -487,8 +485,8 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int PALONLY: - if (sector[sect].floorpal) - copyfloorpal(t, §or[sect]); + if (sectp->floorpal) + copyfloorpal(t, sectp); if (!h->GetOwner()) continue; @@ -619,12 +617,12 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int t->picnum = s->yvel; else t->picnum += h->temp_data[0]; - if (sector[sect].floorpal) - copyfloorpal(t, §or[sect]); + if (sectp->floorpal) + copyfloorpal(t, sectp); break; case WATERBUBBLE: - if (sector[t->sectnum].floorpicnum == FLOORSLIME) + if (t->sector()->floorpicnum == FLOORSLIME) { t->pal = 7; break; @@ -632,8 +630,8 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int default: default_case: - if (sector[sect].floorpal) - copyfloorpal(t, §or[sect]); + if (sectp->floorpal) + copyfloorpal(t, sectp); break; } @@ -742,14 +740,14 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int { int daz; - if (isRRRA() && sector[sect].lotag == 160) continue; - if ((sector[sect].lotag & 0xff) > 2 || s->statnum == 4 || s->statnum == 5 || s->picnum == DRONE) - daz = sector[sect].floorz; + if (isRRRA() && sectp->lotag == 160) continue; + if ((sectp->lotag & 0xff) > 2 || s->statnum == 4 || s->statnum == 5 || s->picnum == DRONE) + daz = sectp->floorz; else daz = h->floorz; if ((s->z - daz) < (8 << 8)) - if (ps[screenpeek].posz < daz) + if (ps[screenpeek].pos.z < daz) { auto shadowspr = &tsprite[spritesortcnt]; *shadowspr = *t; @@ -775,7 +773,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int else { // Alter the shadow's position so that it appears behind the sprite itself. - int look = getangle(shadowspr->x - ps[screenpeek].posx, shadowspr->y - ps[screenpeek].posy); + int look = getangle(shadowspr->x - ps[screenpeek].pos.x, shadowspr->y - ps[screenpeek].pos.y); shadowspr->x += bcos(look, -9); shadowspr->y += bsin(look, -9); } @@ -825,7 +823,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int case FIRE: case BURNING: if (Owner && Owner->picnum != TREE1 && Owner->picnum != TREE2) - t->z = sector[t->sectnum].floorz; + t->z = t->sector()->floorz; t->shade = -127; break; case WALLLIGHT3: @@ -978,7 +976,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int } h->dispicnum = t->picnum; - if (sector[t->sectnum].floorpicnum == MIRROR) + if (t->sector()->floorpicnum == MIRROR) t->xrepeat = t->yrepeat = 0; } } diff --git a/source/games/duke/src/bowling.cpp b/source/games/duke/src/bowling.cpp index 81efcd4cd..ac00bd71b 100644 --- a/source/games/duke/src/bowling.cpp +++ b/source/games/duke/src/bowling.cpp @@ -57,7 +57,7 @@ void ballreturn(DDukeActor *ball) } } -short pinsectorresetdown(short sect) +void pinsectorresetdown(int sect) { int j = getanimationgoal(anim_ceilingz, sect); @@ -65,12 +65,10 @@ short pinsectorresetdown(short sect) { j = sector[sect].floorz; setanimation(sect, anim_ceilingz, sect, j, 64); - return 1; } - return 0; } -short pinsectorresetup(short sect) +int pinsectorresetup(int sect) { int j = getanimationgoal(anim_ceilingz, sect); @@ -83,15 +81,12 @@ short pinsectorresetup(short sect) return 0; } -short checkpins(short sect) +int checkpins(int sect) { - short i, pin; int x, y; - short pins[10]; - short tag; - - pin = 0; - for (i = 0; i < 10; i++) pins[i] = 0; + bool pins[10] = {}; + int tag = 0; + int pin = 0; DukeSectIterator it(sect); while (auto a2 = it.Next()) @@ -99,7 +94,7 @@ short checkpins(short sect) if (a2->s->picnum == BOWLINGPIN) { pin++; - pins[a2->s->lotag] = 1; + pins[a2->s->lotag] = true; } if (a2->s->picnum == BOWLINGPINSPOT) { @@ -112,9 +107,9 @@ short checkpins(short sect) tag += LANEPICS + 1; TileFiles.tileMakeWritable(tag); tileCopySection(LANEPICS + 1, 0, 0, 128, 64, tag, 0, 0); - for (i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { - if (pins[i] == 1) + if (pins[i]) { switch (i) { @@ -167,7 +162,7 @@ short checkpins(short sect) return pin; } -void resetpins(short sect) +void resetpins(int sect) { int i, tag; int x, y; @@ -256,16 +251,14 @@ void resetlanepics(void) { if (!isRR()) return; int x, y; - short i; - short tag, pic; - for (tag = 0; tag < 4; tag++) + for (int tag = 0; tag < 4; tag++) { - pic = tag + 1; + int pic = tag + 1; if (pic == 0) continue; pic += LANEPICS + 1; TileFiles.tileMakeWritable(pic); tileCopySection(LANEPICS + 1, 0, 0, 128, 64, pic, 0, 0); - for (i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { switch (i) { diff --git a/source/games/duke/src/ccmds.cpp b/source/games/duke/src/ccmds.cpp index f7d04da40..5727cab79 100644 --- a/source/games/duke/src/ccmds.cpp +++ b/source/games/duke/src/ccmds.cpp @@ -66,7 +66,7 @@ static int ccmd_spawn(CCmdFuncPtr parm) case 3: // cstat cstat = (unsigned short)atol(parm->parms[2]); set |= 2; case 2: // pal - pal = (unsigned char)atol(parm->parms[1]); set |= 1; + pal = (uint8_t)atol(parm->parms[1]); set |= 1; case 1: // tile number if (isdigit(parm->parms[0][0])) { picnum = (unsigned short)atol(parm->parms[0]); @@ -89,8 +89,8 @@ static int ccmd_spawn(CCmdFuncPtr parm) } auto spawned = spawn(ps[myconnectindex].GetActor(), picnum); - if (set & 1) spawned->s->pal = (char)pal; - if (set & 2) spawned->s->cstat = (short)cstat; + if (set & 1) spawned->s->pal = (uint8_t)pal; + if (set & 2) spawned->s->cstat = (uint16_t)cstat; if (set & 4) spawned->s->ang = ang; if (set & 8) { if (setsprite(spawned, x, y, z) < 0) @@ -107,9 +107,9 @@ void GameInterface::WarpToCoords(int x, int y, int z, int ang, int horz) { player_struct* p = &ps[myconnectindex]; - p->oposx = p->posx = x; - p->oposy = p->posy = y; - p->oposz = p->posz = z; + p->oposx = p->pos.x = x; + p->oposy = p->pos.y = y; + p->oposz = p->pos.z = z; if (ang != INT_MIN) { diff --git a/source/games/duke/src/d_menu.cpp b/source/games/duke/src/d_menu.cpp index ea3ea9a23..6b3b39168 100644 --- a/source/games/duke/src/d_menu.cpp +++ b/source/games/duke/src/d_menu.cpp @@ -99,8 +99,8 @@ bool GameInterface::StartGame(FNewGameStartup& gs) { int32_t skillsound = PISTOL_BODYHIT; - static const short sounds_d[] = { JIBBED_ACTOR6, BONUS_SPEECH1, DUKE_GETWEAPON2, JIBBED_ACTOR5, JIBBED_ACTOR5 }; - static const short sounds_r[] = { 427, 428, 196, 195, 197 }; + static const uint16_t sounds_d[] = { JIBBED_ACTOR6, BONUS_SPEECH1, DUKE_GETWEAPON2, JIBBED_ACTOR5, JIBBED_ACTOR5 }; + static const uint16_t sounds_r[] = { 427, 428, 196, 195, 197 }; if (gs.Skill >=0 && gs.Skill <= 5) skillsound = isRR()? sounds_r[gs.Skill] : sounds_d[gs.Skill]; if (menu_sounds && skillsound >= 0 && SoundEnabled() && !netgame) diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index 0a617c345..793e66e3b 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -56,20 +56,20 @@ void checkhitsprite_r(DDukeActor* i, DDukeActor* sn); void checksectors_d(int snum); void checksectors_r(int snum); -bool ceilingspace_d(int sectnum); -bool ceilingspace_r(int sectnum); -bool floorspace_d(int sectnum); -bool floorspace_r(int sectnum); +bool ceilingspace_d(sectortype*); +bool ceilingspace_r(sectortype*); +bool floorspace_d(sectortype*); +bool floorspace_r(sectortype*); void addweapon_d(struct player_struct* p, int weapon); void addweapon_r(struct player_struct* p, int weapon); void hitradius_d(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4); void hitradius_r(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4); -void lotsofmoney_d(DDukeActor* s, short n); -void lotsofmail_d(DDukeActor* s, short n); -void lotsofpaper_d(DDukeActor* s, short n); -void lotsoffeathers_r(DDukeActor* s, short n); -void guts_d(DDukeActor* s, short gtype, short n, short p); -void guts_r(DDukeActor* s, short gtype, short n, short p); +void lotsofmoney_d(DDukeActor* s, int n); +void lotsofmail_d(DDukeActor* s, int n); +void lotsofpaper_d(DDukeActor* s, int n); +void lotsoffeathers_r(DDukeActor* s, int n); +void guts_d(DDukeActor* s, int gtype, int n, int p); +void guts_r(DDukeActor* s, int gtype, int n, int p); DDukeActor* ifhitsectors_d(int sectnum); DDukeActor* ifhitsectors_r(int sectnum); int ifhitbyweapon_r(DDukeActor* sn); diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 8e8f4dfd2..2e1860644 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -19,6 +19,7 @@ #include "soundefs.h" #include "gamestruct.h" #include "v_draw.h" +#include "gamefuncs.h" BEGIN_DUKE_NS @@ -88,14 +89,14 @@ struct Dispatcher void (*checkhitsprite)(DDukeActor* i, DDukeActor* sn); void (*checksectors)(int low); - bool (*ceilingspace)(int sectnum); - bool (*floorspace)(int sectnum); + bool (*ceilingspace)(sectortype* sectp); + bool (*floorspace)(sectortype* sectp); void (*addweapon)(struct player_struct *p, int weapon); void (*hitradius)(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4); - void (*lotsofmoney)(DDukeActor *s, short n); - void (*lotsofmail)(DDukeActor *s, short n); - void (*lotsofpaper)(DDukeActor *s, short n); - void (*guts)(DDukeActor* s, short gtype, short n, short p); + void (*lotsofmoney)(DDukeActor *s, int n); + void (*lotsofmail)(DDukeActor *s, int n); + void (*lotsofpaper)(DDukeActor *s, int n); + void (*guts)(DDukeActor* s, int gtype, int n, int p); DDukeActor* (*ifhitsectors)(int sectnum); int (*ifhitbyweapon)(DDukeActor* sectnum); void (*fall)(DDukeActor* actor, int g_p); diff --git a/source/games/duke/src/dukeactor.h b/source/games/duke/src/dukeactor.h index d7804b525..7eef940b7 100644 --- a/source/games/duke/src/dukeactor.h +++ b/source/games/duke/src/dukeactor.h @@ -179,13 +179,13 @@ inline int movesprite_ex(DDukeActor* actor, int xchange, int ychange, int zchang return f(actor, xchange, ychange, zchange, cliptype, result); } -inline int clipmove_ex(int* x, int* y, int* z, short* sect, int xv, int yv, int wal, int ceil, int flor, int ct, Collision& result) +inline int clipmove_ex(vec3_t* pos, int* sect, int xv, int yv, int wal, int ceil, int flor, int ct, Collision& result) { - int res = clipmove(x, y, z, sect, xv, yv, wal, ceil, flor, ct); + int res = clipmove(pos, sect, xv, yv, wal, ceil, flor, ct); return result.setFromEngine(res); } -inline void getzrange_ex(int x, int y, int z, int16_t sectnum, int32_t* ceilz, Collision& ceilhit, int32_t* florz, Collision& florhit, int32_t walldist, uint32_t cliptype) +inline void getzrange_ex(int x, int y, int z, int sectnum, int32_t* ceilz, Collision& ceilhit, int32_t* florz, Collision& florhit, int32_t walldist, uint32_t cliptype) { int ch, fh; getzrange(x, y, z, sectnum, ceilz, &ch, florz, &fh, walldist, cliptype); @@ -193,22 +193,27 @@ inline void getzrange_ex(int x, int y, int z, int16_t sectnum, int32_t* ceilz, C florhit.setFromEngine(fh); } -inline int hitscan(int x, int y, int z, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz, - short* hitsect, short* hitwall, DDukeActor** hitspr, int* hitx, int* hity, int* hitz, uint32_t cliptype) +inline int hitscan(int x, int y, int z, int sectnum, int32_t vx, int32_t vy, int32_t vz, + int* hitsect, int* hitwall, DDukeActor** hitspr, int* hitx, int* hity, int* hitz, uint32_t cliptype) { - short hitsprt; - int res = ::hitscan(x, y, z, sectnum, vx, vy, vz, hitsect, hitwall, &hitsprt, hitx, hity, hitz, cliptype); + short hitsprt, hitsct, hitwal; + int res = ::hitscan(x, y, z, sectnum, vx, vy, vz, &hitsct, &hitwal, &hitsprt, hitx, hity, hitz, cliptype); if (hitspr) *hitspr = hitsprt == -1 ? nullptr : &hittype[hitsprt]; + if (hitsect) *hitsect = hitsct; + if (hitwall) *hitwall = hitwal; return res; } -inline void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange, - int16_t* neartagsector, int16_t* neartagwall, DDukeActor** neartagsprite, +inline void neartag(int32_t xs, int32_t ys, int32_t zs, int sectnum, int ange, + int* neartagsector, int* neartagwall, DDukeActor** neartagsprite, int32_t* neartaghitdist, int32_t neartagrange, uint8_t tagsearch) { int16_t nts; - ::neartag(xs, ys, zs, sectnum, ange, neartagsector, neartagwall, &nts, neartaghitdist, neartagrange, tagsearch); + int16_t ntsec, ntwal; + ::neartag(xs, ys, zs, sectnum, ange, &ntsec, &ntwal, &nts, neartaghitdist, neartagrange, tagsearch); *neartagsprite = nts == -1 ? nullptr : &hittype[nts]; + *neartagsector = ntsec; + *neartagwall = ntwal; } diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index bc3f2a56e..22b676816 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -84,7 +84,7 @@ void handle_se19(DDukeActor* i, int BIGFORCE); void handle_se20(DDukeActor* i); void handle_se21(DDukeActor* i); void handle_se22(DDukeActor* i); -void handle_se24(DDukeActor* actor, int16_t* list1, int16_t* list2, bool scroll, int TRIPBOMB, int LASERLINE, int CRANE, int shift); +void handle_se24(DDukeActor* actor, const int16_t* list1, const int16_t* list2, bool scroll, int TRIPBOMB, int LASERLINE, int CRANE, int shift); void handle_se25(DDukeActor* a, int t_index, int snd1, int snd2); void handle_se26(DDukeActor* i); void handle_se27(DDukeActor* i); @@ -136,7 +136,7 @@ int madenoise(int playerNum); int haskey(int sect, int snum); void shootbloodsplat(DDukeActor* i, int p, int sx, int sy, int sz, int sa, int atwith, int BIGFORCE, int OOZFILTER, int NEWBEAST); -void breakwall(short newpn, DDukeActor* spr, short dawallnum); +void breakwall(int newpn, DDukeActor* spr, int dawallnum); int callsound(int sectnum,DDukeActor* snum); int hitasprite(DDukeActor* snum,DDukeActor **hitSprite); int findplayer(const DDukeActor* s, int* dist); @@ -153,7 +153,7 @@ void hud_input(int playerNum); int getanimationgoal(int animtype, int animindex); bool isanearoperator(int lotag); bool isanunderoperator(int lotag); -int setanimation(short animsect, int animtype, int animindex, int thegoal, int thevel); +int setanimation(int animsect, int animtype, int animindex, int thegoal, int thevel); void dofurniture(int wallNum, int sectnum, int playerNum); void dotorch(); int hitawall(struct player_struct* pl, int* hitWall); @@ -169,7 +169,7 @@ int furthestangle(DDukeActor* snum, int angDiv); void getglobalz(DDukeActor* s); void OnEvent(int id, int pnum = -1, DDukeActor* snum = nullptr, int dist = -1); -DDukeActor* EGS(short whatsect, int s_x, int s_y, int s_z, short s_pn, signed char s_s, signed char s_xr, signed char s_yr, short s_a, short s_ve, int s_zv, DDukeActor* s_ow, signed char s_ss); +DDukeActor* EGS(int whatsect, int s_x, int s_y, int s_z, int s_pn, int8_t s_s, int8_t s_xr, int8_t s_yr, int s_a, int s_ve, int s_zv, DDukeActor* s_ow, int8_t s_ss); void ceilingglass(DDukeActor* snum, int sectnum, int cnt); void spriteglass(DDukeActor* snum, int cnt); void lotsofcolourglass(DDukeActor* snum, int wallNum, int cnt); diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp index 40dca7aaa..765695df7 100644 --- a/source/games/duke/src/game_misc.cpp +++ b/source/games/duke/src/game_misc.cpp @@ -60,8 +60,8 @@ FString GameInterface::GetCoordString() FString out; out.Format("pos= %d, %d, %d - angle = %2.3f - sector = %d, lotag = %d, hitag = %d", - ps[snum].posx, ps[snum].posy, ps[snum].posz, ps[snum].angle.ang.asdeg(), ps[snum].cursectnum, - sector[ps[snum].cursectnum].lotag, sector[ps[snum].cursectnum].hitag); + ps[snum].pos.x, ps[snum].pos.y, ps[snum].pos.z, ps[snum].angle.ang.asdeg(), ps[snum].cursectnum, + ps[snum].cursector()->lotag, ps[snum].cursector()->hitag); return out; } @@ -215,7 +215,7 @@ void V_AddBlend (float r, float g, float b, float a, float v_blend[4]) void drawoverlays(double smoothratio) { - unsigned char fader = 0, fadeg = 0, fadeb = 0, fadef = 0, tintr = 0, tintg = 0, tintb = 0, tintf = 0, dotint = 0; + uint8_t fader = 0, fadeg = 0, fadeb = 0, fadef = 0, tintr = 0, tintg = 0, tintb = 0, tintf = 0, dotint = 0; struct player_struct* pp; int cposx, cposy, cang; @@ -252,7 +252,7 @@ void drawoverlays(double smoothratio) { fi.displayweapon(screenpeek, smoothratio); if (pp->over_shoulder_on == 0) - fi.displaymasks(screenpeek, pp->GetActor()->s->pal == 1 ? 1 : sector[pp->cursectnum].floorpal, smoothratio); + fi.displaymasks(screenpeek, pp->GetActor()->s->pal == 1 ? 1 : pp->cursector()->floorpal, smoothratio); } if (!isRR()) moveclouds(smoothratio); @@ -272,8 +272,8 @@ void drawoverlays(double smoothratio) } else { - cposx = interpolatedvalue(pp->oposx, pp->posx, smoothratio); - cposy = interpolatedvalue(pp->oposy, pp->posy, smoothratio); + cposx = interpolatedvalue(pp->oposx, pp->pos.x, smoothratio); + cposy = interpolatedvalue(pp->oposy, pp->pos.y, smoothratio); cang = (!SyncInput() ? pp->angle.ang : interpolatedangle(pp->angle.oang, pp->angle.ang, smoothratio)).asbuild(); } } @@ -561,7 +561,7 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang, else i = TILE_APLAYERTOP; - j = abs(pp.truefz - pp.posz) >> 8; + j = abs(pp.truefz - pp.pos.z) >> 8; j = czoom * (pspr->yrepeat + j); if (j < 22000) j = 22000; diff --git a/source/games/duke/src/gamedef.cpp b/source/games/duke/src/gamedef.cpp index d18ef46b0..8234b92b1 100644 --- a/source/games/duke/src/gamedef.cpp +++ b/source/games/duke/src/gamedef.cpp @@ -2007,7 +2007,7 @@ int ConCompiler::parsecommand() { int lLabelID; // syntax getsector[].x - // gets the value of sector[].xxx into + // gets the value of sector [].xxx into // now get name of .xxx while ((*textptr != '[')) @@ -2592,7 +2592,7 @@ int ConCompiler::parsecommand() { int lLabelID; // syntax getsector[].x - // gets the value of sector[].xxx into + // gets the value of sector [].xxx into // now get name of .xxx while ((*textptr != '[')) @@ -2971,7 +2971,7 @@ int ConCompiler::parsecommand() } #endif // syntax: - // int x, int y, short tilenum, signed char shade, char orientation + // int x, int y, int tilenum, int shade, int orientation // myospal adds char pal // Parse: x diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 095a1ac39..df1259b00 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -307,15 +307,15 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, break; case PLAYER_POSX: // oh, my... :( Writing to these has been disabled until I know how to do it without the engine shitting all over itself. - if (!bSet) SetGameVarID(lVar2, ps[iPlayer].posx, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, ps[iPlayer].pos.x, sActor, sPlayer); break; case PLAYER_POSY: - if (!bSet) SetGameVarID(lVar2, ps[iPlayer].posy, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, ps[iPlayer].pos.y, sActor, sPlayer); break; case PLAYER_POSZ: - if (!bSet) SetGameVarID(lVar2, ps[iPlayer].posz, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, ps[iPlayer].pos.z, sActor, sPlayer); break; case PLAYER_HORIZ: @@ -692,7 +692,11 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, break; case PLAYER_ROTSCRNANG: - if (bSet) ps[iPlayer].angle.rotscrnang = buildang(lValue); + if (bSet) + { + ps[iPlayer].angle.orotscrnang = ps[iPlayer].angle.rotscrnang; + ps[iPlayer].angle.rotscrnang = buildang(lValue); + } else SetGameVarID(lVar2, ps[iPlayer].angle.rotscrnang.asbuild(), sActor, sPlayer); break; @@ -912,7 +916,7 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, } else { - auto center = ps[iPlayer].sync.actions & SB_CENTERVIEW ? xs_CRoundToInt(ps[iPlayer].horizon.horiz.asq16() * (9. / gi->playerHorizMax())) : 0; + auto center = ps[iPlayer].sync.actions & SB_CENTERVIEW ? abs(xs_CRoundToInt(ps[iPlayer].horizon.horiz.asq16() * (9. / gi->playerHorizMax()))) : 0; SetGameVarID(lVar2, center, sActor, sPlayer); } break; @@ -925,7 +929,7 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, } //////////////////// -void DoWall(char bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, short sPlayer, int lParm2) +void DoWall(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, int sPlayer, int lParm2) { int iWall; int lValue; @@ -939,72 +943,73 @@ void DoWall(char bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, s if (!bSet) SetGameVarID(lVar2, 0, sActor, sPlayer); return; } + auto wallp = &wall[iWall]; // All fields affecting map geometry have been made read-only! switch (lLabelID) { case WALL_X: - if (!bSet) SetGameVarID(lVar2, wall[iWall].x, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, wallp->x, sActor, sPlayer); break; case WALL_Y: - if (bSet) SetGameVarID(lVar2, wall[iWall].y, sActor, sPlayer); + if (bSet) SetGameVarID(lVar2, wallp->y, sActor, sPlayer); break; case WALL_POINT2: - if (!bSet) SetGameVarID(lVar2, wall[iWall].point2, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, wallp->point2, sActor, sPlayer); break; case WALL_NEXTWALL: - if (!bSet) SetGameVarID(lVar2, wall[iWall].nextwall, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, wallp->nextwall, sActor, sPlayer); break; case WALL_NEXTSECTOR: - if (!bSet) SetGameVarID(lVar2, wall[iWall].nextsector, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, wallp->nextsector, sActor, sPlayer); break; case WALL_CSTAT: - if (bSet) wall[iWall].cstat = lValue; - else SetGameVarID(lVar2, wall[iWall].cstat, sActor, sPlayer); + if (bSet) wallp->cstat = lValue; + else SetGameVarID(lVar2, wallp->cstat, sActor, sPlayer); break; case WALL_PICNUM: - if (bSet) wall[iWall].picnum = lValue; - else SetGameVarID(lVar2, wall[iWall].picnum, sActor, sPlayer); + if (bSet) wallp->picnum = lValue; + else SetGameVarID(lVar2, wallp->picnum, sActor, sPlayer); break; case WALL_OVERPICNUM: - if (bSet) wall[iWall].overpicnum = lValue; - else SetGameVarID(lVar2, wall[iWall].overpicnum, sActor, sPlayer); + if (bSet) wallp->overpicnum = lValue; + else SetGameVarID(lVar2, wallp->overpicnum, sActor, sPlayer); break; case WALL_SHADE: - if (bSet) wall[iWall].shade = lValue; - else SetGameVarID(lVar2, wall[iWall].shade, sActor, sPlayer); + if (bSet) wallp->shade = lValue; + else SetGameVarID(lVar2, wallp->shade, sActor, sPlayer); break; case WALL_PAL: - if (bSet) wall[iWall].pal = lValue; - else SetGameVarID(lVar2, wall[iWall].pal, sActor, sPlayer); + if (bSet) wallp->pal = lValue; + else SetGameVarID(lVar2, wallp->pal, sActor, sPlayer); break; case WALL_XREPEAT: - if (bSet) wall[iWall].xrepeat = lValue; - else SetGameVarID(lVar2, wall[iWall].xrepeat, sActor, sPlayer); + if (bSet) wallp->xrepeat = lValue; + else SetGameVarID(lVar2, wallp->xrepeat, sActor, sPlayer); break; case WALL_YREPEAT: - if (bSet) wall[iWall].yrepeat = lValue; - else SetGameVarID(lVar2, wall[iWall].yrepeat, sActor, sPlayer); + if (bSet) wallp->yrepeat = lValue; + else SetGameVarID(lVar2, wallp->yrepeat, sActor, sPlayer); break; case WALL_XPANNING: - if (bSet) wall[iWall].xpan_ = (float)(lValue & 255); - else SetGameVarID(lVar2, wall[iWall].xpan(), sActor, sPlayer); + if (bSet) wallp->xpan_ = (float)(lValue & 255); + else SetGameVarID(lVar2, wallp->xpan(), sActor, sPlayer); break; case WALL_YPANNING: - if (bSet) wall[iWall].ypan_ = (float)(lValue & 255); - else SetGameVarID(lVar2, wall[iWall].ypan(), sActor, sPlayer); + if (bSet) wallp->ypan_ = (float)(lValue & 255); + else SetGameVarID(lVar2, wallp->ypan(), sActor, sPlayer); break; case WALL_LOTAG: - if (bSet) wall[iWall].lotag = lValue; - else SetGameVarID(lVar2, wall[iWall].lotag, sActor, sPlayer); + if (bSet) wallp->lotag = lValue; + else SetGameVarID(lVar2, wallp->lotag, sActor, sPlayer); break; case WALL_HITAG: - if (bSet) wall[iWall].hitag = lValue; - else SetGameVarID(lVar2, wall[iWall].hitag, sActor, sPlayer); + if (bSet) wallp->hitag = lValue; + else SetGameVarID(lVar2, wallp->hitag, sActor, sPlayer); break; case WALL_EXTRA: - if (bSet) wall[iWall].extra = lValue; - else SetGameVarID(lVar2, wall[iWall].extra, sActor, sPlayer); + if (bSet) wallp->extra = lValue; + else SetGameVarID(lVar2, wallp->extra, sActor, sPlayer); break; default: break; @@ -1012,7 +1017,7 @@ void DoWall(char bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, s return; } -void DoSector(char bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, short sPlayer, int lParm2) +void DoSector(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, int sPlayer, int lParm2) { int iSector; int lValue; @@ -1034,95 +1039,96 @@ void DoSector(char bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, } lValue = GetGameVarID(lVar2, sActor, sPlayer); + auto sectp = §or[iSector]; // All fields affecting map geometry have been made read-only! switch (lLabelID) { case SECTOR_WALLPTR: - if (!bSet) SetGameVarID(lVar2, sector[iSector].wallptr, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, sectp->wallptr, sActor, sPlayer); break; case SECTOR_WALLNUM: - if (!bSet) SetGameVarID(lVar2, sector[iSector].wallnum, sActor, sPlayer); + if (!bSet) SetGameVarID(lVar2, sectp->wallnum, sActor, sPlayer); break; case SECTOR_CEILINGZ: - if (bSet) sector[iSector].ceilingz = lValue; - else SetGameVarID(lVar2, sector[iSector].ceilingz, sActor, sPlayer); + if (bSet) sectp->ceilingz = lValue; + else SetGameVarID(lVar2, sectp->ceilingz, sActor, sPlayer); break; case SECTOR_FLOORZ: - if (bSet) sector[iSector].floorz = lValue; - else SetGameVarID(lVar2, sector[iSector].floorz, sActor, sPlayer); + if (bSet) sectp->floorz = lValue; + else SetGameVarID(lVar2, sectp->floorz, sActor, sPlayer); break; case SECTOR_CEILINGSTAT: - if (bSet) sector[iSector].ceilingstat = lValue; - else SetGameVarID(lVar2, sector[iSector].ceilingstat, sActor, sPlayer); + if (bSet) sectp->ceilingstat = lValue; + else SetGameVarID(lVar2, sectp->ceilingstat, sActor, sPlayer); break; case SECTOR_FLOORSTAT: - if (bSet) sector[iSector].floorstat = lValue; - else SetGameVarID(lVar2, sector[iSector].floorstat, sActor, sPlayer); + if (bSet) sectp->floorstat = lValue; + else SetGameVarID(lVar2, sectp->floorstat, sActor, sPlayer); break; case SECTOR_CEILINGPICNUM: - if (bSet) sector[iSector].ceilingpicnum = lValue; - else SetGameVarID(lVar2, sector[iSector].ceilingpicnum, sActor, sPlayer); + if (bSet) sectp->ceilingpicnum = lValue; + else SetGameVarID(lVar2, sectp->ceilingpicnum, sActor, sPlayer); break; case SECTOR_CEILINGSLOPE: - if (bSet) sector[iSector].ceilingheinum = lValue; - else SetGameVarID(lVar2, sector[iSector].ceilingheinum, sActor, sPlayer); + if (bSet) sectp->ceilingheinum = lValue; + else SetGameVarID(lVar2, sectp->ceilingheinum, sActor, sPlayer); break; case SECTOR_CEILINGSHADE: - if (bSet) sector[iSector].ceilingshade = lValue; - else SetGameVarID(lVar2, sector[iSector].ceilingshade, sActor, sPlayer); + if (bSet) sectp->ceilingshade = lValue; + else SetGameVarID(lVar2, sectp->ceilingshade, sActor, sPlayer); break; case SECTOR_CEILINGPAL: - if (bSet) sector[iSector].ceilingpal = lValue; - else SetGameVarID(lVar2, sector[iSector].ceilingpal, sActor, sPlayer); + if (bSet) sectp->ceilingpal = lValue; + else SetGameVarID(lVar2, sectp->ceilingpal, sActor, sPlayer); break; case SECTOR_CEILINGXPANNING: - if (bSet) sector[iSector].ceilingxpan_ = (float)(lValue & 255); - else SetGameVarID(lVar2, sector[iSector].ceilingxpan(), sActor, sPlayer); + if (bSet) sectp->ceilingxpan_ = (float)(lValue & 255); + else SetGameVarID(lVar2, sectp->ceilingxpan(), sActor, sPlayer); break; case SECTOR_CEILINGYPANNING: - if (bSet) sector[iSector].ceilingypan_ = (float)(lValue & 255); - else SetGameVarID(lVar2, sector[iSector].ceilingypan(), sActor, sPlayer); + if (bSet) sectp->ceilingypan_ = (float)(lValue & 255); + else SetGameVarID(lVar2, sectp->ceilingypan(), sActor, sPlayer); break; case SECTOR_FLOORPICNUM: - if (bSet) sector[iSector].floorpicnum = lValue; - else SetGameVarID(lVar2, sector[iSector].floorpicnum, sActor, sPlayer); + if (bSet) sectp->floorpicnum = lValue; + else SetGameVarID(lVar2, sectp->floorpicnum, sActor, sPlayer); break; case SECTOR_FLOORSLOPE: - if (bSet) sector[iSector].floorheinum = lValue; - else SetGameVarID(lVar2, sector[iSector].floorheinum, sActor, sPlayer); + if (bSet) sectp->floorheinum = lValue; + else SetGameVarID(lVar2, sectp->floorheinum, sActor, sPlayer); break; case SECTOR_FLOORSHADE: - if (bSet) sector[iSector].floorshade = lValue; - else SetGameVarID(lVar2, sector[iSector].floorshade, sActor, sPlayer); + if (bSet) sectp->floorshade = lValue; + else SetGameVarID(lVar2, sectp->floorshade, sActor, sPlayer); break; case SECTOR_FLOORPAL: - if (bSet) sector[iSector].floorpal = lValue; - else SetGameVarID(lVar2, sector[iSector].floorpal, sActor, sPlayer); + if (bSet) sectp->floorpal = lValue; + else SetGameVarID(lVar2, sectp->floorpal, sActor, sPlayer); break; case SECTOR_FLOORXPANNING: - if (bSet) sector[iSector].floorxpan_ = (float)(lValue & 255); - else SetGameVarID(lVar2, sector[iSector].floorxpan(), sActor, sPlayer); + if (bSet) sectp->floorxpan_ = (float)(lValue & 255); + else SetGameVarID(lVar2, sectp->floorxpan(), sActor, sPlayer); break; case SECTOR_FLOORYPANNING: - if (bSet) sector[iSector].floorypan_ = (float)(lValue & 255); - else SetGameVarID(lVar2, sector[iSector].floorypan(), sActor, sPlayer); + if (bSet) sectp->floorypan_ = (float)(lValue & 255); + else SetGameVarID(lVar2, sectp->floorypan(), sActor, sPlayer); break; case SECTOR_VISIBILITY: - if (bSet) sector[iSector].visibility = lValue; - else SetGameVarID(lVar2, sector[iSector].visibility, sActor, sPlayer); + if (bSet) sectp->visibility = lValue; + else SetGameVarID(lVar2, sectp->visibility, sActor, sPlayer); break; case SECTOR_LOTAG: - if (bSet) sector[iSector].lotag = lValue; - else SetGameVarID(lVar2, sector[iSector].lotag, sActor, sPlayer); + if (bSet) sectp->lotag = lValue; + else SetGameVarID(lVar2, sectp->lotag, sActor, sPlayer); break; case SECTOR_HITAG: - if (bSet) sector[iSector].hitag = lValue; - else SetGameVarID(lVar2, sector[iSector].hitag, sActor, sPlayer); + if (bSet) sectp->hitag = lValue; + else SetGameVarID(lVar2, sectp->hitag, sActor, sPlayer); break; case SECTOR_EXTRA: - if (bSet) sector[iSector].extra = lValue; - else SetGameVarID(lVar2, sector[iSector].extra, sActor, sPlayer); + if (bSet) sectp->extra = lValue; + else SetGameVarID(lVar2, sectp->extra, sActor, sPlayer); break; default: break; @@ -1390,7 +1396,7 @@ static int ifcanshoottarget(DDukeActor *actor, int g_p, int g_x) int j; if (g_x > 1024) { - short sclip, angdif; + int sclip, angdif; if (badguy(actor) && actor->s->xrepeat > 56) { @@ -1523,12 +1529,12 @@ int ParseState::parse(void) parseifelse(ifcanshoottarget(g_ac, g_p, g_x)); break; case concmd_ifcanseetarget: - j = cansee(g_sp->x, g_sp->y, g_sp->z - ((krand() & 41) << 8), g_sp->sectnum, ps[g_p].posx, ps[g_p].posy, ps[g_p].posz/*-((krand()&41)<<8)*/, ps[g_p].GetActor()->s->sectnum); + j = cansee(g_sp->x, g_sp->y, g_sp->z - ((krand() & 41) << 8), g_sp->sectnum, ps[g_p].pos.x, ps[g_p].pos.y, ps[g_p].pos.z/*-((krand()&41)<<8)*/, ps[g_p].GetActor()->s->sectnum); parseifelse(j); if (j) g_ac->timetosleep = SLEEPTIME; break; case concmd_ifnocover: - j = cansee(g_sp->x, g_sp->y, g_sp->z, g_sp->sectnum, ps[g_p].posx, ps[g_p].posy, ps[g_p].posz, ps[g_p].GetActor()->s->sectnum); + j = cansee(g_sp->x, g_sp->y, g_sp->z, g_sp->sectnum, ps[g_p].pos.x, ps[g_p].pos.y, ps[g_p].pos.z, ps[g_p].GetActor()->s->sectnum); parseifelse(j); if (j) g_ac->timetosleep = SLEEPTIME; break; @@ -1638,7 +1644,7 @@ int ParseState::parse(void) case concmd_garybanjo: if (banjosound == 0) { - short rnum = (krand() & 3) + 1; + int rnum = (krand() & 3) + 1; if (rnum == 4) { banjosound = 262; @@ -1982,8 +1988,8 @@ int ParseState::parse(void) break; case concmd_larrybird: insptr++; - ps[g_p].posz = sector[ps[g_p].GetActor()->s->sectnum].ceilingz; - ps[g_p].GetActor()->s->z = ps[g_p].posz; + ps[g_p].pos.z = ps[g_p].GetActor()->getSector()->ceilingz; + ps[g_p].GetActor()->s->z = ps[g_p].pos.z; break; case concmd_destroyit: insptr++; @@ -2048,11 +2054,11 @@ int ParseState::parse(void) if(!isRR() && ps[g_p].newOwner != nullptr) { ps[g_p].newOwner = nullptr; - ps[g_p].posx = ps[g_p].oposx; - ps[g_p].posy = ps[g_p].oposy; - ps[g_p].posz = ps[g_p].oposz; + ps[g_p].pos.x = ps[g_p].oposx; + ps[g_p].pos.y = ps[g_p].oposy; + ps[g_p].pos.z = ps[g_p].oposz; ps[g_p].angle.restore(); - updatesector(ps[g_p].posx,ps[g_p].posy,&ps[g_p].cursectnum); + updatesector(ps[g_p].pos.x,ps[g_p].pos.y,&ps[g_p].cursectnum); DukeStatIterator it(STAT_ACTOR); while (auto j = it.Next()) @@ -2157,7 +2163,7 @@ int ParseState::parse(void) break; case concmd_debris: { - short dnum; + int dnum; insptr++; dnum = *insptr; @@ -2200,7 +2206,7 @@ int ParseState::parse(void) break; case concmd_cstat: insptr++; - g_sp->cstat = (short) *insptr; + g_sp->cstat = (uint16_t)*insptr; insptr++; break; case concmd_newpic: @@ -2224,12 +2230,12 @@ int ParseState::parse(void) { // I am not convinced this is even remotely smart to be executed from here.. pickrandomspot(g_p); - g_sp->x = ps[g_p].bobposx = ps[g_p].oposx = ps[g_p].posx; - g_sp->y = ps[g_p].bobposy = ps[g_p].oposy = ps[g_p].posy; - g_sp->z = ps[g_p].oposz = ps[g_p].posz; + g_sp->x = ps[g_p].bobposx = ps[g_p].oposx = ps[g_p].pos.x; + g_sp->y = ps[g_p].bobposy = ps[g_p].oposy = ps[g_p].pos.y; + g_sp->z = ps[g_p].oposz = ps[g_p].pos.z; g_sp->backuppos(); - updatesector(ps[g_p].posx, ps[g_p].posy, &ps[g_p].cursectnum); - setsprite(ps[g_p].GetActor(), ps[g_p].posx, ps[g_p].posy, ps[g_p].posz + gs.playerheight); + updatesector(ps[g_p].pos.x, ps[g_p].pos.y, &ps[g_p].cursectnum); + setsprite(ps[g_p].GetActor(), ps[g_p].pos.x, ps[g_p].pos.y, ps[g_p].pos.z + gs.playerheight); g_sp->cstat = 257; g_sp->shade = -12; @@ -2278,10 +2284,10 @@ int ParseState::parse(void) parseifelse(ud.coop || numplayers > 2); break; case concmd_ifonmud: - parseifelse(abs(g_sp->z - sector[g_sp->sectnum].floorz) < (32 << 8) && sector[g_sp->sectnum].floorpicnum == 3073); // eew, hard coded tile numbers.. :? + parseifelse(abs(g_sp->z - g_sp->sector()->floorz) < (32 << 8) && g_sp->sector()->floorpicnum == 3073); // eew, hard coded tile numbers.. :? break; case concmd_ifonwater: - parseifelse( abs(g_sp->z-sector[g_sp->sectnum].floorz) < (32<<8) && sector[g_sp->sectnum].lotag == ST_1_ABOVE_WATER); + parseifelse( abs(g_sp->z-g_sp->sector()->floorz) < (32<<8) && g_sp->sector()->lotag == ST_1_ABOVE_WATER); break; case concmd_ifmotofast: parseifelse(ps[g_p].MotoSpeed > 60); @@ -2302,7 +2308,7 @@ int ParseState::parse(void) break; case concmd_ifinwater: - parseifelse( sector[g_sp->sectnum].lotag == 2); + parseifelse( g_sp->sector()->lotag == 2); break; case concmd_ifcount: insptr++; @@ -2403,7 +2409,7 @@ int ParseState::parse(void) j = 1; else if( (l& prunning) && s >= 8 && PlayerInput(g_p, SB_RUN) ) j = 1; - else if( (l& phigher) && ps[g_p].posz < (g_sp->z-(48<<8)) ) + else if( (l& phigher) && ps[g_p].pos.z < (g_sp->z-(48<<8)) ) j = 1; else if( (l& pwalkingback) && s <= -8 && !(PlayerInput(g_p, SB_RUN)) ) j = 1; @@ -2426,9 +2432,9 @@ int ParseState::parse(void) else if( (l& pfacing) ) { if (g_sp->picnum == TILE_APLAYER && ud.multimode > 1) - j = getincangle(ps[otherp].angle.ang.asbuild(), getangle(ps[g_p].posx - ps[otherp].posx, ps[g_p].posy - ps[otherp].posy)); + j = getincangle(ps[otherp].angle.ang.asbuild(), getangle(ps[g_p].pos.x - ps[otherp].pos.x, ps[g_p].pos.y - ps[otherp].pos.y)); else - j = getincangle(ps[g_p].angle.ang.asbuild(), getangle(g_sp->x - ps[g_p].posx, g_sp->y - ps[g_p].posy)); + j = getincangle(ps[g_p].angle.ang.asbuild(), getangle(g_sp->x - ps[g_p].pos.x, g_sp->y - ps[g_p].pos.y)); if( j > -128 && j < 128 ) j = 1; @@ -2475,23 +2481,25 @@ int ParseState::parse(void) parseifelse(PlayerInput(g_p, SB_OPEN)); break; case concmd_ifoutside: - parseifelse(sector[g_sp->sectnum].ceilingstat & 1); + parseifelse(g_sp->sector()->ceilingstat & 1); break; case concmd_ifmultiplayer: parseifelse(ud.multimode > 1); break; case concmd_operate: insptr++; - if( sector[g_sp->sectnum].lotag == 0 ) + if( g_sp->sector()->lotag == 0 ) { - int16_t neartagsector, neartagwall; + int neartagsector, neartagwall; DDukeActor* neartagsprite; int32_t neartaghitdist; neartag(g_sp->x, g_sp->y, g_sp->z - (32 << 8), g_sp->sectnum, g_sp->ang, &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 768L, 1); - if( neartagsector >= 0 && isanearoperator(sector[neartagsector].lotag) ) - if( (sector[neartagsector].lotag&0xff) == ST_23_SWINGING_DOOR || sector[neartagsector].floorz == sector[neartagsector].ceilingz ) - if( (sector[neartagsector].lotag&16384) == 0 ) - if ((sector[neartagsector].lotag & 32768) == 0) + if (neartagsector >= 0) + { + auto sectp = §or[neartagsector]; + if (isanearoperator(sectp->lotag)) + if ((sectp->lotag & 0xff) == ST_23_SWINGING_DOOR || sectp->floorz == sectp->ceilingz) + if ((sectp->lotag & 16384) == 0 && (sectp->lotag & 32768) == 0) { DukeSectIterator it(neartagsector); DDukeActor* a2; @@ -2504,10 +2512,11 @@ int ParseState::parse(void) if (a2 == nullptr) operatesectors(neartagsector, g_ac); } + } } break; case concmd_ifinspace: - parseifelse(fi.ceilingspace(g_sp->sectnum)); + parseifelse(fi.ceilingspace(g_sp->sector())); break; case concmd_spritepal: @@ -2766,7 +2775,7 @@ int ParseState::parse(void) case concmd_pstomp: insptr++; if( ps[g_p].knee_incs == 0 && ps[g_p].GetActor()->s->xrepeat >= (isRR()? 9: 40) ) - if( cansee(g_sp->x,g_sp->y,g_sp->z-(4<<8),g_sp->sectnum,ps[g_p].posx,ps[g_p].posy,ps[g_p].posz+(16<<8),ps[g_p].GetActor()->s->sectnum) ) + if( cansee(g_sp->x,g_sp->y,g_sp->z-(4<<8),g_sp->sectnum,ps[g_p].pos.x,ps[g_p].pos.y,ps[g_p].pos.z+(16<<8),ps[g_p].GetActor()->s->sectnum) ) { ps[g_p].knee_incs = 1; if(ps[g_p].weapon_pos == 0) @@ -2776,7 +2785,7 @@ int ParseState::parse(void) break; case concmd_ifawayfromwall: { - short s1; + int s1; s1 = g_sp->sectnum; @@ -2807,7 +2816,7 @@ int ParseState::parse(void) insptr++; break; case concmd_ifinouterspace: - parseifelse( fi.floorspace(g_sp->sectnum)); + parseifelse( fi.floorspace(g_sp->sector())); break; case concmd_ifnotmoving: parseifelse( (g_ac->movflag&kHitTypeMask) > kHitSector ); @@ -3102,7 +3111,7 @@ int ParseState::parse(void) case concmd_getangletotarget: { int i; - short ang; + int ang; insptr++; i = *(insptr++); // ID of def @@ -3418,19 +3427,19 @@ int ParseState::parse(void) case concmd_sectgetlotag: { insptr++; - SetGameVarID(g_iLoTagID, sector[g_sp->sectnum].lotag, g_ac, g_p); + SetGameVarID(g_iLoTagID, g_sp->sector()->lotag, g_ac, g_p); break; } case concmd_sectgethitag: { insptr++; - SetGameVarID(g_iHiTagID, sector[g_sp->sectnum].hitag, g_ac, g_p); + SetGameVarID(g_iHiTagID, g_sp->sector()->hitag, g_ac, g_p); break; } case concmd_gettexturefloor: { insptr++; - SetGameVarID(g_iTextureID, sector[g_sp->sectnum].floorpicnum, g_ac, g_p); + SetGameVarID(g_iTextureID, g_sp->sector()->floorpicnum, g_ac, g_p); break; } @@ -3504,7 +3513,7 @@ int ParseState::parse(void) int lCases; int lEnd; int lCheckCase; - char bMatched; + bool bMatched; int* lTempInsPtr; // command format: @@ -3521,7 +3530,7 @@ int ParseState::parse(void) lpDefault = insptr++; lpCases = insptr; insptr += lCases * 2; - bMatched = 0; + bMatched = false; lTempInsPtr = insptr; for (lCheckCase = 0; lCheckCase < lCases && !bMatched; lCheckCase++) { @@ -3533,7 +3542,7 @@ int ParseState::parse(void) if (parse()) break; } - bMatched = 1; + bMatched = true; } } if (!bMatched) @@ -3567,7 +3576,7 @@ int ParseState::parse(void) case concmd_gettextureceiling: { insptr++; - SetGameVarID(g_iTextureID, sector[g_sp->sectnum].ceilingpicnum, g_ac, g_p); + SetGameVarID(g_iTextureID, g_sp->sector()->ceilingpicnum, g_ac, g_p); break; } case concmd_ifvarvarand: @@ -3640,7 +3649,7 @@ int ParseState::parse(void) void LoadActor(DDukeActor *actor, int p, int x) { - char done; + int done; ParseState s; s.g_p = p; // Player ID @@ -3818,7 +3827,7 @@ quit: void OnEvent(int iEventID, int p, DDukeActor *actor, int x) { - char done; + int done; if (iEventID >= MAXGAMEEVENTS) { diff --git a/source/games/duke/src/global.cpp b/source/games/duke/src/global.cpp index e6a5caca4..9a1ceaa70 100644 --- a/source/games/duke/src/global.cpp +++ b/source/games/duke/src/global.cpp @@ -91,29 +91,30 @@ bool sound445done; // used in checksectors_r. This was local state inside // serialized uint8_t sectorextra[MAXSECTORS]; // something about keys, all access through the haskey function. +uint8_t shadedsector[MAXSECTORS]; // display hackiness + DDukeActor hittype[MAXSPRITES + 1]; // +1 to have a blank entry for serialization, all access in game code through the iterators. int spriteqamount = 64; // internal sprite queue int spriteqloc; DDukeActor* spriteq[1024]; -uint8_t shadedsector[MAXSECTORS]; // display hackiness animwalltype animwall[MAXANIMWALLS]; // animated walls int numanimwalls; int animatecnt; // sector plane movement -int16_t animatesect[MAXANIMATES]; +int animatesect[MAXANIMATES]; int8_t animatetype[MAXANIMATES]; -int16_t animatetarget[MAXANIMATES]; +int animatetarget[MAXANIMATES]; int animategoal[MAXANIMATES]; int animatevel[MAXANIMATES]; int numclouds; // cloudy skies -int16_t clouds[256]; +int clouds[256]; float cloudx; float cloudy; int cloudclock; int numcyclers; // sector lighting effects -int16_t cyclers[MAXCYCLERS][6]; +Cycler cyclers[MAXCYCLERS]; int mirrorcnt; -int16_t mirrorsector[64]; // mirrors -int16_t mirrorwall[64]; +int mirrorsector[64]; // mirrors +int mirrorwall[64]; int numplayersprites; // player management for some SEs. player_orig po[MAXPLAYERS]; unsigned ambientfx; // used by soundtag and soundtagonce script commands. If exported, export the commands, not the data! diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 9e101fb4f..3a125611f 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -55,6 +55,7 @@ extern int screenpeek; // Variables that must be saved extern uint8_t sectorextra[MAXSECTORS]; // these hold fields that were formerly in sprite and sector. Move these back into the base structs! +extern uint8_t shadedsector[MAXSECTORS]; extern int rtsplaying; extern int tempwallptr; @@ -62,7 +63,6 @@ extern int tempwallptr; extern bool sound445done; extern player_struct ps[MAXPLAYERS]; extern int spriteqamount; -extern uint8_t shadedsector[MAXSECTORS]; extern int lastvisinc; extern animwalltype animwall[MAXANIMWALLS]; extern int numanimwalls; @@ -84,21 +84,21 @@ enum animtype_t anim_vertexx, anim_vertexy, }; -extern int16_t animatesect[MAXANIMATES]; -extern int16_t animatetarget[MAXANIMATES]; +extern int animatesect[MAXANIMATES]; +extern int animatetarget[MAXANIMATES]; extern int8_t animatetype[MAXANIMATES]; extern int animategoal[MAXANIMATES]; extern int animatevel[MAXANIMATES]; -extern int16_t clouds[256]; +extern int clouds[256]; extern float cloudx; extern float cloudy; extern int cloudclock; extern DDukeActor *spriteq[1024]; -extern int16_t cyclers[MAXCYCLERS][6]; -extern int16_t mirrorsector[64]; -extern int16_t mirrorwall[64]; +extern Cycler cyclers[MAXCYCLERS]; +extern int mirrorsector[64]; +extern int mirrorwall[64]; extern int wupass; extern int chickenplant; diff --git a/source/games/duke/src/hudweapon_d.cpp b/source/games/duke/src/hudweapon_d.cpp index c6a21b8f6..111a54b87 100644 --- a/source/games/duke/src/hudweapon_d.cpp +++ b/source/games/duke/src/hudweapon_d.cpp @@ -88,7 +88,7 @@ void displayloogie(player_struct* p) int animatefist(int gs, player_struct* p, double look_anghalf, double looking_arc, double plravel, int fistpal) { - short fisti; + int fisti; double fistzoom; double fistz; @@ -121,7 +121,7 @@ int animateknee(int gs, player_struct* p, double look_anghalf, double looking_ar { if (p->knee_incs > 11 || p->knee_incs == 0 || p->GetActor()->s->extra <= 0) return 0; - static const short knee_y[] = { 0,-8,-16,-32,-64,-84,-108,-108,-108,-72,-32,-8 }; + static const int8_t knee_y[] = { 0,-8,-16,-32,-64,-84,-108,-108,-108,-72,-32,-8 }; looking_arc += knee_y[p->knee_incs]; @@ -140,7 +140,7 @@ int animateknuckles(int gs, player_struct* p, double look_anghalf, double lookin { if (isWW2GI() || p->over_shoulder_on != 0 || p->knuckle_incs == 0 || p->GetActor()->s->extra <= 0) return 0; - static const short knuckle_frames[] = { 0,1,2,2,3,3,3,2,2,1,0 }; + static const uint8_t knuckle_frames[] = { 0,1,2,2,3,3,3,2,2,1,0 }; hud_drawpal(160 + plravel - look_anghalf, looking_arc + 180 - horiz16th, CRACKKNUCKLES + knuckle_frames[p->knuckle_incs >> 1], gs, 4, pal); @@ -174,7 +174,7 @@ static int animatetip(int gs, player_struct* p, double look_anghalf, double look { if (p->tipincs == 0) return 0; - static const short tip_y[] = { 0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16 }; + static const int8_t tip_y[] = { 0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16 }; hud_drawpal(170 + plravel - look_anghalf, (tip_y[p->tipincs] >> 1) + looking_arc + 240 - horiz16th, TIP + ((26 - p->tipincs) >> 4), gs, 0, pal); @@ -192,7 +192,7 @@ int animateaccess(int gs, player_struct* p, double look_anghalf, double looking_ { if(p->access_incs == 0 || p->GetActor()->s->extra <= 0) return 0; - static const short access_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16}; + static const int8_t access_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16}; looking_arc += access_y[p->access_incs]; @@ -221,7 +221,7 @@ void displayweapon_d(int snum, double smoothratio) int i, j; int o, pal; double weapon_sway, weapon_xoffset, gun_pos, looking_arc, kickback_pic, random_club_frame, hard_landing, look_anghalf, horiz16th, plravel; - signed char shade; + int8_t shade; struct player_struct *p; p = &ps[snum]; @@ -263,7 +263,7 @@ void displayweapon_d(int snum, double smoothratio) shade = p->GetActor()->s->shade; if(shade > 24) shade = 24; - pal = p->GetActor()->s->pal == 1 ? 1 : sector[p->cursectnum].floorpal; + pal = p->GetActor()->s->pal == 1 ? 1 : p->cursector()->floorpal; if (pal == 0) pal = p->palookup; @@ -703,7 +703,7 @@ void displayweapon_d(int snum, double smoothratio) { if (*kb < 5) { - short kb_frames[] = { 0,1,2,0,0 }; + static const uint8_t kb_frames[] = { 0,1,2,0,0 }; double l = 195 - 12 + weapon_xoffset; @@ -813,7 +813,7 @@ void displayweapon_d(int snum, double smoothratio) auto displayhandremote = [&]() { - signed char remote_frames[] = { 0,1,1,2,1,1,0,0,0,0,0 }; + int8_t remote_frames[] = { 0,1,1,2,1,1,0,0,0,0,0 }; weapon_xoffset = -48; @@ -889,7 +889,7 @@ void displayweapon_d(int snum, double smoothratio) { if (*kb) { - char cycloidy[] = { 0,4,12,24,12,4,0 }; + static const uint8_t cycloidy[] = { 0,4,12,24,12,4,0 }; i = Sgn(*kb >> 2); @@ -924,7 +924,7 @@ void displayweapon_d(int snum, double smoothratio) if (*kb) { - char cat_frames[] = { 0,0,1,1,2,2 }; + static const uint8_t cat_frames[] = { 0,0,1,1,2,2 }; if (p->GetActor()->s->pal != 1) { @@ -1173,7 +1173,7 @@ void displayweapon_d(int snum, double smoothratio) auto displayflamethrower = [&]() { - if (*kb < 1 || sector[p->cursectnum].lotag == 2) + if (*kb < 1 || p->cursector()->lotag == 2) { hud_drawpal(weapon_xoffset + 210 - look_anghalf, looking_arc + 261 - gun_pos, FLAMETHROWER, shade, o, pal); hud_drawpal(weapon_xoffset + 210 - look_anghalf, looking_arc + 261 - gun_pos, FLAMETHROWERPILOT, shade, o, pal); diff --git a/source/games/duke/src/hudweapon_r.cpp b/source/games/duke/src/hudweapon_r.cpp index 6fd360121..5a5459e5a 100644 --- a/source/games/duke/src/hudweapon_r.cpp +++ b/source/games/duke/src/hudweapon_r.cpp @@ -71,7 +71,7 @@ void displaymasks_r(int snum, int p, double smoothratio) { //int pin = 0; // to get the proper clock value with regards to interpolation we have add a smoothratio based offset to the value. - double interpclock = PlayClock + (TICSPERFRAME/65536.) * smoothratio; + double interpclock = PlayClock + (+TICSPERFRAME/65536.) * smoothratio; int pin = RS_STRETCH; hud_drawsprite((320 - (tileWidth(SCUBAMASK) >> 1) - 15), (200 - (tileHeight(SCUBAMASK) >> 1) + bsinf(interpclock, -10)), 49152, 0, SCUBAMASK, 0, p, 2 + 16 + pin); hud_drawsprite((320 - tileWidth(SCUBAMASK + 4)), (200 - tileHeight(SCUBAMASK + 4)), 65536, 0, SCUBAMASK + 4, 0, p, 2 + 16 + pin); @@ -110,13 +110,13 @@ void displayweapon_r(int snum, double smoothratio) int cw; int i, j; double weapon_sway, weapon_xoffset, gun_pos, looking_arc, look_anghalf, hard_landing, TiltStatus; - char o,pal; - signed char shade; + int pal; + int8_t shade; auto p = &ps[snum]; auto kb = &p->kickback_pic; - o = 0; + int o = 0; if (cl_hudinterpolation) { @@ -150,7 +150,7 @@ void displayweapon_r(int snum, double smoothratio) shade = p->GetActor()->s->shade; if(shade > 24) shade = 24; - pal = p->GetActor()->s->pal == 1 ? 1 : pal = sector[p->cursectnum].floorpal; + pal = p->GetActor()->s->pal == 1 ? 1 : pal = p->cursector()->floorpal; if(p->newOwner != nullptr || ud.cameraactor != nullptr || p->over_shoulder_on > 0 || (p->GetActor()->s->pal != 1 && p->GetActor()->s->extra <= 0)) return; @@ -318,11 +318,11 @@ void displayweapon_r(int snum, double smoothratio) auto displaycrowbar = [&] { - static const short kb_frames[] = { 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 }; - static const short kb_ox[] = { 310,342,364,418,350,316,282,288,0,0 }; - static const short kb_oy[] = { 300,362,320,268,248,248,277,420,0,0 }; + static const uint8_t kb_frames[] = { 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 }; + static const uint16_t kb_ox[] = { 310,342,364,418,350,316,282,288,0,0 }; + static const uint16_t kb_oy[] = { 300,362,320,268,248,248,277,420,0,0 }; double x; - short y; + int y; x = weapon_xoffset + ((kb_ox[kb_frames[*kb]] >> 1) - 12); y = 200 - (244 - kb_oy[kb_frames[*kb]]); hud_drawpal(x - look_anghalf, looking_arc + y - gun_pos, @@ -337,11 +337,11 @@ void displayweapon_r(int snum, double smoothratio) auto displayslingblade = [&] { - static const short kb_frames[] = { 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 }; - static const short kb_ox[] = { 580,676,310,491,356,210,310,614 }; - static const short kb_oy[] = { 369,363,300,323,371,400,300,440 }; + static const uint8_t kb_frames[] = { 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 }; + static const uint16_t kb_ox[] = { 580,676,310,491,356,210,310,614 }; + static const uint16_t kb_oy[] = { 369,363,300,323,371,400,300,440 }; double x; - short y; + int y; x = weapon_xoffset + ((kb_ox[kb_frames[*kb]] >> 1) - 12); y = 210 - (244 - kb_oy[kb_frames[*kb]]); hud_drawpal(x - look_anghalf + 20, looking_arc + y - gun_pos - 80, @@ -491,13 +491,13 @@ void displayweapon_r(int snum, double smoothratio) { double x; - short y; - static const short kb_frames3[] = { 0,0,1,1,2,2,5,5,6,6,7,7,8,8,0,0,0,0,0,0,0 }; - static const short kb_frames2[] = { 0,0,3,3,4,4,5,5,6,6,7,7,8,8,0,0,20,20,21,21,21,21,20,20,20,20,0,0 }; - static const short kb_frames[] = { 0,0,1,1,2,2,3,3,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,0,0,20,20,21,21,21,21,20,20,20,20,0,0 }; - static const short kb_ox[] = { 300,300,300,300,300,330,320,310,305,306,302 }; - static const short kb_oy[] = { 315,300,302,305,302,302,303,306,302,404,384 }; - short tm; + int y; + static const uint8_t kb_frames3[] = { 0,0,1,1,2,2,5,5,6,6,7,7,8,8,0,0,0,0,0,0,0 }; + static const uint8_t kb_frames2[] = { 0,0,3,3,4,4,5,5,6,6,7,7,8,8,0,0,20,20,21,21,21,21,20,20,20,20,0,0 }; + static const uint8_t kb_frames[] = { 0,0,1,1,2,2,3,3,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,0,0,20,20,21,21,21,21,20,20,20,20,0,0 }; + static const uint16_t kb_ox[] = { 300,300,300,300,300,330,320,310,305,306,302 }; + static const uint16_t kb_oy[] = { 315,300,302,305,302,302,303,306,302,404,384 }; + int tm; tm = 180; if (p->shotgun_state[1]) { @@ -632,10 +632,10 @@ void displayweapon_r(int snum, double smoothratio) if ((*kb) < 22) { static const uint8_t kb_frames[] = { 0,0,1,1,2,2,3,3,4,4,6,6,6,6,5,5,4,4,3,3,0,0 }; - static const short kb_ox[] = { 194,190,185,208,215,215,216,216,201,170 }; - static const short kb_oy[] = { 256,249,248,238,228,218,208,256,245,258 }; + static const uint16_t kb_ox[] = { 194,190,185,208,215,215,216,216,201,170 }; + static const uint16_t kb_oy[] = { 256,249,248,238,228,218,208,256,245,258 }; double x; - short y; + int y; x = weapon_xoffset + (kb_ox[kb_frames[*kb]] - 12); y = 244 - (244 - kb_oy[kb_frames[*kb]]); @@ -648,13 +648,13 @@ void displayweapon_r(int snum, double smoothratio) } else { - static const short kb_frames[] = { 0,0,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,0,0 }; - static const short kb_ox[] = { 244,244,244 }; - static const short kb_oy[] = { 256,249,248 }; + static const uint8_t kb_frames[] = { 0,0,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,0,0 }; + static const uint16_t kb_ox[] = { 244,244,244 }; + static const uint16_t kb_oy[] = { 256,249,248 }; double x; - short dx; - short y; - short dy; + int dx; + int y; + int dy; x = weapon_xoffset + (kb_ox[kb_frames[(*kb) - 22]] - 12); y = 244 - (244 - kb_oy[kb_frames[(*kb) - 22]]); @@ -789,7 +789,7 @@ void displayweapon_r(int snum, double smoothratio) if (!(gs.displayflags & DUKE3D_NO_WIDESCREEN_PINNING)) pin = RS_ALIGN_R; if ((*kb)) { - char cat_frames[] = { 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + static const uint8_t cat_frames[] = { 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; rdmyospal(weapon_xoffset + 260 - look_anghalf, looking_arc + 215 - gun_pos, FREEZE + cat_frames[*kb], -32, o | pin, pal); } else rdmyospal(weapon_xoffset + 260 - look_anghalf, looking_arc + 215 - gun_pos, FREEZE, shade, o | pin, pal); @@ -825,8 +825,8 @@ void displayweapon_r(int snum, double smoothratio) } else { - signed char kb_frames[] = { 1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0 }; - short frm = kb_frames[*kb]; + static const int8_t kb_frames[] = { 1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0 }; + int frm = kb_frames[*kb]; rd2myospal(weapon_xoffset + 184 - look_anghalf, looking_arc + 240 - gun_pos, SHRINKER + frm, shade, o, 0); } diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 59bc1c057..a58af5166 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -189,7 +189,7 @@ inline bool playrunning() inline void doslopetilting(player_struct* p, double const scaleAdjust = 1) { - bool const canslopetilt = p->on_ground && sector[p->cursectnum].lotag != ST_2_UNDERWATER && (sector[p->cursectnum].floorstat & 2); + bool const canslopetilt = p->on_ground && p->cursector()->lotag != ST_2_UNDERWATER && (p->cursector()->floorstat & 2); p->horizon.calcviewpitch(p->pos.vec2, p->angle.ang, p->aim_mode == 0, canslopetilt, p->cursectnum, scaleAdjust); } @@ -202,7 +202,7 @@ inline void doslopetilting(player_struct* p, double const scaleAdjust = 1) inline void hud_draw(double x, double y, int tilenum, int shade, int orientation) { - int p = sector[ps[screenpeek].cursectnum].floorpal; + int p = ps[screenpeek].cursector()->floorpal; hud_drawsprite(x, y, 65536, 0, tilenum, shade, p, 2 | orientation); } diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 38a77215f..ecba9532b 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -58,9 +58,7 @@ void hud_input(int plnum) int i, k; uint8_t dainv; struct player_struct* p; - short unk; - unk = 0; p = &ps[plnum]; auto pact = p->GetActor(); @@ -284,9 +282,9 @@ void hud_input(int plnum) auto pactor = EGS(p->cursectnum, - p->posx, - p->posy, - p->posz + (30 << 8), TILE_APLAYER, -64, 0, 0, p->angle.ang.asbuild(), 0, 0, nullptr, 10); + p->pos.x, + p->pos.y, + p->pos.z + (30 << 8), TILE_APLAYER, -64, 0, 0, p->angle.ang.asbuild(), 0, 0, nullptr, 10); pactor->temp_data[3] = pactor->temp_data[4] = 0; p->holoduke_on = pactor; pactor->s->yvel = plnum; @@ -337,7 +335,7 @@ void hud_input(int plnum) S_PlayActorSound(390, pact); p->noise_radius = 16384; madenoise(plnum); - if (sector[p->cursectnum].lotag == 857) + if (p->cursector()->lotag == 857) { if (p->GetActor()->s->extra <= gs.max_player_health) { @@ -528,7 +526,7 @@ enum static void processInputBits(player_struct *p, ControlInfo* const hidInput) { // Set-up crouch bools. - int const sectorLotag = p->cursectnum != -1 ? sector[p->cursectnum].lotag : 0; + int const sectorLotag = p->cursectnum != -1 ? p->cursector()->lotag : 0; bool const crouchable = sectorLotag != ST_2_UNDERWATER && (sectorLotag != ST_1_ABOVE_WATER || p->spritebridge); bool const disableToggle = p->jetpack_on || (!crouchable && p->on_ground) || (isRRRA() && (p->OnMotorcycle || p->OnBoat)); @@ -652,7 +650,7 @@ static double boatApplyTurn(player_struct *p, ControlInfo* const hidInput, bool if (kbdLeft || kbdRight || p->moto_drink || hidInput->mouseturnx || hidInput->dyaw) { double const velScale = 6. / 19.; - auto const baseVel = !p->NotOnWater ? VEHICLETURN : VEHICLETURN * velScale; + auto const baseVel = !p->NotOnWater ? VEHICLETURN : +VEHICLETURN * velScale; if (kbdLeft || p->moto_drink < 0 || hidInput->mouseturnx < 0 || hidInput->dyaw < 0) { @@ -737,8 +735,8 @@ static void processVehicleInput(player_struct *p, ControlInfo* const hidInput, I if (p->OnBoat || !p->moto_underwater) { - p->vehForwardScale = std::min((buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) + hidInput->dz, 1.f); - p->vehReverseScale = std::min(buttonMap.ButtonDown(gamefunc_Move_Backward) + -hidInput->dz, 1.f); + p->vehForwardScale = min((buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) + hidInput->dz, 1.f); + p->vehReverseScale = min(buttonMap.ButtonDown(gamefunc_Move_Backward) + -hidInput->dz, 1.f); p->vehBraking = buttonMap.ButtonDown(gamefunc_Run); } @@ -752,7 +750,7 @@ static void processVehicleInput(player_struct *p, ControlInfo* const hidInput, I input.avel = (float)boatApplyTurn(p, hidInput, kbdLeft, kbdRight, scaleAdjust); } - loc.fvel = clamp(xs_CRoundToInt(p->MotoSpeed), -(MAXVELMOTO >> 3), MAXVELMOTO); + loc.fvel = (int16_t)clamp(xs_CRoundToInt(p->MotoSpeed), -(MAXVELMOTO >> 3), MAXVELMOTO); input.avel *= BAngToDegree; loc.avel += input.avel; } diff --git a/source/games/duke/src/noise.cpp b/source/games/duke/src/noise.cpp index 15baa7c49..00f670121 100644 --- a/source/games/duke/src/noise.cpp +++ b/source/games/duke/src/noise.cpp @@ -35,8 +35,8 @@ int madenoise(int snum) player_struct *p; p = &ps[snum]; p->donoise = 1; - p->noise_x = p->posx; - p->noise_y = p->posy; + p->noise_x = p->pos.x; + p->noise_y = p->pos.y; return 1; } diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 474c9c9b9..56c750e3e 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -84,8 +84,8 @@ int setpal(struct player_struct* p) if (p->DrugMode) palette = DRUGPAL; else if (p->heat_on) palette = SLIMEPAL; else if (p->cursectnum < 0) palette = BASEPAL; // don't crash if out of range. - else if (sector[p->cursectnum].ceilingpicnum >= TILE_FLOORSLIME && sector[p->cursectnum].ceilingpicnum <= TILE_FLOORSLIME + 2) palette = SLIMEPAL; - else if (sector[p->cursectnum].lotag == ST_2_UNDERWATER) palette = WATERPAL; + else if (p->cursector()->ceilingpicnum >= TILE_FLOORSLIME && p->cursector()->ceilingpicnum <= TILE_FLOORSLIME + 2) palette = SLIMEPAL; + else if (p->cursector()->lotag == ST_2_UNDERWATER) palette = WATERPAL; else palette = BASEPAL; return palette; } @@ -134,7 +134,7 @@ void forceplayerangle(int snum) void tracers(int x1, int y1, int z1, int x2, int y2, int z2, int n) { int i, xv, yv, zv; - short sect = -1; + int sect = -1; i = n + 1; xv = (x2 - x1) / i; @@ -170,8 +170,8 @@ int hits(DDukeActor* actor) { auto sp = actor->s; int sx, sy, sz; - short sect; - short hw; + int sect; + int hw; int zoff; DDukeActor* d; @@ -193,7 +193,7 @@ int hitasprite(DDukeActor* actor, DDukeActor** hitsp) { auto sp = actor->s; int sx, sy, sz, zoff; - short sect, hw; + int sect, hw; if (badguy(actor)) zoff = (42 << 8); @@ -217,14 +217,14 @@ int hitasprite(DDukeActor* actor, DDukeActor** hitsp) int hitawall(struct player_struct* p, int* hitw) { int sx, sy, sz; - short sect, hitw1; + int sect, hitw1; DDukeActor* d; - hitscan(p->posx, p->posy, p->posz, p->cursectnum, + hitscan(p->pos.x, p->pos.y, p->pos.z, p->cursectnum, p->angle.ang.bcos(), p->angle.ang.bsin(), 0, §, &hitw1, &d, &sx, &sy, &sz, CLIPMASK0); *hitw = hitw1; - return (FindDistance2D(sx - p->posx, sy - p->posy)); + return (FindDistance2D(sx - p->pos.x, sy - p->pos.y)); } @@ -236,7 +236,7 @@ int hitawall(struct player_struct* p, int* hitw) DDukeActor* aim(DDukeActor* actor, int aang) { - char gotshrinker, gotfreezer; + bool gotshrinker, gotfreezer; int a, k, cans; int aimstats[] = { STAT_PLAYER, STAT_DUMMYPLAYER, STAT_ACTOR, STAT_ZOMBIEACTOR }; int dx1, dy1, dx2, dy2, dx3, dy3, smax, sdist; @@ -278,8 +278,8 @@ DDukeActor* aim(DDukeActor* actor, int aang) if (isRR()) { - gotshrinker = 0; - gotfreezer = 0; + gotshrinker = false; + gotfreezer = false; } else if (isWW2GI()) { @@ -494,15 +494,15 @@ void footprints(int snum) auto psect = s->sectnum; if (p->footprintcount > 0 && p->on_ground) - if ((sector[p->cursectnum].floorstat & 2) != 2) + if ((p->cursector()->floorstat & 2) != 2) { int j = -1; DukeSectIterator it(psect); while (auto act = it.Next()) { if (act->s->picnum == TILE_FOOTPRINTS || act->s->picnum == TILE_FOOTPRINTS2 || act->s->picnum == TILE_FOOTPRINTS3 || act->s->picnum == TILE_FOOTPRINTS4) - if (abs(act->s->x - p->posx) < 384) - if (abs(act->s->y - p->posy) < 384) + if (abs(act->s->x - p->pos.x) < 384) + if (abs(act->s->y - p->pos.y) < 384) { j = 1; break; @@ -511,7 +511,7 @@ void footprints(int snum) if (j < 0) { p->footprintcount--; - if (sector[p->cursectnum].lotag == 0 && sector[p->cursectnum].hitag == 0) + if (p->cursector()->lotag == 0 && p->cursector()->hitag == 0) { DDukeActor* fprint; switch (krand() & 3) @@ -552,7 +552,7 @@ void playerisdead(int snum, int psectlotag, int fz, int cz) if (s->pal != 1) { SetPlayerPal(p, PalEntry(63, 63, 0, 0)); - p->posz -= (16 << 8); + p->pos.z -= (16 << 8); s->z -= (16 << 8); } #if 0 @@ -609,8 +609,8 @@ void playerisdead(int snum, int psectlotag, int fz, int cz) { if (p->on_warping_sector == 0) { - if (abs(p->posz - fz) > (gs.playerheight >> 1)) - p->posz += 348; + if (abs(p->pos.z - fz) > (gs.playerheight >> 1)) + p->pos.z += 348; } else { @@ -618,20 +618,20 @@ void playerisdead(int snum, int psectlotag, int fz, int cz) s->zvel = -348; } - clipmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 0, 0, 164, (4 << 8), (4 << 8), CLIPMASK0); - // p->bobcounter += 32; + Collision coll; + clipmove_ex(&p->pos, &p->cursectnum, 0, 0, 164, (4 << 8), (4 << 8), CLIPMASK0, coll); } backupplayer(p); p->horizon.horizoff = p->horizon.horiz = q16horiz(0); - updatesector(p->posx, p->posy, &p->cursectnum); + updatesector(p->pos.x, p->pos.y, &p->cursectnum); - pushmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 128L, (4 << 8), (20 << 8), CLIPMASK0); + pushmove(&p->pos, &p->cursectnum, 128L, (4 << 8), (20 << 8), CLIPMASK0); if (fz > cz + (16 << 8) && s->pal != 1) - p->angle.rotscrnang = buildang(p->dead_flag + ((fz + p->posz) >> 7)); + p->angle.rotscrnang = buildang(p->dead_flag + ((fz + p->pos.z) >> 7)); p->on_warping_sector = 0; @@ -706,7 +706,7 @@ void playerCrouch(int snum) OnEvent(EVENT_CROUCH, snum, p->GetActor(), -1); if (GetGameVarID(g_iReturnVarID, p->GetActor(), snum) == 0) { - p->posz += (2048 + 768); + p->pos.z += (2048 + 768); p->crack_time = CRACK_TIME; } } @@ -765,18 +765,18 @@ void player_struct::backuppos(bool noclipping) { if (!noclipping) { - oposx = posx; - oposy = posy; + oposx = pos.x; + oposy = pos.y; } else { - posx = oposx; - posy = oposy; + pos.x = oposx; + pos.y = oposy; } - oposz = posz; - bobposx = posx; - bobposy = posy; + oposz = pos.z; + bobposx = pos.x; + bobposy = pos.y; opyoff = pyoff; } @@ -1006,7 +1006,7 @@ void shootbloodsplat(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, i spritetype* const s = actor->s; int sect = s->sectnum; int zvel; - short hitsect, hitwall; + int hitsect, hitwall; int hitx, hity, hitz; DDukeActor* d; diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 501b4eb81..43ed5d28d 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -176,7 +176,7 @@ static void shootflamethrowerflame(DDukeActor* actor, int p, int sx, int sy, int if (badguy(actor) && (s->hitag & face_player_smart) != 0) sa = (short)(s->ang + (krand() & 31) - 16); - if (sector[s->sectnum].lotag == 2 && (krand() % 5) == 0) + if (s->sector()->lotag == 2 && (krand() % 5) == 0) spawned = spawn(actor, WATERBUBBLE); } else @@ -186,7 +186,7 @@ static void shootflamethrowerflame(DDukeActor* actor, int p, int sx, int sy, int vel = (int)((((512 - (1024 - abs(abs(getangle(sx - ps[p].oposx, sy - ps[p].oposy) - sa) - 1024))) * 0.001953125f) * ps[p].GetActor()->s->xvel) + 400); - if (sector[s->sectnum].lotag == 2 && (krand() % 5) == 0) + if (s->sector()->lotag == 2 && (krand() % 5) == 0) spawned = spawn(actor, WATERBUBBLE); } @@ -232,7 +232,7 @@ static void shootknee(DDukeActor* actor, int p, int sx, int sy, int sz, int sa) auto s = actor->s; int sect = s->sectnum; int zvel; - short hitsect, hitwall; + int hitsect, hitwall; int hitx, hity, hitz; DDukeActor* hitsprt; @@ -319,7 +319,7 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa auto s = actor->s; int sect = s->sectnum; int zvel; - short hitsect, hitwall; + int hitsect, hitwall; int hitx, hity, hitz; DDukeActor* hitact; @@ -389,7 +389,7 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa int x; int j = findplayer(actor, &x); sz -= (4 << 8); - zvel = ((ps[j].posz - sz) << 8) / (ldist(ps[j].GetActor(), actor)); + zvel = ((ps[j].pos.z - sz) << 8) / (ldist(ps[j].GetActor(), actor)); if (s->picnum != BOSS1) { zvel += 128 - (krand() & 255); @@ -398,7 +398,7 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa else { zvel += 128 - (krand() & 255); - sa = getangle(ps[j].posx - sx, ps[j].posy - sy) + 64 - (krand() & 127); + sa = getangle(ps[j].pos.x - sx, ps[j].pos.y - sy) + 64 - (krand() & 127); } } @@ -469,35 +469,36 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa else if (hitwall >= 0) { spawn(spark, SMALLSMOKE); + auto wal = &wall[hitwall]; - if (fi.isadoorwall(wall[hitwall].picnum) == 1) + if (fi.isadoorwall(wal->picnum) == 1) goto SKIPBULLETHOLE; if (p >= 0 && ( - wall[hitwall].picnum == DIPSWITCH || - wall[hitwall].picnum == DIPSWITCH + 1 || - wall[hitwall].picnum == DIPSWITCH2 || - wall[hitwall].picnum == DIPSWITCH2 + 1 || - wall[hitwall].picnum == DIPSWITCH3 || - wall[hitwall].picnum == DIPSWITCH3 + 1 || - wall[hitwall].picnum == HANDSWITCH || - wall[hitwall].picnum == HANDSWITCH + 1)) + wal->picnum == DIPSWITCH || + wal->picnum == DIPSWITCH + 1 || + wal->picnum == DIPSWITCH2 || + wal->picnum == DIPSWITCH2 + 1 || + wal->picnum == DIPSWITCH3 || + wal->picnum == DIPSWITCH3 + 1 || + wal->picnum == HANDSWITCH || + wal->picnum == HANDSWITCH + 1)) { fi.checkhitswitch(p, hitwall, nullptr); return; } - if (wall[hitwall].hitag != 0 || (wall[hitwall].nextwall >= 0 && wall[wall[hitwall].nextwall].hitag != 0)) + if (wal->hitag != 0 || (wal->nextwall >= 0 && wal->nextWall()->hitag != 0)) goto SKIPBULLETHOLE; if (hitsect >= 0 && sector[hitsect].lotag == 0) - if (wall[hitwall].overpicnum != BIGFORCE) - if ((wall[hitwall].nextsector >= 0 && sector[wall[hitwall].nextsector].lotag == 0) || - (wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0)) - if ((wall[hitwall].cstat & 16) == 0) + if (wal->overpicnum != BIGFORCE) + if ((wal->nextsector >= 0 && wal->nextSector()->lotag == 0) || + (wal->nextsector == -1 && sector[hitsect].lotag == 0)) + if ((wal->cstat & 16) == 0) { - if (wall[hitwall].nextsector >= 0) + if (wal->nextsector >= 0) { - DukeSectIterator it(wall[hitwall].nextsector); + DukeSectIterator it(wal->nextsector); while (auto l = it.Next()) { if (l->s->statnum == 3 && l->s->lotag == 13) @@ -514,17 +515,17 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa } auto hole = spawn(spark, BULLETHOLE); hole->s->xvel = -1; - hole->s->ang = getangle(wall[hitwall].x - wall[wall[hitwall].point2].x, - wall[hitwall].y - wall[wall[hitwall].point2].y) + 512; + hole->s->ang = getangle(wal->x - wall[wal->point2].x, + wal->y - wall[wal->point2].y) + 512; ssp(hole, CLIPMASK0); } SKIPBULLETHOLE: - if (wall[hitwall].cstat & 2) - if (wall[hitwall].nextsector >= 0) - if (hitz >= (sector[wall[hitwall].nextsector].floorz)) - hitwall = wall[hitwall].nextwall; + if (wal->cstat & 2) + if (wal->nextsector >= 0) + if (hitz >= (wal->nextSector()->floorz)) + hitwall = wal->nextwall; fi.checkhitwall(spark, hitwall, hitx, hity, hitz, SHOTSPARK1); } @@ -563,7 +564,7 @@ static void shootstuff(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, spritetype* const s = actor->s; int sect = s->sectnum; int vel, zvel; - short l, scount; + int l, scount; if (s->extra >= 0) s->shade = -96; @@ -674,7 +675,7 @@ static void shootrpg(DDukeActor *actor, int p, int sx, int sy, int sz, int sa, i auto s = actor->s; int sect = s->sectnum; int vel, zvel; - short l, scount; + int l, scount; if (s->extra >= 0) s->shade = -96; @@ -840,7 +841,7 @@ static void shootlaser(DDukeActor* actor, int p, int sx, int sy, int sz, int sa) spritetype* const s = actor->s; int sect = s->sectnum; int zvel; - short hitsect, hitwall, j; + int hitsect, hitwall, j; int hitx, hity, hitz; DDukeActor* hitsprt; @@ -911,7 +912,7 @@ static void shootgrowspark(DDukeActor* actor, int p, int sx, int sy, int sz, int auto s = actor->s; int sect = s->sectnum; int zvel; - short hitsect, hitwall, k; + int hitsect, hitwall, k; int hitx, hity, hitz; DDukeActor* hitsprt; @@ -952,7 +953,7 @@ static void shootgrowspark(DDukeActor* actor, int p, int sx, int sy, int sz, int int x; int j = findplayer(actor, &x); sz -= (4 << 8); - zvel = ((ps[j].posz - sz) << 8) / (ldist(ps[j].GetActor(), actor)); + zvel = ((ps[j].pos.z - sz) << 8) / (ldist(ps[j].GetActor(), actor)); zvel += 128 - (krand() & 255); sa += 32 - (krand() & 63); } @@ -995,7 +996,7 @@ void shoot_d(DDukeActor* actor, int atwith) { spritetype* const s = actor->s; - short sect, l, j; + int sect, l, j; int sx, sy, sz, sa, p, vel, zvel, x, dal; if (s->picnum == TILE_APLAYER) { @@ -1020,9 +1021,9 @@ void shoot_d(DDukeActor* actor, int atwith) if (s->picnum == TILE_APLAYER) { - sx = ps[p].posx; - sy = ps[p].posy; - sz = ps[p].posz + ps[p].pyoff + (4 << 8); + sx = ps[p].pos.x; + sy = ps[p].pos.y; + sz = ps[p].pos.z + ps[p].pyoff + (4 << 8); sa = ps[p].angle.ang.asbuild(); ps[p].crack_time = CRACK_TIME; @@ -1560,7 +1561,7 @@ int doincrements_d(struct player_struct* p) } } - if (p->scuba_on == 0 && sector[p->cursectnum].lotag == 2) + if (p->scuba_on == 0 && p->cursector()->lotag == 2) { if (p->scuba_amount > 0) { @@ -1621,7 +1622,7 @@ int doincrements_d(struct player_struct* p) void checkweapons_d(struct player_struct* p) { - static const short weapon_sprites[MAX_WEAPONS] = { KNEE, FIRSTGUNSPRITE, SHOTGUNSPRITE, + static const uint16_t weapon_sprites[MAX_WEAPONS] = { KNEE, FIRSTGUNSPRITE, SHOTGUNSPRITE, CHAINGUNSPRITE, RPGSPRITE, HEAVYHBOMB, SHRINKERSPRITE, DEVISTATORSPRITE, TRIPBOMBSPRITE, FREEZESPRITE, HEAVYHBOMB, SHRINKERSPRITE }; @@ -1680,7 +1681,7 @@ static void operateJetpack(int snum, ESyncBits actions, int psectlotag, int fz, if (p->jetpack_on < 11) { p->jetpack_on++; - p->posz -= (p->jetpack_on << 7); //Goin up + p->pos.z -= (p->jetpack_on << 7); //Goin up } else if (p->jetpack_on == 11 && !S_CheckActorSoundPlaying(pact, DUKE_JETPACK_IDLE)) S_PlayActorSound(DUKE_JETPACK_IDLE, pact); @@ -1695,7 +1696,7 @@ static void operateJetpack(int snum, ESyncBits actions, int psectlotag, int fz, OnEvent(EVENT_SOARUP, snum, p->GetActor(), -1); if (GetGameVarID(g_iReturnVarID, p->GetActor(), snum) == 0) { - p->posz -= j; + p->pos.z -= j; p->crack_time = CRACK_TIME; } } @@ -1707,7 +1708,7 @@ static void operateJetpack(int snum, ESyncBits actions, int psectlotag, int fz, OnEvent(EVENT_SOARDOWN, snum, p->GetActor(), -1); if (GetGameVarID(g_iReturnVarID, p->GetActor(), snum) == 0) { - p->posz += j; + p->pos.z += j; p->crack_time = CRACK_TIME; } } @@ -1719,10 +1720,10 @@ static void operateJetpack(int snum, ESyncBits actions, int psectlotag, int fz, if (psectlotag != 2 && p->scuba_on == 1) p->scuba_on = 0; - if (p->posz > (fz - (k << 8))) - p->posz += ((fz - (k << 8)) - p->posz) >> 1; - if (p->posz < (pact->ceilingz + (18 << 8))) - p->posz = pact->ceilingz + (18 << 8); + if (p->pos.z > (fz - (k << 8))) + p->pos.z += ((fz - (k << 8)) - p->pos.z) >> 1; + if (p->pos.z < (pact->ceilingz + (18 << 8))) + p->pos.z = pact->ceilingz + (18 << 8); } @@ -1764,7 +1765,7 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int p->dummyplayersprite = spawn(pact, PLAYERONWATER); p->footprintcount = 6; - if (sector[p->cursectnum].floorpicnum == FLOORSLIME) + if (p->cursector()->floorpicnum == FLOORSLIME) p->footprintpal = 8; else p->footprintpal = 0; p->footprintshade = 0; @@ -1776,12 +1777,12 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int footprints(snum); } - if (p->posz < (fz - (i << 8))) //falling + if (p->pos.z < (fz - (i << 8))) //falling { // not jumping or crouching - if ((actions & (SB_JUMP|SB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->posz >= (fz - (i << 8) - (16 << 8))) - p->posz = fz - (i << 8); + if ((actions & (SB_JUMP|SB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->pos.z >= (fz - (i << 8) - (16 << 8))) + p->pos.z = fz - (i << 8); else { p->on_ground = 0; @@ -1794,10 +1795,10 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int S_PlayActorSound(DUKE_SCREAM, pact); } - if ((p->posz + p->poszv) >= (fz - (i << 8))) // hit the ground + if ((p->pos.z + p->poszv) >= (fz - (i << 8))) // hit the ground { S_StopSound(DUKE_SCREAM, pact); - if (sector[p->cursectnum].lotag != 1) + if (p->cursector()->lotag != 1) { if (p->falling_counter > 62) quickkill(p); @@ -1838,18 +1839,18 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int { //Smooth on the ground - int k = ((fz - (i << 8)) - p->posz) >> 1; + int k = ((fz - (i << 8)) - p->pos.z) >> 1; if (abs(k) < 256) k = 0; - p->posz += k; + p->pos.z += k; p->poszv -= 768; if (p->poszv < 0) p->poszv = 0; } else if (p->jumping_counter == 0) { - p->posz += ((fz - (i << 7)) - p->posz) >> 1; //Smooth on the water - if (p->on_warping_sector == 0 && p->posz > fz - (16 << 8)) + p->pos.z += ((fz - (i << 7)) - p->pos.z) >> 1; //Smooth on the water + if (p->on_warping_sector == 0 && p->pos.z > fz - (16 << 8)) { - p->posz = fz - (16 << 8); + p->pos.z = fz - (16 << 8); p->poszv >>= 1; } } @@ -1900,15 +1901,15 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int } } - p->posz += p->poszv; + p->pos.z += p->poszv; - if (p->posz < (cz + (4 << 8))) + if (p->pos.z < (cz + (4 << 8))) { p->jumping_counter = 0; if (p->poszv < 0) p->posxv = p->posyv = 0; p->poszv = 128; - p->posz = cz + (4 << 8); + p->pos.z = cz + (4 << 8); } } @@ -1968,14 +1969,14 @@ static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) if (p->poszv > 2048) p->poszv >>= 1; - p->posz += p->poszv; + p->pos.z += p->poszv; - if (p->posz > (fz - (15 << 8))) - p->posz += ((fz - (15 << 8)) - p->posz) >> 1; + if (p->pos.z > (fz - (15 << 8))) + p->pos.z += ((fz - (15 << 8)) - p->pos.z) >> 1; - if (p->posz < (cz + (4 << 8))) + if (p->pos.z < (cz + (4 << 8))) { - p->posz = cz + (4 << 8); + p->pos.z = cz + (4 << 8); p->poszv = 0; } @@ -1986,7 +1987,7 @@ static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) j->s->y += bsin(p->angle.ang.asbuild() + 64 - (global_random & 128), -6); j->s->xrepeat = 3; j->s->yrepeat = 2; - j->s->z = p->posz + (8 << 8); + j->s->z = p->pos.z + (8 << 8); } } @@ -2001,10 +2002,10 @@ int operateTripbomb(int snum) auto p = &ps[snum]; int sx, sy, sz; - short sect, hw; + int sect, hw; DDukeActor* hitsprt; - hitscan(p->posx, p->posy, p->posz, + hitscan(p->pos.x, p->pos.y, p->pos.z, p->cursectnum, p->angle.ang.bcos(), p->angle.ang.bsin(), -p->horizon.sum().asq16() >> 11, §, &hw, &hitsprt, &sx, &sy, &sz, CLIPMASK1); @@ -2031,9 +2032,9 @@ int operateTripbomb(int snum) if (j == nullptr && hw >= 0 && (wall[hw].cstat & 16) == 0) if ((wall[hw].nextsector >= 0 && sector[wall[hw].nextsector].lotag <= 2) || (wall[hw].nextsector == -1 && sector[sect].lotag <= 2)) - if (((sx - p->posx) * (sx - p->posx) + (sy - p->posy) * (sy - p->posy)) < (290 * 290)) + if (((sx - p->pos.x) * (sx - p->pos.x) + (sy - p->pos.y) * (sy - p->pos.y)) < (290 * 290)) { - p->posz = p->oposz; + p->pos.z = p->oposz; p->poszv = 0; return 1; } @@ -2145,7 +2146,7 @@ static void fireweapon(int snum) if (isWorldTour() && p->ammo_amount[FLAMETHROWER_WEAPON] > 0) { p->kickback_pic = 1; - if (sector[p->cursectnum].lotag != 2) + if (p->cursector()->lotag != 2) S_PlayActorSound(FLAMETHROWER_INTRO, pact); } break; @@ -2198,9 +2199,9 @@ static void operateweapon(int snum, ESyncBits actions, int psect) } auto spawned = EGS(p->cursectnum, - p->posx + p->angle.ang.bcos(-6), - p->posy + p->angle.ang.bsin(-6), - p->posz, HEAVYHBOMB, -16, 9, 9, + p->pos.x + p->angle.ang.bcos(-6), + p->pos.y + p->angle.ang.bsin(-6), + p->pos.z, HEAVYHBOMB, -16, 9, 9, p->angle.ang.asbuild(), (k + (p->hbomb_hold_delay << 5)), i, pact, 1); if (isNam()) @@ -2544,7 +2545,7 @@ static void operateweapon(int snum, ESyncBits actions, int psect) p->kickback_pic++; if (p->kickback_pic == 2) { - if (sector[p->cursectnum].lotag != 2) + if (p->cursector()->lotag != 2) { p->ammo_amount[FLAMETHROWER_WEAPON]--; if (snum == screenpeek) @@ -2568,7 +2569,7 @@ static void operateweapon(int snum, ESyncBits actions, int psect) case TRIPBOMB_WEAPON: // Claymore in NAM if (p->kickback_pic < 4) { - p->posz = p->oposz; + p->pos.z = p->oposz; p->poszv = 0; if (p->kickback_pic == 3) fi.shoot(pact, HANDHOLDINGLASER); @@ -2703,7 +2704,7 @@ void processinput_d(int snum) int j, k, doubvel, fz, cz, truefdist; Collision chz, clz; bool shrunk; - short psect, psectlotag; + int psect, psectlotag; struct player_struct* p; spritetype* s; @@ -2735,14 +2736,14 @@ void processinput_d(int snum) p->spritebridge = 0; shrunk = (s->yrepeat < 32); - getzrange_ex(p->posx, p->posy, p->posz, psect, &cz, chz, &fz, clz, 163L, CLIPMASK0); + getzrange_ex(p->pos.x, p->pos.y, p->pos.z, psect, &cz, chz, &fz, clz, 163L, CLIPMASK0); - j = getflorzofslope(psect, p->posx, p->posy); + j = getflorzofslope(psect, p->pos.x, p->pos.y); p->truefz = j; - p->truecz = getceilzofslope(psect, p->posx, p->posy); + p->truecz = getceilzofslope(psect, p->pos.x, p->pos.y); - truefdist = abs(p->posz - j); + truefdist = abs(p->pos.z - j); if (clz.type == kHitSector && psectlotag == 1 && truefdist > gs.playerheight + (16 << 8)) psectlotag = 0; @@ -2775,7 +2776,7 @@ void processinput_d(int snum) } else if (badguy(clz.actor) && clz.actor->s->xrepeat > 24 && abs(s->z - clz.actor->s->z) < (84 << 8)) { - j = getangle(clz.actor->s->x - p->posx, clz.actor->s->y - p->posy); + j = getangle(clz.actor->s->x - p->pos.x, clz.actor->s->y - p->pos.y); p->posxv -= bcos(j, 4); p->posyv -= bsin(j, 4); } @@ -2841,10 +2842,10 @@ void processinput_d(int snum) p->playerweaponsway(s->xvel); - s->xvel = clamp(ksqrt((p->posx - p->bobposx) * (p->posx - p->bobposx) + (p->posy - p->bobposy) * (p->posy - p->bobposy)), 0, 512); + s->xvel = clamp(ksqrt((p->pos.x - p->bobposx) * (p->pos.x - p->bobposx) + (p->pos.y - p->bobposy) * (p->pos.y - p->bobposy)), 0, 512); if (p->on_ground) p->bobcounter += p->GetActor()->s->xvel >> 1; - p->backuppos(ud.clipping == 0 && (sector[p->cursectnum].floorpicnum == MIRROR || p->cursectnum < 0 || p->cursectnum >= MAXSECTORS)); + p->backuppos(ud.clipping == 0 && (p->cursector()->floorpicnum == MIRROR || p->cursectnum < 0 || p->cursectnum >= MAXSECTORS)); // Shrinking code @@ -2884,9 +2885,9 @@ void processinput_d(int snum) if (p->spritebridge == 0) { - j = sector[s->sectnum].floorpicnum; + j = s->sector()->floorpicnum; - if (j == PURPLELAVA || sector[s->sectnum].ceilingpicnum == PURPLELAVA) + if (j == PURPLELAVA || s->sector()->ceilingpicnum == PURPLELAVA) { if (p->boot_amount > 0) { @@ -3006,24 +3007,22 @@ HORIZONLY: if (psectlotag == 1 || p->spritebridge == 1) ii = (4L << 8); else ii = (20L << 8); - if (sector[p->cursectnum].lotag == 2) k = 0; + if (p->cursector()->lotag == 2) k = 0; else k = 1; Collision clip{}; if (ud.clipping) { - p->posx += p->posxv >> 14; - p->posy += p->posyv >> 14; - updatesector(p->posx, p->posy, &p->cursectnum); + p->pos.x += p->posxv >> 14; + p->pos.y += p->posyv >> 14; + updatesector(p->pos.x, p->pos.y, &p->cursectnum); changeactorsect(pact, p->cursectnum); } else - clipmove_ex(&p->posx, &p->posy, - &p->posz, &p->cursectnum, - p->posxv, p->posyv, 164L, (4L << 8), ii, CLIPMASK0, clip); + clipmove_ex(&p->pos, &p->cursectnum, p->posxv, p->posyv, 164, (4 << 8), ii, CLIPMASK0, clip); if (p->jetpack_on == 0 && psectlotag != 2 && psectlotag != 1 && shrunk) - p->posz += 32 << 8; + p->pos.z += 32 << 8; if (clip.type != kHitNone) checkplayerhurt_d(p, clip); @@ -3044,7 +3043,7 @@ HORIZONLY: } // RBG*** - setsprite(pact, p->posx, p->posy, p->posz + gs.playerheight); + setsprite(pact, p->pos.x, p->pos.y, p->pos.z + gs.playerheight); if (psectlotag < 3) { @@ -3060,7 +3059,7 @@ HORIZONLY: } } - if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && sector[p->cursectnum].lotag == 1) + if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && p->cursector()->lotag == 1) if (!S_CheckActorSoundPlaying(pact, DUKE_ONWATER)) S_PlayActorSound(DUKE_ONWATER, pact); @@ -3068,15 +3067,15 @@ HORIZONLY: changeactorsect(pact, p->cursectnum); if (ud.clipping == 0) - j = (pushmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 164L, (4L << 8), (4L << 8), CLIPMASK0) < 0 && furthestangle(p->GetActor(), 8) < 512); + j = (pushmove(&p->pos, &p->cursectnum, 164L, (4L << 8), (4L << 8), CLIPMASK0) < 0 && furthestangle(p->GetActor(), 8) < 512); else j = 0; if (ud.clipping == 0) { if (abs(pact->floorz - pact->ceilingz) < (48 << 8) || j) { - if (!(sector[s->sectnum].lotag & 0x8000) && (isanunderoperator(sector[s->sectnum].lotag) || - isanearoperator(sector[s->sectnum].lotag))) + if (!(s->sector()->lotag & 0x8000) && (isanunderoperator(s->sector()->lotag) || + isanearoperator(s->sector()->lotag))) fi.activatebysector(s->sectnum, pact); if (j) { diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 886115340..5844f63ef 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -44,7 +44,7 @@ BEGIN_DUKE_NS void incur_damage_r(struct player_struct* p) { int damage = 0, unk = 0, shield_damage = 0; - short gut = 0; + int gut = 0; p->GetActor()->s->extra -= p->extra_extra8 >> 8; @@ -88,7 +88,7 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa, spritetype* const s = actor->s; int sect = s->sectnum; int zvel; - short hitsect, hitwall; + int hitsect, hitwall; int hitx, hity, hitz; DDukeActor* hitsprt; @@ -126,11 +126,11 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa, ny = hity + (effector->GetOwner()->s->y - effector->s->y); if (sector[hitsect].lotag == 161) { - nz = sector[effector->GetOwner()->s->sectnum].floorz; + nz = effector->GetOwner()->getSector()->floorz; } else { - nz = sector[effector->GetOwner()->s->sectnum].ceilingz; + nz = effector->GetOwner()->getSector()->ceilingz; } hitscan(nx, ny, nz, effector->GetOwner()->s->sectnum, bcos(sa), bsin(sa), zvel << 6, &hitsect, &hitwall, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1); @@ -210,7 +210,7 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa auto s = actor->s; int sect = s->sectnum; int zvel; - short hitsect, hitwall; + int hitsect, hitwall; int hitx, hity, hitz; DDukeActor* hitsprt; @@ -251,7 +251,7 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa int x; int j = findplayer(actor, &x); sz -= (4 << 8); - zvel = ((ps[j].posz - sz) << 8) / (ldist(ps[j].GetActor(), actor)); + zvel = ((ps[j].pos.z - sz) << 8) / (ldist(ps[j].GetActor(), actor)); if (s->picnum != BOSS1) { zvel += 128 - (krand() & 255); @@ -260,7 +260,7 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa else { zvel += 128 - (krand() & 255); - sa = getangle(ps[j].posx - sx, ps[j].posy - sy) + 64 - (krand() & 127); + sa = getangle(ps[j].pos.x - sx, ps[j].pos.y - sy) + 64 - (krand() & 127); } } @@ -283,11 +283,11 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa ny = hity + (effector->GetOwner()->s->y - effector->s->y); if (sector[hitsect].lotag == 161) { - nz = sector[effector->GetOwner()->s->sectnum].floorz; + nz = effector->GetOwner()->getSector()->floorz; } else { - nz = sector[effector->GetOwner()->s->sectnum].ceilingz; + nz = effector->GetOwner()->getSector()->ceilingz; } hitscan(nx, ny, nz, effector->GetOwner()->s->sectnum, bcos(sa), bsin(sa), zvel << 6, &hitsect, &hitwall, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1); @@ -366,38 +366,39 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa else if (hitwall >= 0) { spawn(spark, SMALLSMOKE); + auto wal = &wall[hitwall]; - if (fi.isadoorwall(wall[hitwall].picnum) == 1) + if (fi.isadoorwall(wal->picnum) == 1) goto SKIPBULLETHOLE; - if (isablockdoor(wall[hitwall].picnum) == 1) + if (isablockdoor(wal->picnum) == 1) goto SKIPBULLETHOLE; if (p >= 0 && ( - wall[hitwall].picnum == DIPSWITCH || - wall[hitwall].picnum == DIPSWITCH + 1 || - wall[hitwall].picnum == DIPSWITCH2 || - wall[hitwall].picnum == DIPSWITCH2 + 1 || - wall[hitwall].picnum == DIPSWITCH3 || - wall[hitwall].picnum == DIPSWITCH3 + 1 || - (isRRRA() && wall[hitwall].picnum == RRTILE8660) || - wall[hitwall].picnum == HANDSWITCH || - wall[hitwall].picnum == HANDSWITCH + 1)) + wal->picnum == DIPSWITCH || + wal->picnum == DIPSWITCH + 1 || + wal->picnum == DIPSWITCH2 || + wal->picnum == DIPSWITCH2 + 1 || + wal->picnum == DIPSWITCH3 || + wal->picnum == DIPSWITCH3 + 1 || + (isRRRA() && wal->picnum == RRTILE8660) || + wal->picnum == HANDSWITCH || + wal->picnum == HANDSWITCH + 1)) { fi.checkhitswitch(p, hitwall, nullptr); return; } - if (wall[hitwall].hitag != 0 || (wall[hitwall].nextwall >= 0 && wall[wall[hitwall].nextwall].hitag != 0)) + if (wal->hitag != 0 || (wal->nextwall >= 0 && wal->nextWall()->hitag != 0)) goto SKIPBULLETHOLE; if (hitsect >= 0 && sector[hitsect].lotag == 0) - if (wall[hitwall].overpicnum != BIGFORCE) - if ((wall[hitwall].nextsector >= 0 && sector[wall[hitwall].nextsector].lotag == 0) || - (wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0)) - if ((wall[hitwall].cstat & 16) == 0) + if (wal->overpicnum != BIGFORCE) + if ((wal->nextsector >= 0 && wal->nextSector()->lotag == 0) || + (wal->nextsector == -1 && sector[hitsect].lotag == 0)) + if ((wal->cstat & 16) == 0) { - if (wall[hitwall].nextsector >= 0) + if (wal->nextsector >= 0) { - DukeSectIterator it(wall[hitwall].nextsector); + DukeSectIterator it(wal->nextsector); while (auto l = it.Next()) { if (l->s->statnum == 3 && l->s->lotag == 13) @@ -414,17 +415,17 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa } auto l = spawn(spark, BULLETHOLE); l->s->xvel = -1; - l->s->ang = getangle(wall[hitwall].x - wall[wall[hitwall].point2].x, - wall[hitwall].y - wall[wall[hitwall].point2].y) + 512; + l->s->ang = getangle(wal->x - wall[wal->point2].x, + wal->y - wall[wal->point2].y) + 512; ssp(l, CLIPMASK0); } SKIPBULLETHOLE: - if (wall[hitwall].cstat & 2) - if (wall[hitwall].nextsector >= 0) - if (hitz >= (sector[wall[hitwall].nextsector].floorz)) - hitwall = wall[hitwall].nextwall; + if (wal->cstat & 2) + if (wal->nextsector >= 0) + if (hitz >= (wal->nextSector()->floorz)) + hitwall = wal->nextwall; fi.checkhitwall(spark, hitwall, hitx, hity, hitz, SHOTSPARK1); } @@ -463,7 +464,7 @@ static void shootstuff(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, auto s = actor->s; int sect = s->sectnum; int vel, zvel; - short scount; + int scount; if (isRRRA()) { @@ -603,7 +604,7 @@ static void shootrpg(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, i auto s = actor->s; int sect = s->sectnum; int vel, zvel; - short l, scount; + int l, scount; DDukeActor* act90 = nullptr; if (s->extra >= 0) s->shade = -96; @@ -755,7 +756,7 @@ static void shootwhip(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, auto s = actor->s; int sect = s->sectnum; int vel, zvel; - short scount; + int scount; if (s->extra >= 0) s->shade = -96; @@ -829,7 +830,7 @@ void shoot_r(DDukeActor* actor, int atwith) { spritetype* const s = actor->s; - short sect, sa, p; + int sect, sa, p; int sx, sy, sz, vel, zvel, x; @@ -840,9 +841,9 @@ void shoot_r(DDukeActor* actor, int atwith) { p = s->yvel; - sx = ps[p].posx; - sy = ps[p].posy; - sz = ps[p].posz + ps[p].pyoff + (4 << 8); + sx = ps[p].pos.x; + sy = ps[p].pos.y; + sz = ps[p].pos.z + ps[p].pyoff + (4 << 8); sa = ps[p].angle.ang.asbuild(); if (isRRRA()) ps[p].crack_time = CRACK_TIME; @@ -1422,7 +1423,7 @@ int doincrements_r(struct player_struct* p) } } - if (p->scuba_on == 0 && sector[p->cursectnum].lotag == 2) + if (p->scuba_on == 0 && p->cursector()->lotag == 2) { if (p->scuba_amount > 0) { @@ -1487,7 +1488,7 @@ int doincrements_r(struct player_struct* p) void checkweapons_r(struct player_struct* p) { - static const short weapon_sprites[MAX_WEAPONS] = { KNEE, FIRSTGUNSPRITE, SHOTGUNSPRITE, + static const uint16_t weapon_sprites[MAX_WEAPONS] = { KNEE, FIRSTGUNSPRITE, SHOTGUNSPRITE, CHAINGUNSPRITE, RPGSPRITE, HEAVYHBOMB, SHRINKERSPRITE, DEVISTATORSPRITE, TRIPBOMBSPRITE, BOWLINGBALLSPRITE, FREEZEBLAST, HEAVYHBOMB }; @@ -1577,7 +1578,7 @@ static void onMotorcycle(int snum, ESyncBits &actions) auto p = &ps[snum]; auto pact = p->GetActor(); - short rng; + int rng; if (p->MotoSpeed < 0) p->MotoSpeed = 0; @@ -1742,11 +1743,11 @@ static void onMotorcycle(int snum, ESyncBits &actions) } if (horiz != FRACUNIT) { - p->horizon.addadjustment(horiz - FixedToFloat(p->horizon.horiz.asq16())); + p->horizon.addadjustment(horiz - p->horizon.horiz.asbuildf()); } int currSpeed = int(p->MotoSpeed); - short velAdjustment; + int velAdjustment; if (p->MotoSpeed >= 20 && p->on_ground == 1 && (p->vehTurnLeft || p->vehTurnRight)) { velAdjustment = p->vehTurnLeft ? -10 : 10; @@ -1815,7 +1816,7 @@ static void onBoat(int snum, ESyncBits &actions) auto pact = p->GetActor(); bool heeltoe; - short rng; + int rng; if (p->NotOnWater) { @@ -2010,13 +2011,13 @@ static void onBoat(int snum, ESyncBits &actions) } if (horiz != FRACUNIT) { - p->horizon.addadjustment(horiz - FixedToFloat(p->horizon.horiz.asq16())); + p->horizon.addadjustment(horiz - p->horizon.horiz.asbuildf()); } if (p->MotoSpeed > 0 && p->on_ground == 1 && (p->vehTurnLeft || p->vehTurnRight)) { int currSpeed = int(p->MotoSpeed * 4.); - short velAdjustment = p->vehTurnLeft ? -10 : 10; + int velAdjustment = p->vehTurnLeft ? -10 : 10; auto angAdjustment = (velAdjustment < 0 ? 350 : -350) << BAMBITS; if (p->moto_do_bump) @@ -2078,12 +2079,12 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int p->dummyplayersprite = spawn(pact, PLAYERONWATER); p->footprintcount = 6; - if (sector[p->cursectnum].floorpicnum == FLOORSLIME) + if (p->cursector()->floorpicnum == FLOORSLIME) { p->footprintpal = 8; p->footprintshade = 0; } - else if (isRRRA() && (sector[p->cursectnum].floorpicnum == RRTILE7756 || sector[p->cursectnum].floorpicnum == RRTILE7888)) + else if (isRRRA() && (p->cursector()->floorpicnum == RRTILE7756 || p->cursector()->floorpicnum == RRTILE7888)) { p->footprintpal = 0; p->footprintshade = 40; @@ -2101,15 +2102,15 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int footprints(snum); } - if (p->posz < (fz - (i << 8))) //falling + if (p->pos.z < (fz - (i << 8))) //falling { - if ((actions & (SB_JUMP|SB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->posz >= (fz - (i << 8) - (16 << 8))) - p->posz = fz - (i << 8); + if ((actions & (SB_JUMP|SB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->pos.z >= (fz - (i << 8) - (16 << 8))) + p->pos.z = fz - (i << 8); else { p->on_ground = 0; - if ((p->OnMotorcycle || p->OnBoat) && fz - (i << 8) * 2 > p->posz) + if ((p->OnMotorcycle || p->OnBoat) && fz - (i << 8) * 2 > p->pos.z) { if (p->MotoOnGround) { @@ -2139,13 +2140,13 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int S_PlayActorSound(DUKE_SCREAM, pact); } - if ((p->posz + p->poszv) >= (fz - (i << 8))) // hit the ground + if ((p->pos.z + p->poszv) >= (fz - (i << 8))) // hit the ground { S_StopSound(DUKE_SCREAM, pact); - if (sector[p->cursectnum].lotag != 1) + if (p->cursector()->lotag != 1) { if (isRRRA()) p->MotoOnGround = 1; - if (p->falling_counter > 62 || (isRRRA() && p->falling_counter > 2 && sector[p->cursectnum].lotag == 802)) + if (p->falling_counter > 62 || (isRRRA() && p->falling_counter > 2 && p->cursector()->lotag == 802)) quickkill(p); else if (p->falling_counter > 9) @@ -2199,18 +2200,18 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int { //Smooth on the ground - int k = ((fz - (i << 8)) - p->posz) >> 1; + int k = ((fz - (i << 8)) - p->pos.z) >> 1; if (abs(k) < 256) k = 0; - p->posz += k; + p->pos.z += k; p->poszv -= 768; if (p->poszv < 0) p->poszv = 0; } else if (p->jumping_counter == 0) { - p->posz += ((fz - (i << 7)) - p->posz) >> 1; //Smooth on the water - if (p->on_warping_sector == 0 && p->posz > fz - (16 << 8)) + p->pos.z += ((fz - (i << 7)) - p->pos.z) >> 1; //Smooth on the water + if (p->on_warping_sector == 0 && p->pos.z > fz - (16 << 8)) { - p->posz = fz - (16 << 8); + p->pos.z = fz - (16 << 8); p->poszv >>= 1; } } @@ -2257,15 +2258,15 @@ static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int } } - p->posz += p->poszv; + p->pos.z += p->poszv; - if (p->posz < (cz + (4 << 8))) + if (p->pos.z < (cz + (4 << 8))) { p->jumping_counter = 0; if (p->poszv < 0) p->posxv = p->posyv = 0; p->poszv = 128; - p->posz = cz + (4 << 8); + p->pos.z = cz + (4 << 8); } } @@ -2321,14 +2322,14 @@ static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) if (p->poszv > 2048) p->poszv >>= 1; - p->posz += p->poszv; + p->pos.z += p->poszv; - if (p->posz > (fz - (15 << 8))) - p->posz += ((fz - (15 << 8)) - p->posz) >> 1; + if (p->pos.z > (fz - (15 << 8))) + p->pos.z += ((fz - (15 << 8)) - p->pos.z) >> 1; - if (p->posz < (cz + (4 << 8))) + if (p->pos.z < (cz + (4 << 8))) { - p->posz = cz + (4 << 8); + p->pos.z = cz + (4 << 8); p->poszv = 0; } @@ -2339,7 +2340,7 @@ static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) j->s->y += bsin(p->angle.ang.asbuild() + 64 - (global_random & 128) + 128, -6); j->s->xrepeat = 3; j->s->yrepeat = 2; - j->s->z = p->posz + (8 << 8); + j->s->z = p->pos.z + (8 << 8); j->s->cstat = 514; } } @@ -2356,8 +2357,8 @@ void onMotorcycleMove(int snum, int psect, int j) auto pact = p->GetActor(); auto s = pact->s; int psectlotag = sector[psect].lotag; - short angleDelta = abs(p->angle.ang.asbuild() - getangle(wall[wall[j].point2].x - wall[j].x, wall[wall[j].point2].y - wall[j].y)); - short damageAmount; + int angleDelta = abs(p->angle.ang.asbuild() - getangle(wall[wall[j].point2].x - wall[j].x, wall[wall[j].point2].y - wall[j].y)); + int damageAmount; p->angle.addadjustment(p->MotoSpeed / (krand() & 1 ? -2 : 2)); @@ -2411,7 +2412,7 @@ void onBoatMove(int snum, int psect, int j) auto p = &ps[snum]; auto pact = p->GetActor(); int psectlotag = sector[psect].lotag; - short angleDelta = abs(p->angle.ang.asbuild() - getangle(wall[wall[j].point2].x - wall[j].x, wall[wall[j].point2].y - wall[j].y)); + int angleDelta = abs(p->angle.ang.asbuild() - getangle(wall[wall[j].point2].x - wall[j].x, wall[wall[j].point2].y - wall[j].y)); p->angle.addadjustment(p->MotoSpeed / (krand() & 1 ? -4 : 4)); @@ -2735,9 +2736,9 @@ static void operateweapon(int snum, ESyncBits actions, int psect) } auto spawned = EGS(p->cursectnum, - p->posx + p->angle.ang.bcos(-6), - p->posy + p->angle.ang.bsin(-6), - p->posz, HEAVYHBOMB, -16, 9, 9, + p->pos.x + p->angle.ang.bcos(-6), + p->pos.y + p->angle.ang.bsin(-6), + p->pos.z, HEAVYHBOMB, -16, 9, 9, p->angle.ang.asbuild(), (k + (p->hbomb_hold_delay << 5)) * 2, i, pact, 1); if (k == 15) @@ -3145,9 +3146,9 @@ static void operateweapon(int snum, ESyncBits actions, int psect) } EGS(p->cursectnum, - p->posx + p->angle.ang.bcos(-6), - p->posy + p->angle.ang.bsin(-6), - p->posz, TRIPBOMBSPRITE, -16, 9, 9, + p->pos.x + p->angle.ang.bcos(-6), + p->pos.y + p->angle.ang.bsin(-6), + p->pos.z, TRIPBOMBSPRITE, -16, 9, 9, p->angle.ang.asbuild(), k * 2, i, pact, 1); } p->kickback_pic++; @@ -3329,8 +3330,8 @@ void processinput_r(int snum) { int i, k, doubvel, fz, cz, truefdist; Collision chz, clz; - char shrunk; - short psect, psectlotag; + bool shrunk; + int psect, psectlotag; auto p = &ps[snum]; auto pact = p->GetActor(); @@ -3372,7 +3373,7 @@ void processinput_r(int snum) while (auto act2 = it.Next()) { if (act2->s->picnum == RRTILE380) - if (act2->s->z - (8 << 8) < p->posz) + if (act2->s->z - (8 << 8) < p->pos.z) psectlotag = 2; } } @@ -3393,19 +3394,19 @@ void processinput_r(int snum) int tempfz; if (s->clipdist == 64) { - getzrange_ex(p->posx, p->posy, p->posz, psect, &cz, chz, &fz, clz, 163L, CLIPMASK0); - tempfz = getflorzofslope(psect, p->posx, p->posy); + getzrange_ex(p->pos.x, p->pos.y, p->pos.z, psect, &cz, chz, &fz, clz, 163L, CLIPMASK0); + tempfz = getflorzofslope(psect, p->pos.x, p->pos.y); } else { - getzrange_ex(p->posx, p->posy, p->posz, psect, &cz, chz, &fz, clz, 4L, CLIPMASK0); - tempfz = getflorzofslope(psect, p->posx, p->posy); + getzrange_ex(p->pos.x, p->pos.y, p->pos.z, psect, &cz, chz, &fz, clz, 4L, CLIPMASK0); + tempfz = getflorzofslope(psect, p->pos.x, p->pos.y); } p->truefz = tempfz; - p->truecz = getceilzofslope(psect, p->posx, p->posy); + p->truecz = getceilzofslope(psect, p->pos.x, p->pos.y); - truefdist = abs(p->posz - tempfz); + truefdist = abs(p->pos.z - tempfz); if (clz.type == kHitSector && psectlotag == 1 && truefdist > gs.playerheight + (16 << 8)) psectlotag = 0; @@ -3469,7 +3470,7 @@ void processinput_r(int snum) } else if (badguy(clz.actor) && clz.actor->s->xrepeat > 24 && abs(s->z - clz.actor->s->z) < (84 << 8)) { - int j = getangle(clz.actor->s->x - p->posx, clz.actor->s->y - p->posy); + int j = getangle(clz.actor->s->x - p->pos.x, clz.actor->s->y - p->pos.y); p->posxv -= bcos(j, 4); p->posyv -= bsin(j, 4); } @@ -3560,10 +3561,10 @@ void processinput_r(int snum) p->playerweaponsway(s->xvel); - s->xvel = clamp(ksqrt((p->posx - p->bobposx) * (p->posx - p->bobposx) + (p->posy - p->bobposy) * (p->posy - p->bobposy)), 0, 512); + s->xvel = clamp(ksqrt((p->pos.x - p->bobposx) * (p->pos.x - p->bobposx) + (p->pos.y - p->bobposy) * (p->pos.y - p->bobposy)), 0, 512); if (p->on_ground) p->bobcounter += p->GetActor()->s->xvel >> 1; - p->backuppos(ud.clipping == 0 && (sector[p->cursectnum].floorpicnum == MIRROR || p->cursectnum < 0 || p->cursectnum >= MAXSECTORS)); + p->backuppos(ud.clipping == 0 && (p->cursector()->floorpicnum == MIRROR || p->cursectnum < 0 || p->cursectnum >= MAXSECTORS)); // Shrinking code @@ -3619,7 +3620,7 @@ void processinput_r(int snum) if (p->spritebridge == 0) { - int j = sector[s->sectnum].floorpicnum; + int j = s->sector()->floorpicnum; k = 0; if (p->on_ground && truefdist <= gs.playerheight + (16 << 8)) @@ -3674,7 +3675,7 @@ void processinput_r(int snum) break; case 1: if ((krand() & 1) == 0) - if (!isRRRA() || (!p->OnBoat && !p->OnMotorcycle && sector[p->cursectnum].hitag != 321)) + if (!isRRRA() || (!p->OnBoat && !p->OnMotorcycle && p->cursector()->hitag != 321)) S_PlayActorSound(DUKE_ONWATER, pact); p->walking_snd_toggle = 1; break; @@ -3769,24 +3770,22 @@ HORIZONLY: if (psectlotag == 1 || p->spritebridge == 1) i = (4L << 8); else i = (20L << 8); - if (sector[p->cursectnum].lotag == 2) k = 0; + if (p->cursector()->lotag == 2) k = 0; else k = 1; Collision clip{}; if (ud.clipping) { - p->posx += p->posxv >> 14; - p->posy += p->posyv >> 14; - updatesector(p->posx, p->posy, &p->cursectnum); + p->pos.x += p->posxv >> 14; + p->pos.y += p->posyv >> 14; + updatesector(p->pos.x, p->pos.y, &p->cursectnum); changeactorsect(pact, p->cursectnum); } else - clipmove_ex(&p->posx, &p->posy, - &p->posz, &p->cursectnum, - p->posxv, p->posyv, 164L, (4L << 8), i, CLIPMASK0, clip); + clipmove_ex(&p->pos, &p->cursectnum, p->posxv, p->posyv, 164, (4 << 8), i, CLIPMASK0, clip); if (p->jetpack_on == 0 && psectlotag != 2 && psectlotag != 1 && shrunk) - p->posz += 32 << 8; + p->pos.z += 32 << 8; if (clip.type != kHitNone) checkplayerhurt_r(p, clip); @@ -3813,10 +3812,10 @@ HORIZONLY: if (wall[clip.index].lotag < 44) { dofurniture(clip.index, p->cursectnum, snum); - pushmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 172L, (4L << 8), (4L << 8), CLIPMASK0); + pushmove(&p->pos, &p->cursectnum, 172L, (4L << 8), (4L << 8), CLIPMASK0); } else - pushmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 172L, (4L << 8), (4L << 8), CLIPMASK0); + pushmove(&p->pos, &p->cursectnum, 172L, (4L << 8), (4L << 8), CLIPMASK0); } } } @@ -3881,7 +3880,7 @@ HORIZONLY: } // RBG*** - setsprite(pact, p->posx, p->posy, p->posz + gs.playerheight); + setsprite(pact, p->pos.x, p->pos.y, p->pos.z + gs.playerheight); if (psectlotag == 800 && (!isRRRA() || !p->lotag800kill)) { @@ -3904,9 +3903,9 @@ HORIZONLY: } } - if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && sector[p->cursectnum].lotag == 1) + if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && p->cursector()->lotag == 1) if (!S_CheckActorSoundPlaying(pact, DUKE_ONWATER)) - if (!isRRRA() || (!p->OnBoat && !p->OnMotorcycle && sector[p->cursectnum].hitag != 321)) + if (!isRRRA() || (!p->OnBoat && !p->OnMotorcycle && p->cursector()->hitag != 321)) S_PlayActorSound(DUKE_ONWATER, pact); if (p->cursectnum != s->sectnum) @@ -3916,9 +3915,9 @@ HORIZONLY: if (ud.clipping == 0) { if (s->clipdist == 64) - j = (pushmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 128L, (4L << 8), (4L << 8), CLIPMASK0) < 0 && furthestangle(p->GetActor(), 8) < 512); + j = (pushmove(&p->pos, &p->cursectnum, 128L, (4L << 8), (4L << 8), CLIPMASK0) < 0 && furthestangle(p->GetActor(), 8) < 512); else - j = (pushmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 16L, (4L << 8), (4L << 8), CLIPMASK0) < 0 && furthestangle(p->GetActor(), 8) < 512); + j = (pushmove(&p->pos, &p->cursectnum, 16L, (4L << 8), (4L << 8), CLIPMASK0) < 0 && furthestangle(p->GetActor(), 8) < 512); } else j = 0; @@ -3926,8 +3925,8 @@ HORIZONLY: { if (abs(pact->floorz - pact->ceilingz) < (48 << 8) || j) { - if (!(sector[s->sectnum].lotag & 0x8000) && (isanunderoperator(sector[s->sectnum].lotag) || - isanearoperator(sector[s->sectnum].lotag))) + if (!(s->sector()->lotag & 0x8000) && (isanunderoperator(s->sector()->lotag) || + isanearoperator(s->sector()->lotag))) fi.activatebysector(s->sectnum, pact); if (j) { @@ -3939,7 +3938,7 @@ HORIZONLY: fi.activatebysector(psect, pact); } - if (ud.clipping == 0 && sector[p->cursectnum].ceilingz > (sector[p->cursectnum].floorz - (12 << 8))) + if (ud.clipping == 0 && p->cursector()->ceilingz > (p->cursector()->floorz - (12 << 8))) { quickkill(p); return; @@ -3967,7 +3966,7 @@ HORIZONLY: } if (p->recoil && p->kickback_pic == 0) { - short d = p->recoil >> 1; + int d = p->recoil >> 1; if (!d) d = 1; p->recoil -= d; @@ -4043,12 +4042,12 @@ void processmove_r(int snum, ESyncBits actions, int psect, int fz, int cz, int s void OnMotorcycle(struct player_struct *p, DDukeActor* motosprite) { - if (!p->OnMotorcycle && !(sector[p->cursectnum].lotag == 2)) + if (!p->OnMotorcycle && !(p->cursector()->lotag == 2)) { if (motosprite) { - p->posx = motosprite->s->x; - p->posy = motosprite->s->y; + p->pos.x = motosprite->s->x; + p->pos.y = motosprite->s->y; p->angle.ang = buildang(motosprite->s->ang); p->ammo_amount[MOTORCYCLE_WEAPON] = motosprite->saved_ammo; deletesprite(motosprite); @@ -4124,8 +4123,8 @@ void OnBoat(struct player_struct *p, DDukeActor* boat) { if (boat) { - p->posx = boat->s->x; - p->posy = boat->s->y; + p->pos.x = boat->s->x; + p->pos.y = boat->s->y; p->angle.ang = buildang(boat->s->ang); p->ammo_amount[BOAT_WEAPON] = boat->saved_ammo; deletesprite(boat); diff --git a/source/games/duke/src/player_w.cpp b/source/games/duke/src/player_w.cpp index f34758efa..dc83e2667 100644 --- a/source/games/duke/src/player_w.cpp +++ b/source/games/duke/src/player_w.cpp @@ -49,7 +49,7 @@ int operateTripbomb(int snum); // //--------------------------------------------------------------------------- -void DoFire(struct player_struct* p, short snum) +void DoFire(struct player_struct* p, int snum) { int i; @@ -106,7 +106,7 @@ void DoFire(struct player_struct* p, short snum) // //--------------------------------------------------------------------------- -void DoSpawn(struct player_struct *p, short snum) +void DoSpawn(struct player_struct *p, int snum) { if(!aplWeaponSpawn[p->curr_weapon][snum]) return; @@ -342,9 +342,9 @@ void operateweapon_ww(int snum, ESyncBits actions, int psect) } auto j = EGS(p->cursectnum, - p->posx + p->angle.ang.bcos(-6), - p->posy + p->angle.ang.bsin(-6), - p->posz, HEAVYHBOMB, -16, 9, 9, + p->pos.x + p->angle.ang.bcos(-6), + p->pos.y + p->angle.ang.bsin(-6), + p->pos.z, HEAVYHBOMB, -16, 9, 9, p->angle.ang.asbuild(), (k + (p->hbomb_hold_delay << 5)), i, p->GetActor(), 1); { @@ -436,7 +436,7 @@ void operateweapon_ww(int snum, ESyncBits actions, int psect) if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_STANDSTILL && p->kickback_pic < (aplWeaponFireDelay[p->curr_weapon][snum] + 1)) { - p->posz = p->oposz; + p->pos.z = p->oposz; p->poszv = 0; } if (p->kickback_pic == aplWeaponSound2Time[p->curr_weapon][snum]) diff --git a/source/games/duke/src/prediction.cpp b/source/games/duke/src/prediction.cpp index 799ed9aa8..f34738cd7 100644 --- a/source/games/duke/src/prediction.cpp +++ b/source/games/duke/src/prediction.cpp @@ -37,11 +37,11 @@ BEGIN_DUKE_NS int myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel; -short globalskillsound; +int globalskillsound; binangle myang, omyang; fixedhoriz myhoriz, omyhoriz, myhorizoff, omyhorizoff; -short mycursectnum, myjumpingcounter; -char myjumpingtoggle, myonground, myhardlanding,myreturntocenter; +int mycursectnum, myjumpingcounter; +uint8_t myjumpingtoggle, myonground, myhardlanding,myreturntocenter; int fakemovefifoplc; int myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; int myhorizbak[MOVEFIFOSIZ]; @@ -50,9 +50,9 @@ short myangbak[MOVEFIFOSIZ]; void resetmys() { - myx = omyx = ps[myconnectindex].posx; - myy = omyy = ps[myconnectindex].posy; - myz = omyz = ps[myconnectindex].posz; + myx = omyx = ps[myconnectindex].pos.x; + myy = omyy = ps[myconnectindex].pos.y; + myz = omyz = ps[myconnectindex].pos.z; myxvel = myyvel = myzvel = 0; myang = myang = ps[myconnectindex].angle.ang; myhoriz = omyhoriz = ps[myconnectindex].horizon.horiz; @@ -75,12 +75,12 @@ void fakedomovethingscorrect(void) i = ((movefifoplc-1)&(MOVEFIFOSIZ-1)); p = &ps[myconnectindex]; - if (p->posx == myxbak[i] && p->posy == myybak[i] && p->posz == myzbak[i] + if (p->pos.x == myxbak[i] && p->pos.y == myybak[i] && p->pos.z == myzbak[i] && p->horiz == myhorizbak[i] && p->ang == myangbak[i]) return; - myx = p->posx; omyx = p->oposx; myxvel = p->posxv; - myy = p->posy; omyy = p->oposy; myyvel = p->posyv; - myz = p->posz; omyz = p->oposz; myzvel = p->poszv; + myx = p->pos.x; omyx = p->oposx; myxvel = p->posxv; + myy = p->pos.y; omyy = p->oposy; myyvel = p->posyv; + myz = p->pos.z; omyz = p->oposz; myzvel = p->poszv; myang = p->ang; omyang = p->oang; mycursectnum = p->cursectnum; myhoriz = p->horiz; omyhoriz = p->ohoriz; @@ -103,7 +103,7 @@ void fakedomovethings(void) struct player_struct *p; int i, j, k, doubvel, fz, cz, x, y; Collision clz, chz; - short psect, psectlotag, tempsect, backcstat; + int psect, psectlotag, tempsect, backcstat; uint8_t shrunk, spritebridge; ESyncBits actions; diff --git a/source/games/duke/src/prediction.h b/source/games/duke/src/prediction.h index ed31b59eb..2e0e8f29a 100644 --- a/source/games/duke/src/prediction.h +++ b/source/games/duke/src/prediction.h @@ -3,11 +3,11 @@ BEGIN_DUKE_NS extern int myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel; -extern short globalskillsound; -extern short mycursectnum, myjumpingcounter; +extern int globalskillsound; +extern int mycursectnum, myjumpingcounter; extern binangle myang, omyang; extern fixedhoriz myhoriz, omyhoriz, myhorizoff, omyhorizoff; -extern char myjumpingtoggle, myonground, myhardlanding,myreturntocenter; +extern uint8_t myjumpingtoggle, myonground, myhardlanding,myreturntocenter; extern int fakemovefifoplc; extern int myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; extern int myhorizbak[MOVEFIFOSIZ]; diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index e410615a6..7c111c268 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -52,7 +52,7 @@ int which_palookup = 9; void pickrandomspot(int snum) { struct player_struct *p; - short i; + int i; p = &ps[snum]; @@ -60,9 +60,9 @@ void pickrandomspot(int snum) i = krand()%numplayersprites; else i = snum; - p->bobposx = p->oposx = p->posx = po[i].ox; - p->bobposy = p->oposy = p->posy = po[i].oy; - p->oposz = p->posz = po[i].oz; + p->bobposx = p->oposx = p->pos.x = po[i].ox; + p->bobposy = p->oposy = p->pos.y = po[i].oy; + p->oposz = p->pos.z = po[i].oz; p->angle.oang = p->angle.ang = buildang(po[i].oa); p->cursectnum = po[i].os; } @@ -242,7 +242,7 @@ void resetplayerstats(int snum) if (numplayers < 2) { - ufospawn = isRRRA()? 3 : std::min(ud.player_skill*4+1, 32); + ufospawn = isRRRA()? 3 : min(ud.player_skill*4+1, 32); ufocnt = 0; hulkspawn = ud.player_skill + 1; } @@ -262,7 +262,7 @@ void resetplayerstats(int snum) void resetweapons(int snum) { - short weapon; + int weapon; struct player_struct *p; p = &ps[snum]; @@ -278,7 +278,7 @@ void resetweapons(int snum) p->curr_weapon = PISTOL_WEAPON; p->gotweapon[PISTOL_WEAPON] = true; p->gotweapon[KNEE_WEAPON] = true; - p->ammo_amount[PISTOL_WEAPON] = std::min(gs.max_ammo_amount[PISTOL_WEAPON], 48); + p->ammo_amount[PISTOL_WEAPON] = min(gs.max_ammo_amount[PISTOL_WEAPON], 48); p->gotweapon[HANDREMOTE_WEAPON] = true; p->last_weapon = -1; @@ -362,7 +362,7 @@ void resetinventory(int snum) if (numplayers < 2) { - ufospawn = std::min(ud.player_skill*4+1, 32); + ufospawn = min(ud.player_skill*4+1, 32); ufocnt = 0; hulkspawn = ud.player_skill + 1; } @@ -385,7 +385,7 @@ void resetinventory(int snum) void resetprestat(int snum,int g) { struct player_struct *p; - short i; + int i; p = &ps[snum]; @@ -479,7 +479,7 @@ void resetprestat(int snum,int g) if (numplayers < 2) { - ufospawn = std::min(ud.player_skill*4+1, 32); + ufospawn = min(ud.player_skill*4+1, 32); ufocnt = 0; hulkspawn = ud.player_skill + 1; } @@ -501,13 +501,13 @@ void resetprestat(int snum,int g) void resetpspritevars(int g) { int i, j; - short circ; + int circ; int firstx, firsty; spritetype* s; int aimmode[MAXPLAYERS]; STATUSBARTYPE tsbar[MAXPLAYERS]; - EGS(ps[0].cursectnum, ps[0].posx, ps[0].posy, ps[0].posz, + EGS(ps[0].cursectnum, ps[0].pos.x, ps[0].pos.y, ps[0].pos.z, TILE_APLAYER, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, nullptr, 10); if (ud.recstat != 2) for (i = 0; i < MAXPLAYERS; i++) @@ -579,8 +579,8 @@ void resetpspritevars(int g) if (numplayersprites == 0) { - firstx = ps[0].posx; - firsty = ps[0].posy; + firstx = ps[0].pos.x; + firsty = ps[0].pos.y; } po[numplayersprites].ox = s->x; @@ -627,9 +627,9 @@ void resetpspritevars(int g) ps[j].frag_ps = j; act->SetOwner(act); - ps[j].bobposx = ps[j].oposx = ps[j].posx = s->x; - ps[j].bobposy = ps[j].oposy = ps[j].posy = s->y; - ps[j].oposz = ps[j].posz = s->z; + ps[j].bobposx = ps[j].oposx = ps[j].pos.x = s->x; + ps[j].bobposy = ps[j].oposy = ps[j].pos.y = s->y; + ps[j].oposz = ps[j].pos.z = s->z; s->backuppos(); ps[j].angle.oang = ps[j].angle.ang = buildang(s->ang); @@ -692,38 +692,39 @@ void prelevel_common(int g) for (i = 0; i < numsectors; i++) { - sector[i].extra = 256; + auto sectp = §or[i]; + sectp->extra = 256; - switch (sector[i].lotag) + switch (sectp->lotag) { case 20: case 22: - if (sector[i].floorz > sector[i].ceilingz) - sector[i].lotag |= 32768; + if (sectp->floorz > sectp->ceilingz) + sectp->lotag |= 32768; continue; } - if (sector[i].ceilingstat & 1) + if (sectp->ceilingstat & 1) { - //setupbackdrop(sector[i].ceilingpicnum); + //setupbackdrop(sectp->ceilingpicnum); - if (sector[i].ceilingpicnum == TILE_CLOUDYSKIES && numclouds < 127) + if (sectp->ceilingpicnum == TILE_CLOUDYSKIES && numclouds < 127) clouds[numclouds++] = i; if (ps[0].one_parallax_sectnum == -1) ps[0].one_parallax_sectnum = i; } - if (sector[i].lotag == 32767) //Found a secret room + if (sectp->lotag == 32767) //Found a secret room { ps[0].max_secret_rooms++; continue; } - if (sector[i].lotag == -1) + if (sectp->lotag == -1) { - ps[0].exitx = wall[sector[i].wallptr].x; - ps[0].exity = wall[sector[i].wallptr].y; + ps[0].exitx = wall[sectp->wallptr].x; + ps[0].exity = wall[sectp->wallptr].y; continue; } } @@ -886,7 +887,8 @@ static void SpawnPortals() // There is one map where a sector neighboring a portal is not marked as part of the portal itself. for (int i = 0; i < numsectors; i++) { - if (sector[i].floorpicnum == FOF && sector[i].portalflags != PORTAL_SECTOR_FLOOR) + auto sectp = §or[i]; + if (sectp->floorpicnum == FOF && sectp->portalflags != PORTAL_SECTOR_FLOOR) { for (auto& pt : allPortals) { @@ -896,8 +898,8 @@ static void SpawnPortals() { if (findwallbetweensectors(i, t) >= 0) { - sector[i].portalflags = PORTAL_SECTOR_FLOOR; - sector[i].portalnum = uint8_t(1 ^ (&pt - allPortals.Data())); + sectp->portalflags = PORTAL_SECTOR_FLOOR; + sectp->portalnum = uint8_t(1 ^ (&pt - allPortals.Data())); pt.targets.Push(i); goto nexti; } @@ -905,7 +907,7 @@ static void SpawnPortals() } } } - else if (sector[i].ceilingpicnum == FOF && sector[i].portalflags != PORTAL_SECTOR_CEILING) + else if (sectp->ceilingpicnum == FOF && sectp->portalflags != PORTAL_SECTOR_CEILING) { for (auto& pt : allPortals) { @@ -915,8 +917,8 @@ static void SpawnPortals() { if (findwallbetweensectors(i, t) >= 0) { - sector[i].portalflags = PORTAL_SECTOR_CEILING; - sector[i].portalnum = uint8_t(1 ^ (&pt - allPortals.Data())); + sectp->portalflags = PORTAL_SECTOR_CEILING; + sectp->portalnum = uint8_t(1 ^ (&pt - allPortals.Data())); pt.targets.Push(i); goto nexti; } @@ -945,7 +947,9 @@ static int LoadTheMap(MapRecord *mi, struct player_struct *p, int gamemode) } currentLevel = mi; - engineLoadBoard(mi->fileName, isShareware(), &p->pos, &lbang, &p->cursectnum); + int sect; + engineLoadBoard(mi->fileName, isShareware(), &p->pos, &lbang, §);// &p->cursectnum); + p->cursectnum = sect; SECRET_SetMapName(mi->DisplayName(), mi->name); STAT_NewLevel(mi->fileName); diff --git a/source/games/duke/src/premap_d.cpp b/source/games/duke/src/premap_d.cpp index 2d1c9f61a..3c9e3026c 100644 --- a/source/games/duke/src/premap_d.cpp +++ b/source/games/duke/src/premap_d.cpp @@ -246,9 +246,10 @@ void cacheit_d(void) for (i = 0; i < numsectors; i++) { - tloadtile(sector[i].floorpicnum, sector[i].floorpal); - tloadtile(sector[i].ceilingpicnum, sector[i].ceilingpal); - if (sector[i].ceilingpicnum == LA) + auto sectp = §or[i]; + tloadtile(sectp->floorpicnum, sectp->floorpal); + tloadtile(sectp->ceilingpicnum, sectp->ceilingpal); + if (sectp->ceilingpicnum == LA) { tloadtile(LA + 1); tloadtile(LA + 2); @@ -273,7 +274,7 @@ void cacheit_d(void) void prelevel_d(int g) { - short i, j, startwall, endwall, lotaglist; + int i, j, startwall, endwall, lotaglist; short lotags[65]; prelevel_common(g); @@ -292,19 +293,19 @@ void prelevel_d(int g) else switch (si->picnum) { case GPSPEED: - sector[si->sectnum].extra = si->lotag; + si->sector()->extra = si->lotag; deletesprite(ac); break; case CYCLER: if (numcyclers >= MAXCYCLERS) I_Error("Too many cycling sectors."); - cyclers[numcyclers][0] = si->sectnum; - cyclers[numcyclers][1] = si->lotag; - cyclers[numcyclers][2] = si->shade; - cyclers[numcyclers][3] = sector[si->sectnum].floorshade; - cyclers[numcyclers][4] = si->hitag; - cyclers[numcyclers][5] = (si->ang == 1536); + cyclers[numcyclers].sectnum = si->sectnum; + cyclers[numcyclers].lotag = si->lotag; + cyclers[numcyclers].shade1 = si->shade; + cyclers[numcyclers].shade2 = si->sector()->floorshade; + cyclers[numcyclers].hitag = si->hitag; + cyclers[numcyclers].state = (si->ang == 1536); numcyclers++; deletesprite(ac); break; @@ -385,13 +386,14 @@ void prelevel_d(int g) if (wal->overpicnum == MIRROR && (wal->cstat & 32) != 0) { j = wal->nextsector; + auto sectp = §or[j]; if (mirrorcnt > 63) I_Error("Too many mirrors (64 max.)"); - if ((j >= 0) && sector[j].ceilingpicnum != MIRROR) + if ((j >= 0) && sectp->ceilingpicnum != MIRROR) { - sector[j].ceilingpicnum = MIRROR; - sector[j].floorpicnum = MIRROR; + sectp->ceilingpicnum = MIRROR; + sectp->floorpicnum = MIRROR; mirrorwall[mirrorcnt] = i; mirrorsector[mirrorcnt] = j; mirrorcnt++; @@ -409,7 +411,7 @@ void prelevel_d(int g) { case FANSHADOW: case FANSPRITE: - wall->cstat |= 65; + wal->cstat |= 65; animwall[numanimwalls].wallnum = i; numanimwalls++; break; @@ -424,7 +426,7 @@ void prelevel_d(int g) else wal->cstat |= 85 + 256; if (wal->lotag && wal->nextwall >= 0) - wall[wal->nextwall].lotag = wal->lotag; + wal->nextWall()->lotag = wal->lotag; case BIGFORCE: diff --git a/source/games/duke/src/premap_r.cpp b/source/games/duke/src/premap_r.cpp index 4d25e99bc..2a83812fa 100644 --- a/source/games/duke/src/premap_r.cpp +++ b/source/games/duke/src/premap_r.cpp @@ -54,8 +54,8 @@ static inline void tloadtile(int tilenum, int palnum = 0) static void cachespritenum(spritetype *spr) { - char maxc; - short j; + int maxc; + int j; int pal = spr->pal; if (ud.monsters_off && badguy(spr)) return; @@ -328,7 +328,7 @@ static void cachespritenum(spritetype *spr) static void cachegoodsprites(void) { - short i; + int i; tloadtile(BOTTOMSTATUSBAR); if (ud.multimode > 1) @@ -390,9 +390,10 @@ void cacheit_r(void) for (i = 0; i < numsectors; i++) { - tloadtile(sector[i].floorpicnum, sector[i].floorpal); - tloadtile(sector[i].ceilingpicnum, sector[i].ceilingpal); - if (sector[i].ceilingpicnum == LA) + auto sectp = §or[i]; + tloadtile(sectp->floorpicnum, sectp->floorpal); + tloadtile(sectp->ceilingpicnum, sectp->ceilingpal); + if (sectp->ceilingpicnum == LA) { tloadtile(LA + 1); tloadtile(LA + 2); @@ -417,15 +418,15 @@ void cacheit_r(void) void prelevel_r(int g) { struct player_struct* p; - short i; - short j; - short startwall; - short endwall; - short lotaglist; + int i; + int j; + int startwall; + int endwall; + int lotaglist; short lotags[65]; int speed; int dist; - short sound; + int sound; sound = 0; prelevel_common(g); @@ -459,10 +460,11 @@ void prelevel_r(int g) for (i = 0; i < numsectors; i++) { - if (sector[i].ceilingpicnum == RRTILE2577) + auto sectp = §or[i]; + if (sectp->ceilingpicnum == RRTILE2577) thunderon = 1; - switch (sector[i].lotag) + switch (sectp->lotag) { case 41: { @@ -484,18 +486,18 @@ void prelevel_r(int g) } for (j = 0; j < numsectors; j++) { - if (sector[i].hitag == sector[j].hitag && j != i) + if (sectp->hitag == sector[j].hitag && j != i) { // & 32767 to avoid some ordering issues here. // Other code assumes that the lotag is always a sector effector type and can mask the high bit in. - addjaildoor(dist, speed, sector[i].hitag, sector[j].lotag & 32767, sound, j); + addjaildoor(dist, speed, sectp->hitag, sector[j].lotag & 32767, sound, j); } } break; } case 42: { - short ii; + int ii; int childsectnum = -1; DukeSectIterator it(i); while (auto act = it.Next()) @@ -523,7 +525,7 @@ void prelevel_r(int g) deletesprite(act); } } - addminecart(dist, speed, i, sector[i].hitag, sound, childsectnum); + addminecart(dist, speed, i, sectp->hitag, sound, childsectnum); break; } } @@ -547,19 +549,19 @@ void prelevel_r(int g) break; case GPSPEED: - sector[si->sectnum].extra = si->lotag; + si->sector()->extra = si->lotag; deletesprite(ac); break; case CYCLER: if (numcyclers >= MAXCYCLERS) I_Error("Too many cycling sectors."); - cyclers[numcyclers][0] = si->sectnum; - cyclers[numcyclers][1] = si->lotag; - cyclers[numcyclers][2] = si->shade; - cyclers[numcyclers][3] = sector[si->sectnum].floorshade; - cyclers[numcyclers][4] = si->hitag; - cyclers[numcyclers][5] = (si->ang == 1536); + cyclers[numcyclers].sectnum = si->sectnum; + cyclers[numcyclers].lotag = si->lotag; + cyclers[numcyclers].shade1 = si->shade; + cyclers[numcyclers].shade2 = si->sector()->floorshade; + cyclers[numcyclers].hitag = si->hitag; + cyclers[numcyclers].state = (si->ang == 1536); numcyclers++; deletesprite(ac); break; @@ -744,7 +746,7 @@ void prelevel_r(int g) switch (wal->overpicnum) { case FANSPRITE: - wall->cstat |= 65; + wal->cstat |= 65; animwall[numanimwalls].wallnum = i; numanimwalls++; break; diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp index b3f170c86..600609f34 100644 --- a/source/games/duke/src/render.cpp +++ b/source/games/duke/src/render.cpp @@ -64,10 +64,6 @@ BEGIN_DUKE_NS // //--------------------------------------------------------------------------- -/*static*/ int tempsectorz[MAXSECTORS]; -/*static*/ int tempsectorpicnum[MAXSECTORS]; -//short tempcursectnum; - void renderView(spritetype* playersprite, int sectnum, int x, int y, int z, binangle a, fixedhoriz h, binangle rotscrnang, int smoothratio) { if (!testnewrenderer) @@ -77,7 +73,7 @@ void renderView(spritetype* playersprite, int sectnum, int x, int y, int z, bina se40code(x, y, z, a, h, smoothratio); renderMirror(x, y, z, a, h, smoothratio); - renderDrawRoomsQ16(x, y, z, a.asq16(), h.asq16(), sectnum); + renderDrawRoomsQ16(x, y, z, a.asq16(), h.asq16(), sectnum, false); fi.animatesprites(pm_tsprite, pm_spritesortcnt, x, y, a.asbuild(), smoothratio); renderDrawMasks(); } @@ -121,7 +117,7 @@ void GameInterface::UpdateCameras(double smoothratio) if (!testnewrenderer) { // Note: no ROR or camera here - Polymost has no means to detect these things before rendering the scene itself. - renderDrawRoomsQ16(camera->x, camera->y, camera->z, ang.asq16(), IntToFixed(camera->shade), camera->sectnum); // why 'shade'...? + renderDrawRoomsQ16(camera->x, camera->y, camera->z, ang.asq16(), IntToFixed(camera->shade), camera->sectnum, false); // why 'shade'...? fi.animatesprites(pm_tsprite, pm_spritesortcnt, camera->x, camera->y, ang.asbuild(), (int)smoothratio); renderDrawMasks(); } @@ -256,7 +252,7 @@ static int getdrugmode(player_struct *p, int oyrepeat) void displayrooms(int snum, double smoothratio) { int cposx, cposy, cposz, fz, cz; - short sect; + int sect; binangle cang, rotscrnang; fixedhoriz choriz; struct player_struct* p; @@ -322,7 +318,7 @@ void displayrooms(int snum, double smoothratio) cposz = interpolatedvalue(omyz, myz, smoothratio); if (SyncInput()) { - choriz = q16horiz(interpolatedvalue((omyhoriz + omyhorizoff).asq16(), (myhoriz + myhorizoff).asq16(), smoothratio)); + choriz = interpolatedhorizon(omyhoriz + omyhorizoff, myhoriz + myhorizoff, smoothratio); cang = interpolatedangle(omyang, myang, smoothratio); } else @@ -334,9 +330,9 @@ void displayrooms(int snum, double smoothratio) } else { - cposx = interpolatedvalue(p->oposx, p->posx, smoothratio); - cposy = interpolatedvalue(p->oposy, p->posy, smoothratio); - cposz = interpolatedvalue(p->oposz, p->posz, smoothratio);; + cposx = interpolatedvalue(p->oposx, p->pos.x, smoothratio); + cposy = interpolatedvalue(p->oposy, p->pos.y, smoothratio); + cposz = interpolatedvalue(p->oposz, p->pos.z, smoothratio);; if (SyncInput()) { // Original code for when the values are passed through the sync struct diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index f99f049db..924dffe1f 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -84,9 +84,9 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w, { if (arc.BeginObject(keyname)) { - arc("posx", w.posx) - ("posy", w.posy) - ("posz", w.posz) + arc("posx", w.pos.x) + ("posy", w.pos.y) + ("posz", w.pos.z) ("angle", w.angle) ("horizon", w.horizon) .Array("gotweapon", w.gotweapon, MAX_WEAPONS) @@ -253,9 +253,9 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w, .EndObject(); w.invdisptime = 0; - w.oposx = w.posx; - w.oposy = w.posy; - w.oposz = w.posz; + w.oposx = w.pos.x; + w.oposy = w.pos.y; + w.oposz = w.pos.z; w.opyoff = w.pyoff; w.oweapon_sway = w.weapon_sway; w.oweapon_pos = w.weapon_pos; @@ -298,6 +298,23 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DDukeActor& w, DDu return arc; } +FSerializer& Serialize(FSerializer& arc, const char* keyname, Cycler& w, Cycler* def) +{ + static Cycler nul; + if (!def) def = &nul; + if (arc.BeginObject(keyname)) + { + arc("sector", w.sectnum, def->sectnum) + ("lotag", w.lotag, def->lotag) + ("hitag", w.hitag, def->hitag) + ("shade1", w.shade1, def->shade1) + ("shade2", w.shade2, def->shade2) + ("state", w.state, def->state) + .EndObject(); + } + return arc; +} + void GameInterface::SerializeGameState(FSerializer& arc) { @@ -366,7 +383,7 @@ void GameInterface::SerializeGameState(FSerializer& arc) .Array("spriteq", spriteq, 1024) ("numcyclers", numcyclers) - .Array("cyclers", &cyclers[0][0], 6 * numcyclers) + .Array("cycler", cyclers, numcyclers) ("mirrorcnt", mirrorcnt) .Array("mirrorsector", mirrorsector, mirrorcnt) .Array("mirrorwall", mirrorwall, mirrorcnt) diff --git a/source/games/duke/src/sectors.cpp b/source/games/duke/src/sectors.cpp index 8aeb1f6ba..a56580f0f 100644 --- a/source/games/duke/src/sectors.cpp +++ b/source/games/duke/src/sectors.cpp @@ -39,8 +39,6 @@ source as it is released. #include "dukeactor.h" #include "interpolate.h" -using std::min; -using std::max; // PRIMITIVE BEGIN_DUKE_NS @@ -92,7 +90,7 @@ int callsound(int sn, DDukeActor* whatsprite) act->temp_actor = whatsprite; } - if ((sector[si->sectnum].lotag & 0xff) != ST_22_SPLITTING_DOOR) + if ((si->sector()->lotag & 0xff) != ST_22_SPLITTING_DOOR) act->temp_data[0] = 1; } } @@ -216,7 +214,7 @@ bool isanearoperator(int lotag) int findplayer(const DDukeActor* actor, int* d) { - short j, closest_player; + int j, closest_player; int x, closest; auto s = &actor->s->pos; @@ -251,7 +249,7 @@ int findplayer(const DDukeActor* actor, int* d) int findotherplayer(int p, int* d) { - short j, closest_player; + int j, closest_player; int x, closest; closest = 0x7fffffff; @@ -260,7 +258,7 @@ int findotherplayer(int p, int* d) for (j = connecthead; j >= 0; j = connectpoint2[j]) if (p != j && ps[j].GetActor()->s->extra > 0) { - x = abs(ps[j].oposx - ps[p].posx) + abs(ps[j].oposy - ps[p].posy) + (abs(ps[j].oposz - ps[p].posz) >> 4); + x = abs(ps[j].oposx - ps[p].pos.x) + abs(ps[j].oposy - ps[p].pos.y) + (abs(ps[j].oposz - ps[p].pos.z) >> 4); if (x < closest) { @@ -346,10 +344,10 @@ void doanimations(void) { for (p = connecthead; p >= 0; p = connectpoint2[p]) if (ps[p].cursectnum == dasect) - if ((sector[dasect].floorz - ps[p].posz) < (64 << 8)) + if ((sector[dasect].floorz - ps[p].pos.z) < (64 << 8)) if (ps[p].GetActor()->GetOwner() != nullptr) { - ps[p].posz += v; + ps[p].pos.z += v; ps[p].poszv = 0; } @@ -395,7 +393,7 @@ int getanimationgoal(int animtype, int animtarget) // //--------------------------------------------------------------------------- -int setanimation(short animsect, int animtype, int animtarget, int thegoal, int thevel) +int setanimation(int animsect, int animtype, int animtarget, int thegoal, int thevel) { int i, j; @@ -446,7 +444,7 @@ bool activatewarpelevators(DDukeActor* actor, int d) //Parm = sectoreffectornum if (act2->s->lotag == SE_17_WARP_ELEVATOR || (isRRRA() && act2->s->lotag == SE_18_INCREMENTAL_SECTOR_RISE_FALL)) if (act2->s->hitag == actor->s->hitag) if ((abs(sector[sn].floorz - actor->temp_data[2]) > act2->s->yvel) || - (sector[act2->s->sectnum].hitag == (sector[sn].hitag - d))) + (act2->getSector()->hitag == (sector[sn].hitag - d))) break; } @@ -681,7 +679,7 @@ static void handle_st29(int sn, DDukeActor* actor) if ((act2->s->lotag == 22) && (act2->s->hitag == sptr->hitag)) { - sector[act2->s->sectnum].extra = -sector[act2->s->sectnum].extra; + act2->getSector()->extra = -act2->getSector()->extra; act2->temp_data[0] = sn; act2->temp_data[1] = 1; @@ -822,7 +820,7 @@ static void handle_st23(int sn, DDukeActor* actor) } if (!act2) return; - int l = sector[act2->s->sectnum].lotag & 0x8000; + int l = act2->getSector()->lotag & 0x8000; if (act2) { @@ -830,7 +828,7 @@ static void handle_st23(int sn, DDukeActor* actor) while (auto act3 = it.Next()) { - if (l == (sector[act3->s->sectnum].lotag & 0x8000) && act3->s->lotag == SE_11_SWINGING_DOOR && act2->s->hitag == act3->s->hitag && act3->temp_data[4]) + if (l == (act3->getSector()->lotag & 0x8000) && act3->s->lotag == SE_11_SWINGING_DOOR && act2->s->hitag == act3->s->hitag && act3->temp_data[4]) { return; } @@ -839,10 +837,10 @@ static void handle_st23(int sn, DDukeActor* actor) it.Reset(STAT_EFFECTOR); while (auto act3 = it.Next()) { - if (l == (sector[act3->s->sectnum].lotag & 0x8000) && act3->s->lotag == SE_11_SWINGING_DOOR && act2->s->hitag == act3->s->hitag) + if (l == (act3->getSector()->lotag & 0x8000) && act3->s->lotag == SE_11_SWINGING_DOOR && act2->s->hitag == act3->s->hitag) { - if (sector[act3->s->sectnum].lotag & 0x8000) sector[act3->s->sectnum].lotag &= 0x7fff; - else sector[act3->s->sectnum].lotag |= 0x8000; + if (act3->getSector()->lotag & 0x8000) act3->getSector()->lotag &= 0x7fff; + else act3->getSector()->lotag |= 0x8000; act3->temp_data[4] = 1; act3->temp_data[3] = -act3->temp_data[3]; if (q == 0) @@ -883,11 +881,11 @@ static void handle_st25(int sn, DDukeActor* actor) { if (act3->s->lotag == 15) { - sector[act3->s->sectnum].lotag ^= 0x8000; // Toggle the open or close + act3->getSector()->lotag ^= 0x8000; // Toggle the open or close act3->s->ang += 1024; if (act3->temp_data[4]) callsound(act3->s->sectnum, act3); callsound(act3->s->sectnum, act3); - if (sector[act3->s->sectnum].lotag & 0x8000) act3->temp_data[4] = 1; + if (act3->getSector()->lotag & 0x8000) act3->temp_data[4] = 1; else act3->temp_data[4] = 2; } } @@ -983,7 +981,7 @@ void operatesectors(int sn, DDukeActor *actor) case ST_30_ROTATE_RISE_BRIDGE: { - auto act = ScriptIndexToActor(sector[sn].hitag); + auto act = ScriptIndexToActor(sptr->hitag); if (!act) break; if (act->tempang == 0 || act->tempang == 256) callsound(sn, actor); if (act->s->extra == 1) act->s->extra = 3; @@ -993,7 +991,7 @@ void operatesectors(int sn, DDukeActor *actor) case ST_31_TWO_WAY_TRAIN: { - auto act = ScriptIndexToActor(sector[sn].hitag); + auto act = ScriptIndexToActor(sptr->hitag); if (!act) break; if (act->temp_data[4] == 0) act->temp_data[4] = 1; @@ -1079,21 +1077,23 @@ void operatesectors(int sn, DDukeActor *actor) void operateactivators(int low, int plnum) { int i, j, k; - short * p; + Cycler * p; walltype* wal; for (i = numcyclers - 1; i >= 0; i--) { - p = &cyclers[i][0]; + p = &cyclers[i]; - if (p[4] == low) + + if (p->hitag == low) { - p[5] = !p[5]; + auto sect = p->sector(); + p->state = !p->state; - sector[p[0]].floorshade = sector[p[0]].ceilingshade = (int8_t)p[3]; - wal = &wall[sector[p[0]].wallptr]; - for (j = sector[p[0]].wallnum; j > 0; j--, wal++) - wal->shade = (int8_t)p[3]; + sect->floorshade = sect->ceilingshade = (int8_t)p->shade2; + wal = sect->firstWall(); + for (j = sect->wallnum; j > 0; j--, wal++) + wal->shade = (int8_t)p->shade2; } } @@ -1105,11 +1105,11 @@ void operateactivators(int low, int plnum) { if (act->s->picnum == ACTIVATORLOCKED) { - sector[act->s->sectnum].lotag ^= 16384; + act->getSector()->lotag ^= 16384; if (plnum >= 0) { - if (sector[act->s->sectnum].lotag & 16384) + if (act->getSector()->lotag & 16384) FTA(4, &ps[plnum]); else FTA(8, &ps[plnum]); } @@ -1121,20 +1121,20 @@ void operateactivators(int low, int plnum) case 0: break; case 1: - if (sector[act->s->sectnum].floorz != sector[act->s->sectnum].ceilingz) + if (act->getSector()->floorz != act->getSector()->ceilingz) { continue; } break; case 2: - if (sector[act->s->sectnum].floorz == sector[act->s->sectnum].ceilingz) + if (act->getSector()->floorz == act->getSector()->ceilingz) { continue; } break; } - if (sector[act->s->sectnum].lotag < 3) + if (act->getSector()->lotag < 3) { DukeSectIterator it(act->s->sectnum); while (auto a2 = it.Next()) @@ -1153,7 +1153,7 @@ void operateactivators(int low, int plnum) } } - if (k == -1 && (sector[act->s->sectnum].lotag & 0xff) == 22) + if (k == -1 && (act->getSector()->lotag & 0xff) == 22) k = callsound(act->s->sectnum, act); operatesectors(act->s->sectnum, act); @@ -1218,7 +1218,7 @@ void operateforcefields_common(DDukeActor *effector, int low, const std::initial // //--------------------------------------------------------------------------- -void breakwall(short newpn, DDukeActor* spr, short dawallnum) +void breakwall(int newpn, DDukeActor* spr, int dawallnum) { wall[dawallnum].picnum = newpn; S_PlayActorSound(VENT_BUST, spr); @@ -1244,8 +1244,8 @@ void allignwarpelevators(void) { if ((act2->s->lotag) == SE_17_WARP_ELEVATOR && act != act2 && act->s->hitag == act2->s->hitag) { - sector[act2->s->sectnum].floorz = sector[act->s->sectnum].floorz; - sector[act2->s->sectnum].ceilingz = sector[act->s->sectnum].ceilingz; + act2->getSector()->floorz = act->getSector()->floorz; + act2->getSector()->ceilingz = act->getSector()->ceilingz; } } } diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 520d9f25c..c8d63fd84 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -481,7 +481,7 @@ bool checkhitswitch_d(int snum, int ww, DDukeActor *act) return 1; } - vec3_t v = { sx, sy, ps[snum].posz }; + vec3_t v = { sx, sy, ps[snum].pos.z }; switch (picnum) { default: @@ -614,9 +614,7 @@ bool checkhitswitch_d(int snum, int ww, DDukeActor *act) void activatebysector_d(int sect, DDukeActor* activator) { - short didit; - - didit = 0; + int didit = 0; DukeSectIterator it(sect); while (auto act = it.Next()) @@ -641,7 +639,7 @@ void activatebysector_d(int sect, DDukeActor* activator) void checkhitwall_d(DDukeActor* spr, int dawallnum, int x, int y, int z, int atwith) { - short j, sn = -1, darkestwall; + int j, sn = -1, darkestwall; walltype* wal; wal = &wall[dawallnum]; @@ -667,8 +665,8 @@ void checkhitwall_d(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw } if (((wal->cstat & 16) || wal->overpicnum == BIGFORCE) && wal->nextsector >= 0) - if (sector[wal->nextsector].floorz > z) - if (sector[wal->nextsector].floorz - sector[wal->nextsector].ceilingz) + if (wal->nextSector()->floorz > z) + if (wal->nextSector()->floorz - wal->nextSector()->ceilingz) switch (wal->overpicnum) { case W_FORCEFIELD: @@ -701,8 +699,8 @@ void checkhitwall_d(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw wal->cstat &= 65535 - 65; if (wal->nextwall >= 0) { - wall[wal->nextwall].overpicnum = FANSPRITEBROKE; - wall[wal->nextwall].cstat &= 65535 - 65; + wal->nextWall()->overpicnum = FANSPRITEBROKE; + wal->nextWall()->cstat &= 65535 - 65; } S_PlayActorSound(VENT_BUST, spr); S_PlayActorSound(GLASS_BREAKING, spr); @@ -716,7 +714,7 @@ void checkhitwall_d(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw wal->cstat = 0; if (wal->nextwall >= 0) - wall[wal->nextwall].cstat = 0; + wal->nextWall()->cstat = 0; auto spawned = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); spawned->s->lotag = 128; @@ -730,7 +728,7 @@ void checkhitwall_d(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw lotsofcolourglass(spr, dawallnum, 80); wal->cstat = 0; if (wal->nextwall >= 0) - wall[wal->nextwall].cstat = 0; + wal->nextWall()->cstat = 0; S_PlayActorSound(VENT_BUST, spr); S_PlayActorSound(GLASS_BREAKING, spr); return; @@ -925,18 +923,18 @@ void checkplayerhurt_d(struct player_struct* p, const Collision& coll) S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor()); fi.checkhitwall(p->GetActor(), j, - p->posx + p->angle.ang.bcos(-9), - p->posy + p->angle.ang.bsin(-9), - p->posz, -1); + p->pos.x + p->angle.ang.bcos(-9), + p->pos.y + p->angle.ang.bsin(-9), + p->pos.z, -1); break; case BIGFORCE: p->hurt_delay = 26; fi.checkhitwall(p->GetActor(), j, - p->posx + p->angle.ang.bcos(-9), - p->posy + p->angle.ang.bsin(-9), - p->posz, -1); + p->pos.x + p->angle.ang.bcos(-9), + p->pos.y + p->angle.ang.bsin(-9), + p->pos.z, -1); break; } @@ -950,9 +948,10 @@ void checkplayerhurt_d(struct player_struct* p, const Collision& coll) bool checkhitceiling_d(int sn) { + auto sectp = §or[sn]; int j; - switch (sector[sn].ceilingpicnum) + switch (sectp->ceilingpicnum) { case WALLLIGHT1: case WALLLIGHT2: @@ -964,26 +963,26 @@ bool checkhitceiling_d(int sn) ceilingglass(ps[myconnectindex].GetActor(), sn, 10); S_PlayActorSound(GLASS_BREAKING, ps[screenpeek].GetActor()); - if (sector[sn].ceilingpicnum == WALLLIGHT1) - sector[sn].ceilingpicnum = WALLLIGHTBUST1; + if (sectp->ceilingpicnum == WALLLIGHT1) + sectp->ceilingpicnum = WALLLIGHTBUST1; - if (sector[sn].ceilingpicnum == WALLLIGHT2) - sector[sn].ceilingpicnum = WALLLIGHTBUST2; + if (sectp->ceilingpicnum == WALLLIGHT2) + sectp->ceilingpicnum = WALLLIGHTBUST2; - if (sector[sn].ceilingpicnum == WALLLIGHT3) - sector[sn].ceilingpicnum = WALLLIGHTBUST3; + if (sectp->ceilingpicnum == WALLLIGHT3) + sectp->ceilingpicnum = WALLLIGHTBUST3; - if (sector[sn].ceilingpicnum == WALLLIGHT4) - sector[sn].ceilingpicnum = WALLLIGHTBUST4; + if (sectp->ceilingpicnum == WALLLIGHT4) + sectp->ceilingpicnum = WALLLIGHTBUST4; - if (sector[sn].ceilingpicnum == TECHLIGHT2) - sector[sn].ceilingpicnum = TECHLIGHTBUST2; + if (sectp->ceilingpicnum == TECHLIGHT2) + sectp->ceilingpicnum = TECHLIGHTBUST2; - if (sector[sn].ceilingpicnum == TECHLIGHT4) - sector[sn].ceilingpicnum = TECHLIGHTBUST4; + if (sectp->ceilingpicnum == TECHLIGHT4) + sectp->ceilingpicnum = TECHLIGHTBUST4; - if (!sector[sn].hitag) + if (!sectp->hitag) { DukeSectIterator it(sn); while (auto act = it.Next()) @@ -1005,7 +1004,7 @@ bool checkhitceiling_d(int sn) DukeStatIterator it(STAT_EFFECTOR); while (auto act = it.Next()) { - if (act->s->hitag == (sector[sn].hitag) && act->s->lotag == 3) + if (act->s->hitag == (sectp->hitag) && act->s->lotag == 3) { act->temp_data[2] = j; act->temp_data[4] = 1; @@ -1129,8 +1128,8 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) case FANSPRITE: s->picnum = FANSPRITEBROKE; s->cstat &= (65535 - 257); - if (sector[s->sectnum].floorpicnum == FANSHADOW) - sector[s->sectnum].floorpicnum = FANSHADOWBROKE; + if (s->sector()->floorpicnum == FANSHADOW) + s->sector()->floorpicnum = FANSHADOWBROKE; S_PlayActorSound(GLASS_HEAVYBREAK, targ); for (j = 0; j < 16; j++) RANDOMSCRAP(targ); @@ -1150,7 +1149,7 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) if (gs.actorinfo[SHOTSPARK1].scriptaddress && pspr->extra != ScriptCode[gs.actorinfo[SHOTSPARK1].scriptaddress]) { for (j = 0; j < 15; j++) - EGS(s->sectnum, s->x, s->y, sector[s->sectnum].floorz - (12 << 8) - (j << 9), SCRAP1 + (krand() & 15), -8, 64, 64, + EGS(s->sectnum, s->x, s->y, s->sector()->floorz - (12 << 8) - (j << 9), SCRAP1 + (krand() & 15), -8, 64, 64, krand() & 2047, (krand() & 127) + 64, -(krand() & 511) - 256, targ, 5); spawn(targ, EXPLOSION2); deletesprite(targ); @@ -1305,7 +1304,7 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) } { auto j = spawn(targ, STEAM); - j->s->z = sector[s->sectnum].floorz - (32 << 8); + j->s->z = s->sector()->floorz - (32 << 8); } break; @@ -1410,8 +1409,8 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) if ((s->cstat & 48) == 0) s->ang = (pspr->ang + 1024) & 2047; s->xvel = -(pspr->extra << 2); - short j = s->sectnum; - pushmove(&s->x, &s->y, &s->z, &j, 128L, (4 << 8), (4 << 8), CLIPMASK0); + j = s->sectnum; + pushmove(&s->pos, &j, 128L, (4 << 8), (4 << 8), CLIPMASK0); if (j != s->sectnum && j >= 0 && j < MAXSECTORS) changeactorsect(targ, j); } @@ -1454,12 +1453,12 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) if (ps[p].newOwner != nullptr) { ps[p].newOwner = nullptr; - ps[p].posx = ps[p].oposx; - ps[p].posy = ps[p].oposy; - ps[p].posz = ps[p].oposz; + ps[p].pos.x = ps[p].oposx; + ps[p].pos.y = ps[p].oposy; + ps[p].pos.z = ps[p].oposz; ps[p].angle.restore(); - updatesector(ps[p].posx, ps[p].posy, &ps[p].cursectnum); + updatesector(ps[p].pos.x, ps[p].pos.y, &ps[p].cursectnum); DukeStatIterator it(STAT_ACTOR); while (auto j = it.Next()) @@ -1493,37 +1492,37 @@ void checksectors_d(int snum) int i = -1, oldz; struct player_struct* p; int j, hitscanwall; - short neartagsector, neartagwall; + int neartagsector, neartagwall; DDukeActor* neartagsprite; int neartaghitdist; p = &ps[snum]; auto pact = p->GetActor(); - switch (sector[p->cursectnum].lotag) + switch (p->cursector()->lotag) { case 32767: - sector[p->cursectnum].lotag = 0; + p->cursector()->lotag = 0; FTA(9, p); p->secret_rooms++; SECRET_Trigger(p->cursectnum); return; case -1: - sector[p->cursectnum].lotag = 0; + p->cursector()->lotag = 0; setnextmap(false); return; case -2: - sector[p->cursectnum].lotag = 0; + p->cursector()->lotag = 0; p->timebeforeexit = 26 * 8; - p->customexitsound = sector[p->cursectnum].hitag; + p->customexitsound = p->cursector()->hitag; return; default: - if (sector[p->cursectnum].lotag >= 10000 && sector[p->cursectnum].lotag < 16383) + if (p->cursector()->lotag >= 10000 && p->cursector()->lotag < 16383) { if (snum == screenpeek || ud.coop == 1) - S_PlayActorSound(sector[p->cursectnum].lotag - 10000, pact); - sector[p->cursectnum].lotag = 0; + S_PlayActorSound(p->cursector()->lotag - 10000, pact); + p->cursector()->lotag = 0; } break; @@ -1582,14 +1581,14 @@ void checksectors_d(int snum) neartag(p->oposx, p->oposy, p->oposz, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); else { - neartag(p->posx, p->posy, p->posz, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->pos.x, p->pos.y, p->pos.z, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == nullptr && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (8 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->pos.x, p->pos.y, p->pos.z + (8 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == nullptr && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->pos.x, p->pos.y, p->pos.z + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == nullptr && neartagwall == -1 && neartagsector == -1) { - neartag(p->posx, p->posy, p->posz + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); + neartag(p->pos.x, p->pos.y, p->pos.z + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); if (neartagsprite != nullptr) { switch (neartagsprite->s->picnum) @@ -1619,14 +1618,14 @@ void checksectors_d(int snum) } if (p->newOwner == nullptr && neartagsprite == nullptr && neartagsector == -1 && neartagwall == -1) - if (isanunderoperator(sector[p->GetActor()->s->sectnum].lotag)) + if (isanunderoperator(p->GetActor()->getSector()->lotag)) neartagsector = p->GetActor()->s->sectnum; if (neartagsector >= 0 && (sector[neartagsector].lotag & 16384)) return; if (neartagsprite == nullptr && neartagwall == -1) - if (sector[p->cursectnum].lotag == 2) + if (p->cursector()->lotag == 2) { DDukeActor* hit; oldz = hitasprite(p->GetActor(), &hit); @@ -1731,12 +1730,12 @@ void checksectors_d(int snum) if (i < 0) { - p->posx = p->oposx; - p->posy = p->oposy; - p->posz = p->oposz; + p->pos.x = p->oposx; + p->pos.y = p->oposy; + p->pos.z = p->oposz; p->newOwner = nullptr; - updatesector(p->posx, p->posy, &p->cursectnum); + updatesector(p->pos.x, p->pos.y, &p->cursectnum); DukeStatIterator it(STAT_ACTOR); while (auto act = it.Next()) @@ -1788,9 +1787,9 @@ void checksectors_d(int snum) } operatesectors(neartagsector, p->GetActor()); } - else if ((sector[p->GetActor()->s->sectnum].lotag & 16384) == 0) + else if ((p->GetActor()->getSector()->lotag & 16384) == 0) { - if (isanunderoperator(sector[p->GetActor()->s->sectnum].lotag)) + if (isanunderoperator(p->GetActor()->getSector()->lotag)) { DukeSectIterator it(p->GetActor()->s->sectnum); while (auto act = it.Next()) diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 67eec8369..9ba6f577e 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -681,7 +681,7 @@ bool checkhitswitch_r(int snum, int ww, DDukeActor* act) setnextmap(false); } - vec3_t v = { sx, sy, ps[snum].posz }; + vec3_t v = { sx, sy, ps[snum].pos.z }; switch (picnum) { default: @@ -919,10 +919,10 @@ void activatebysector_r(int sect, DDukeActor* activator) // //--------------------------------------------------------------------------- -static void lotsofpopcorn(DDukeActor *actor, short wallnum, short n) +static void lotsofpopcorn(DDukeActor *actor, int wallnum, int n) { int j, xv, yv, z, x1, y1; - short sect, a; + int sect, a; sect = -1; auto sp = actor->s; @@ -976,7 +976,8 @@ static void lotsofpopcorn(DDukeActor *actor, short wallnum, short n) void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atwith) { - short j, i, sn = -1, darkestwall; + int j, i; + int sn = -1, darkestwall; walltype* wal; spritetype* s; @@ -1005,8 +1006,8 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw } if (((wal->cstat & 16) || wal->overpicnum == BIGFORCE) && wal->nextsector >= 0) - if (sector[wal->nextsector].floorz > z) - if (sector[wal->nextsector].floorz - sector[wal->nextsector].ceilingz) + if (wal->nextSector()->floorz > z) + if (wal->nextSector()->floorz - wal->nextSector()->ceilingz) switch (wal->overpicnum) { case FANSPRITE: @@ -1014,8 +1015,8 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw wal->cstat &= 65535 - 65; if (wal->nextwall >= 0) { - wall[wal->nextwall].overpicnum = FANSPRITEBROKE; - wall[wal->nextwall].cstat &= 65535 - 65; + wal->nextWall()->overpicnum = FANSPRITEBROKE; + wal->nextWall()->cstat &= 65535 - 65; } S_PlayActorSound(VENT_BUST, spr); S_PlayActorSound(GLASS_BREAKING, spr); @@ -1029,7 +1030,7 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw wal->cstat = 0; if (wal->nextwall >= 0) - wall[wal->nextwall].cstat = 0; + wal->nextWall()->cstat = 0; auto spawned = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); spawned->s->lotag = 128; @@ -1046,7 +1047,7 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw wal->cstat = 0; if (wal->nextwall >= 0) - wall[wal->nextwall].cstat = 0; + wal->nextWall()->cstat = 0; auto spawned = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); spawned->s->lotag = 128; @@ -1060,7 +1061,7 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw lotsofcolourglass(spr, dawallnum, 80); wal->cstat = 0; if (wal->nextwall >= 0) - wall[wal->nextwall].cstat = 0; + wal->nextWall()->cstat = 0; S_PlayActorSound(VENT_BUST, spr); S_PlayActorSound(GLASS_BREAKING, spr); return; @@ -1079,7 +1080,7 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw int sect; int unk = 0; int startwall, endwall; - sect = wall[wal->nextwall].nextsector; + sect = wal->nextWall()->nextsector; DukeSectIterator it(sect); while (auto act = it.Next()) { @@ -1090,11 +1091,11 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw act->spriteextra++; if (act->spriteextra == 25) { - startwall = sector[s->sectnum].wallptr; - endwall = startwall + sector[s->sectnum].wallnum; + startwall = s->sector()->wallptr; + endwall = startwall + s->sector()->wallnum; for (i = startwall; i < endwall; i++) sector[wall[i].nextsector].lotag = 0; - sector[s->sectnum].lotag = 0; + s->sector()->lotag = 0; S_StopSound(act->s->lotag); S_PlayActorSound(400, act); deletesprite(act); @@ -1416,9 +1417,9 @@ void checkplayerhurt_r(struct player_struct* p, const Collision &coll) case BIGFORCE: p->hurt_delay = 26; fi.checkhitwall(p->GetActor(), j, - p->posx + p->angle.ang.bcos(-9), - p->posy + p->angle.ang.bsin(-9), - p->posz, -1); + p->pos.x + p->angle.ang.bcos(-9), + p->pos.y + p->angle.ang.bsin(-9), + p->pos.z, -1); break; } @@ -1432,9 +1433,10 @@ void checkplayerhurt_r(struct player_struct* p, const Collision &coll) bool checkhitceiling_r(int sn) { - short j; + auto sectp = §or[sn]; + int j; - switch (sector[sn].ceilingpicnum) + switch (sectp->ceilingpicnum) { case WALLLIGHT1: case WALLLIGHT3: @@ -1453,44 +1455,44 @@ bool checkhitceiling_r(int sn) ceilingglass(ps[myconnectindex].GetActor(), sn, 10); S_PlayActorSound(GLASS_BREAKING, ps[screenpeek].GetActor()); - if (sector[sn].ceilingpicnum == WALLLIGHT1) - sector[sn].ceilingpicnum = WALLLIGHTBUST1; + if (sectp->ceilingpicnum == WALLLIGHT1) + sectp->ceilingpicnum = WALLLIGHTBUST1; - if (sector[sn].ceilingpicnum == WALLLIGHT3) - sector[sn].ceilingpicnum = WALLLIGHTBUST3; + if (sectp->ceilingpicnum == WALLLIGHT3) + sectp->ceilingpicnum = WALLLIGHTBUST3; - if (sector[sn].ceilingpicnum == WALLLIGHT4) - sector[sn].ceilingpicnum = WALLLIGHTBUST4; + if (sectp->ceilingpicnum == WALLLIGHT4) + sectp->ceilingpicnum = WALLLIGHTBUST4; - if (sector[sn].ceilingpicnum == TECHLIGHT2) - sector[sn].ceilingpicnum = TECHLIGHTBUST2; + if (sectp->ceilingpicnum == TECHLIGHT2) + sectp->ceilingpicnum = TECHLIGHTBUST2; - if (sector[sn].ceilingpicnum == TECHLIGHT4) - sector[sn].ceilingpicnum = TECHLIGHTBUST4; + if (sectp->ceilingpicnum == TECHLIGHT4) + sectp->ceilingpicnum = TECHLIGHTBUST4; - if (sector[sn].ceilingpicnum == RRTILE1986) - sector[sn].ceilingpicnum = RRTILE1987; + if (sectp->ceilingpicnum == RRTILE1986) + sectp->ceilingpicnum = RRTILE1987; - if (sector[sn].ceilingpicnum == RRTILE1939) - sector[sn].ceilingpicnum = RRTILE2004; + if (sectp->ceilingpicnum == RRTILE1939) + sectp->ceilingpicnum = RRTILE2004; - if (sector[sn].ceilingpicnum == RRTILE1988) - sector[sn].ceilingpicnum = RRTILE2005; + if (sectp->ceilingpicnum == RRTILE1988) + sectp->ceilingpicnum = RRTILE2005; - if (sector[sn].ceilingpicnum == RRTILE2898) - sector[sn].ceilingpicnum = RRTILE2899; + if (sectp->ceilingpicnum == RRTILE2898) + sectp->ceilingpicnum = RRTILE2899; - if (sector[sn].ceilingpicnum == RRTILE2878) - sector[sn].ceilingpicnum = RRTILE2879; + if (sectp->ceilingpicnum == RRTILE2878) + sectp->ceilingpicnum = RRTILE2879; - if (sector[sn].ceilingpicnum == RRTILE2123) - sector[sn].ceilingpicnum = RRTILE2124; + if (sectp->ceilingpicnum == RRTILE2123) + sectp->ceilingpicnum = RRTILE2124; - if (sector[sn].ceilingpicnum == RRTILE2125) - sector[sn].ceilingpicnum = RRTILE2126; + if (sectp->ceilingpicnum == RRTILE2125) + sectp->ceilingpicnum = RRTILE2126; - if (!sector[sn].hitag) + if (!sectp->hitag) { DukeSectIterator it(sn); while (auto act1 = it.Next()) @@ -1514,7 +1516,7 @@ bool checkhitceiling_r(int sn) while (auto act1 = it.Next()) { auto spr1 = act1->s; - if (spr1->hitag == (sector[sn].hitag) && spr1->lotag == 3) + if (spr1->hitag == (sectp->hitag) && spr1->lotag == 3) { act1->temp_data[2] = j; act1->temp_data[4] = 1; @@ -2193,7 +2195,7 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) if (gs.actorinfo[SHOTSPARK1].scriptaddress && pspr->extra != ScriptCode[gs.actorinfo[SHOTSPARK1].scriptaddress]) { for (j = 0; j < 15; j++) - EGS(s->sectnum, s->x, s->y, sector[s->sectnum].floorz - (12 << 8) - (j << 9), SCRAP1 + (krand() & 15), -8, 64, 64, + EGS(s->sectnum, s->x, s->y, s->sector()->floorz - (12 << 8) - (j << 9), SCRAP1 + (krand() & 15), -8, 64, 64, krand() & 2047, (krand() & 127) + 64, -(krand() & 511) - 256, targ, 5); spawn(targ, EXPLOSION2); deletesprite(targ); @@ -2317,7 +2319,7 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) } { auto j = spawn(targ, STEAM); - j->s->z = sector[s->sectnum].floorz - (32 << 8); + j->s->z = s->sector()->floorz - (32 << 8); } break; @@ -2403,11 +2405,11 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) if (ps[p].newOwner != nullptr) { ps[p].newOwner = nullptr; - ps[p].posx = ps[p].oposx; - ps[p].posy = ps[p].oposy; - ps[p].posz = ps[p].oposz; + ps[p].pos.x = ps[p].oposx; + ps[p].pos.y = ps[p].oposy; + ps[p].pos.z = ps[p].oposz; - updatesector(ps[p].posx, ps[p].posy, &ps[p].cursectnum); + updatesector(ps[p].pos.x, ps[p].pos.y, &ps[p].cursectnum); DukeStatIterator it(STAT_EFFECTOR); while (auto act = it.Next()) @@ -2437,24 +2439,24 @@ void checksectors_r(int snum) int i = -1, oldz; struct player_struct* p; int hitscanwall; - short neartagsector, neartagwall; + int neartagsector, neartagwall; DDukeActor* neartagsprite; int neartaghitdist; p = &ps[snum]; auto pact = p->GetActor(); - switch (sector[p->cursectnum].lotag) + switch (p->cursector()->lotag) { case 32767: - sector[p->cursectnum].lotag = 0; + p->cursector()->lotag = 0; FTA(9, p); p->secret_rooms++; SECRET_Trigger(p->cursectnum); return; case -1: - sector[p->cursectnum].lotag = 0; + p->cursector()->lotag = 0; if (!isRRRA() || !RRRA_ExitedLevel) { setnextmap(false); @@ -2462,16 +2464,16 @@ void checksectors_r(int snum) } return; case -2: - sector[p->cursectnum].lotag = 0; + p->cursector()->lotag = 0; p->timebeforeexit = 26 * 8; - p->customexitsound = sector[p->cursectnum].hitag; + p->customexitsound = p->cursector()->hitag; return; default: - if (sector[p->cursectnum].lotag >= 10000) + if (p->cursector()->lotag >= 10000) { if (snum == screenpeek || ud.coop == 1) - S_PlayActorSound(sector[p->cursectnum].lotag - 10000, pact); - sector[p->cursectnum].lotag = 0; + S_PlayActorSound(p->cursector()->lotag - 10000, pact); + p->cursector()->lotag = 0; } break; @@ -2504,7 +2506,7 @@ void checksectors_r(int snum) if (S_CheckActorSoundPlaying(pact, 27) == 0 && S_CheckActorSoundPlaying(pact, 28) == 0 && S_CheckActorSoundPlaying(pact, 29) == 0 && S_CheckActorSoundPlaying(pact, 257) == 0 && S_CheckActorSoundPlaying(pact, 258) == 0) { - short snd = krand() % 5; + int snd = krand() % 5; if (snd == 0) S_PlayActorSound(27, pact); else if (snd == 1) @@ -2553,21 +2555,21 @@ void checksectors_r(int snum) } return; } - neartag(p->posx, p->posy, p->posz, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); + neartag(p->pos.x, p->pos.y, p->pos.z, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); } if (p->newOwner != nullptr) neartag(p->oposx, p->oposy, p->oposz, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); else { - neartag(p->posx, p->posy, p->posz, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->pos.x, p->pos.y, p->pos.z, p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == nullptr && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (8 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->pos.x, p->pos.y, p->pos.z + (8 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == nullptr && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->pos.x, p->pos.y, p->pos.z + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == nullptr && neartagwall == -1 && neartagsector == -1) { - neartag(p->posx, p->posy, p->posz + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); + neartag(p->pos.x, p->pos.y, p->pos.z + (16 << 8), p->GetActor()->s->sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); if (neartagsprite != nullptr) { switch (neartagsprite->s->picnum) @@ -2590,14 +2592,14 @@ void checksectors_r(int snum) } if (p->newOwner == nullptr && neartagsprite == nullptr && neartagsector == -1 && neartagwall == -1) - if (isanunderoperator(sector[p->GetActor()->s->sectnum].lotag)) + if (isanunderoperator(p->GetActor()->getSector()->lotag)) neartagsector = p->GetActor()->s->sectnum; if (neartagsector >= 0 && (sector[neartagsector].lotag & 16384)) return; if (neartagsprite == nullptr && neartagwall == -1) - if (sector[p->cursectnum].lotag == 2) + if (p->cursector()->lotag == 2) { DDukeActor* hit; oldz = hitasprite(p->GetActor(), &hit); @@ -2732,7 +2734,6 @@ void checksectors_r(int snum) if (neartagsector >= 0 && (sector[neartagsector].lotag & 16384) == 0 && isanearoperator(sector[neartagsector].lotag)) { - short unk = 0; DukeSectIterator it(neartagsector); while (auto act = it.Next()) { @@ -2750,9 +2751,9 @@ void checksectors_r(int snum) FTA(41, p); } } - else if ((sector[p->GetActor()->s->sectnum].lotag & 16384) == 0) + else if ((p->GetActor()->getSector()->lotag & 16384) == 0) { - if (isanunderoperator(sector[p->GetActor()->s->sectnum].lotag)) + if (isanunderoperator(p->GetActor()->getSector()->lotag)) { DukeSectIterator it(p->GetActor()->s->sectnum); while (auto act = it.Next()) diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 9f886749d..5ccdd790e 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -244,10 +244,10 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit fn.Substitute(".ogg", ".voc"); sfx->lumpnum = S_LookupSound(fn); } - sndinf[kPitchStart] = clamp(minpitch, INT16_MIN, INT16_MAX); - sndinf[kPitchEnd] = clamp(maxpitch, INT16_MIN, INT16_MAX); + sndinf[kPitchStart] = clamp(minpitch, INT16_MIN, INT16_MAX); + sndinf[kPitchEnd] = clamp(maxpitch, INT16_MIN, INT16_MAX); sndinf[kPriority] = priority & 255; - sndinf[kVolAdjust] = clamp(distance, INT16_MIN, INT16_MAX); + sndinf[kVolAdjust] = clamp(distance, INT16_MIN, INT16_MAX); sndinf[kWorldTourMapping] = 0; sfx->Volume = volume; sfx->NearLimit = 6; @@ -287,7 +287,7 @@ static int GetPositionInfo(DDukeActor* actor, int soundNum, int sectNum, { orgsndist = sndist = int(16 * (sndorg - campos).Length()); - if ((userflags & (SF_GLOBAL | SF_DTAG)) != SF_GLOBAL && sp->picnum == MUSICANDSFX && sp->lotag < 999 && (sector[sp->sectnum].lotag & 0xff) < ST_9_SLIDING_ST_DOOR) + if ((userflags & (SF_GLOBAL | SF_DTAG)) != SF_GLOBAL && sp->picnum == MUSICANDSFX && sp->lotag < 999 && (sp->sector()->lotag & 0xff) < ST_9_SLIDING_ST_DOOR) sndist = DivScale(sndist, sp->hitag + 1, 14); } @@ -491,7 +491,7 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const vec3_t* pos, int channel, bool explosion = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) || ((sndnum == PIPEBOMB_EXPLODE || sndnum == LASERTRIP_EXPLODE || sndnum == RPG_EXPLODE)); - bool underwater = ps[screenpeek].cursectnum > -1 && sector[ps[screenpeek].cursectnum].lotag == ST_2_UNDERWATER; + bool underwater = ps[screenpeek].cursectnum > -1 && ps[screenpeek].cursector()->lotag == ST_2_UNDERWATER; if (explosion) { if (underwater) @@ -642,7 +642,7 @@ int S_CheckSoundPlaying(int soundNum) void S_MenuSound(void) { static int menunum; - static const short menusnds[] = + static const uint16_t menusnds[] = { LASERTRIP_EXPLODE, DUKE_GRUNT, diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index 1c909aaa7..4977e8439 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -49,7 +49,7 @@ BEGIN_DUKE_NS // //--------------------------------------------------------------------------- -DDukeActor* EGS(short whatsect, int s_x, int s_y, int s_z, short s_pn, signed char s_s, signed char s_xr, signed char s_yr, short s_a, short s_ve, int s_zv, DDukeActor* s_ow, signed char s_ss) +DDukeActor* EGS(int whatsect, int s_x, int s_y, int s_z, int s_pn, int8_t s_s, int8_t s_xr, int8_t s_yr, int s_a, int s_ve, int s_zv, DDukeActor* s_ow, int8_t s_ss) { int const i = insertsprite(whatsect, s_ss); @@ -168,8 +168,8 @@ int initspriteforspawn(DDukeActor* actj, int pn, const std::initializer_listmovflag = 0; act->tempang = 0; act->dispicnum = 0; - act->floorz = sector[sp->sectnum].floorz; - act->ceilingz = sector[sp->sectnum].ceilingz; + act->floorz = sp->sector()->floorz; + act->ceilingz = sp->sector()->ceilingz; act->lastvx = 0; act->lastvy = 0; @@ -306,7 +306,7 @@ void spawntransporter(DDukeActor *actj, DDukeActor* acti, bool beam) { sp->xrepeat = 31; sp->yrepeat = 1; - sp->z = sector[spj->sectnum].floorz - (isRR() ? PHEIGHT_RR : PHEIGHT_DUKE); + sp->z = spj->sector()->floorz - (isRR() ? PHEIGHT_RR : PHEIGHT_DUKE); } else { @@ -343,19 +343,19 @@ void spawntransporter(DDukeActor *actj, DDukeActor* acti, bool beam) int spawnbloodpoolpart1(DDukeActor *actj, DDukeActor* acti) { auto sp = acti->s; - short s1 = sp->sectnum; + int s1 = sp->sectnum; updatesector(sp->x + 108, sp->y + 108, &s1); - if (s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz == sp->sector()->floorz) { updatesector(sp->x - 108, sp->y - 108, &s1); - if (s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz == sp->sector()->floorz) { updatesector(sp->x + 108, sp->y - 108, &s1); - if (s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz == sp->sector()->floorz) { updatesector(sp->x - 108, sp->y + 108, &s1); - if (s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz != sp->sector()->floorz) { sp->xrepeat = sp->yrepeat = 0; changeactorstat(acti, STAT_MISC); return true; } @@ -366,7 +366,7 @@ int spawnbloodpoolpart1(DDukeActor *actj, DDukeActor* acti) } else { sp->xrepeat = sp->yrepeat = 0; changeactorstat(acti, STAT_MISC); return true; } - if (sector[sp->sectnum].lotag == 1) + if (sp->sector()->lotag == 1) { changeactorstat(acti, STAT_MISC); return true; @@ -386,20 +386,19 @@ void initfootprint(DDukeActor* actj, DDukeActor* acti) int sect = sp->sectnum; if (actj) { - short s1; - s1 = sp->sectnum; + int s1 = sp->sectnum; updatesector(sp->x + 84, sp->y + 84, &s1); - if (s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz == sp->sector()->floorz) { updatesector(sp->x - 84, sp->y - 84, &s1); - if (s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz == sp->sector()->floorz) { updatesector(sp->x + 84, sp->y - 84, &s1); - if (s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz == sp->sector()->floorz) { updatesector(sp->x - 84, sp->y + 84, &s1); - if (s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz) + if (s1 >= 0 && sector[s1].floorz != sp->sector()->floorz) { sp->xrepeat = sp->yrepeat = 0; changeactorstat(acti, STAT_MISC); return; } @@ -436,7 +435,7 @@ void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell) if (actj) { auto spj = actj->s; - short snum, a; + int snum, a; if (spj->picnum == TILE_APLAYER) { @@ -444,7 +443,7 @@ void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell) a = ps[snum].angle.ang.asbuild() - (krand() & 63) + 8; //Fine tune t[0] = krand() & 1; - sp->z = (3 << 8) + ps[snum].pyoff + ps[snum].posz - (ps[snum].horizon.sum().asq16() >> 12) + (!isshell ? (3 << 8) : 0); + sp->z = (3 << 8) + ps[snum].pyoff + ps[snum].pos.z - (ps[snum].horizon.sum().asq16() >> 12) + (!isshell ? (3 << 8) : 0); sp->zvel = -(krand() & 255); } else @@ -549,7 +548,7 @@ void initwaterdrip(DDukeActor* actj, DDukeActor* actor) sp->z -= (18 << 8); } else sp->z -= (13 << 8); - sp->ang = getangle(ps[connecthead].posx - sp->x, ps[connecthead].posy - sp->y); + sp->ang = getangle(ps[connecthead].pos.x - sp->x, ps[connecthead].pos.y - sp->y); sp->xvel = 48 - (krand() & 31); ssp(actor, CLIPMASK0); } @@ -622,11 +621,12 @@ int initreactor(DDukeActor* actj, DDukeActor* actor, bool isrecon) void spawneffector(DDukeActor* actor) { auto sp = actor->s; + auto sectp = sp->sector(); int sect = sp->sectnum; auto t = actor->temp_data; int startwall, endwall, x, y, d, s, clostest; - sp->yvel = sector[sect].extra; + sp->yvel = sectp->extra; sp->cstat |= 32768; sp->xrepeat = sp->yrepeat = 0; @@ -652,7 +652,7 @@ void spawneffector(DDukeActor* actor) } else actor->SetOwner(actor); - t[4] = sector[sect].floorz == sp->z; + t[4] = sectp->floorz == sp->z; sp->cstat = 0; changeactorstat(actor, STAT_TRANSPORT); return; @@ -664,15 +664,15 @@ void spawneffector(DDukeActor* actor) if (sp->ang == 512) { - t[1] = sector[sect].ceilingz; + t[1] = sectp->ceilingz; if (sp->pal) - sector[sect].ceilingz = sp->z; + sectp->ceilingz = sp->z; } else { - t[1] = sector[sect].floorz; + t[1] = sectp->floorz; if (sp->pal) - sector[sect].floorz = sp->z; + sectp->floorz = sp->z; } sp->hitag <<= 2; @@ -684,17 +684,17 @@ void spawneffector(DDukeActor* actor) case SE_25_PISTON: // Pistons if (!isRR()) { - t[3] = sector[sect].ceilingz; + t[3] = sectp->ceilingz; t[4] = 1; } else - t[4] = sector[sect].ceilingz; + t[4] = sectp->ceilingz; - sector[sect].ceilingz = sp->z; + sectp->ceilingz = sp->z; StartInterpolation(sect, Interp_Sect_Ceilingz); break; case SE_35: - sector[sect].ceilingz = sp->z; + sectp->ceilingz = sp->z; break; case SE_27_DEMO_CAM: if (ud.recstat == 1) @@ -708,14 +708,14 @@ void spawneffector(DDukeActor* actor) if (!isRRRA()) break; case SE_12_LIGHT_SWITCH: - t[1] = sector[sect].floorshade; - t[2] = sector[sect].ceilingshade; + t[1] = sectp->floorshade; + t[2] = sectp->ceilingshade; break; case SE_13_EXPLOSIVE: { - t[0] = sector[sect].ceilingz; - t[1] = sector[sect].floorz; + t[0] = sectp->ceilingz; + t[1] = sectp->floorz; bool ceiling = (abs(t[0] - sp->z) < abs(t[1] - sp->z)); actor->spriteextra = ceiling; @@ -723,40 +723,40 @@ void spawneffector(DDukeActor* actor) if (sp->ang == 512) { if (ceiling) - sector[sect].ceilingz = sp->z; + sectp->ceilingz = sp->z; else - sector[sect].floorz = sp->z; + sectp->floorz = sp->z; } else - sector[sect].ceilingz = sector[sect].floorz = sp->z; + sectp->ceilingz = sectp->floorz = sp->z; - if (sector[sect].ceilingstat & 1) + if (sectp->ceilingstat & 1) { - sector[sect].ceilingstat ^= 1; + sectp->ceilingstat ^= 1; t[3] = 1; if (!ceiling && sp->ang == 512) { - sector[sect].ceilingstat ^= 1; + sectp->ceilingstat ^= 1; t[3] = 0; } - sector[sect].ceilingshade = - sector[sect].floorshade; + sectp->ceilingshade = + sectp->floorshade; if (sp->ang == 512) { - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (int j = startwall; j < endwall; j++) { int x = wall[j].nextsector; if (x >= 0) if (!(sector[x].ceilingstat & 1)) { - sector[sect].ceilingpicnum = + sectp->ceilingpicnum = sector[x].ceilingpicnum; - sector[sect].ceilingshade = + sectp->ceilingshade = sector[x].ceilingshade; break; //Leave earily } @@ -768,12 +768,12 @@ void spawneffector(DDukeActor* actor) } case SE_17_WARP_ELEVATOR: { - t[2] = sector[sect].floorz; //Stopping loc + t[2] = sectp->floorz; //Stopping loc - int j = nextsectorneighborz(sect, sector[sect].floorz, -1, -1); + int j = nextsectorneighborz(sect, sectp->floorz, -1, -1); t[3] = sector[j].ceilingz; - j = nextsectorneighborz(sect, sector[sect].ceilingz, 1, 1); + j = nextsectorneighborz(sect, sectp->ceilingz, 1, 1); t[4] = sector[j].floorz; if (numplayers < 2) @@ -801,8 +801,8 @@ void spawneffector(DDukeActor* actor) { int q; - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; //find the two most clostest wall x's and y's q = 0x7fffffff; @@ -846,17 +846,17 @@ void spawneffector(DDukeActor* actor) case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT: - t[3] = sector[sect].floorshade; + t[3] = sectp->floorshade; - sector[sect].floorshade = sp->shade; - sector[sect].ceilingshade = sp->shade; + sectp->floorshade = sp->shade; + sectp->ceilingshade = sp->shade; - actor->palvals = (sector[sect].ceilingpal << 8) | sector[sect].floorpal; + actor->palvals = (sectp->ceilingpal << 8) | sectp->floorpal; //fix all the walls; - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (s = startwall; s < endwall; s++) { @@ -868,12 +868,12 @@ void spawneffector(DDukeActor* actor) break; case SE_31_FLOOR_RISE_FALL: - t[1] = sector[sect].floorz; + t[1] = sectp->floorz; // t[2] = sp->hitag; - if (sp->ang != 1536) sector[sect].floorz = sp->z; + if (sp->ang != 1536) sectp->floorz = sp->z; - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (s = startwall; s < endwall; s++) if (wall[s].hitag == 0) wall[s].hitag = 9999; @@ -882,12 +882,12 @@ void spawneffector(DDukeActor* actor) break; case SE_32_CEILING_RISE_FALL: - t[1] = sector[sect].ceilingz; + t[1] = sectp->ceilingz; t[2] = sp->hitag; - if (sp->ang != 1536) sector[sect].ceilingz = sp->z; + if (sp->ang != 1536) sectp->ceilingz = sp->z; - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (s = startwall; s < endwall; s++) if (wall[s].hitag == 0) wall[s].hitag = 9999; @@ -898,12 +898,12 @@ void spawneffector(DDukeActor* actor) case SE_4_RANDOM_LIGHTS: //Flashing lights - t[2] = sector[sect].floorshade; + t[2] = sectp->floorshade; - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; - actor->palvals = (sector[sect].ceilingpal << 8) | sector[sect].floorpal; + actor->palvals = (sectp->ceilingpal << 8) | sectp->floorpal; for (s = startwall; s < endwall; s++) if (wall[s].shade > t[3]) @@ -912,17 +912,17 @@ void spawneffector(DDukeActor* actor) break; case SE_9_DOWN_OPEN_DOOR_LIGHTS: - if (sector[sect].lotag && - labs(sector[sect].ceilingz - sp->z) > 1024) - sector[sect].lotag |= 32768; //If its open + if (sectp->lotag && + labs(sectp->ceilingz - sp->z) > 1024) + sectp->lotag |= 32768; //If its open case SE_8_UP_OPEN_DOOR_LIGHTS: //First, get the ceiling-floor shade - t[0] = sector[sect].floorshade; - t[1] = sector[sect].ceilingshade; + t[0] = sectp->floorshade; + t[1] = sectp->ceilingshade; - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (s = startwall; s < endwall; s++) if (wall[s].shade > t[2]) @@ -936,11 +936,11 @@ void spawneffector(DDukeActor* actor) //First, get the ceiling-floor shade if (!isRR()) break; - t[0] = sector[sect].floorshade; - t[1] = sector[sect].ceilingshade; + t[0] = sectp->floorshade; + t[1] = sectp->ceilingshade; - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; for (s = startwall; s < endwall; s++) if (wall[s].shade > t[2]) @@ -964,12 +964,12 @@ void spawneffector(DDukeActor* actor) if (sp->lotag == 0) { - if (sector[sect].lotag == 30) + if (sectp->lotag == 30) { if (sp->pal) sp->clipdist = 1; else sp->clipdist = 0; - t[3] = sector[sect].floorz; - sector[sect].hitag = ActorToScriptIndex(actor); + t[3] = sectp->floorz; + sectp->hitag = ActorToScriptIndex(actor); } DukeLinearSpriteIterator it; @@ -1003,8 +1003,8 @@ void spawneffector(DDukeActor* actor) } } - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; t[1] = tempwallptr; for (s = startwall; s < endwall; s++) @@ -1020,14 +1020,14 @@ void spawneffector(DDukeActor* actor) if (sp->lotag == SE_30_TWO_WAY_TRAIN || sp->lotag == SE_6_SUBWAY || sp->lotag == SE_14_SUBWAY_CAR || sp->lotag == SE_5_BOSS) { - startwall = sector[sect].wallptr; - endwall = startwall + sector[sect].wallnum; + startwall = sectp->wallptr; + endwall = startwall + sectp->wallnum; - if (sector[sect].hitag == -1) + if (sectp->hitag == -1) sp->extra = 0; else sp->extra = 1; - sector[sect].hitag = ActorToScriptIndex(actor); + sectp->hitag = ActorToScriptIndex(actor); int j = 0; @@ -1056,13 +1056,13 @@ void spawneffector(DDukeActor* actor) } else if (sp->lotag == SE_16_REACTOR) - t[3] = sector[sect].ceilingz; + t[3] = sectp->ceilingz; else if (sp->lotag == SE_26) { t[3] = sp->x; t[4] = sp->y; - if (sp->shade == sector[sect].floorshade) //UP + if (sp->shade == sectp->floorshade) //UP sp->zvel = -256; else sp->zvel = 256; @@ -1071,8 +1071,8 @@ void spawneffector(DDukeActor* actor) } else if (sp->lotag == SE_2_EARTHQUAKE) { - t[5] = sector[sp->sectnum].floorheinum; - sector[sp->sectnum].floorheinum = 0; + t[5] = sp->sector()->floorheinum; + sp->sector()->floorheinum = 0; } } @@ -1085,7 +1085,7 @@ void spawneffector(DDukeActor* actor) if (j == -1) { if (!isRR()) j = SUBWAY; // Duke - else if (sector[sp->sectnum].floorpal == 7) j = 456; + else if (sp->sector()->floorpal == 7) j = 456; else j = 75; } actor->lastvx = j; @@ -1125,7 +1125,7 @@ void spawneffector(DDukeActor* actor) void lotsofglass(DDukeActor *actor, int wallnum, int n) { int j, xv, yv, z, x1, y1, a; - short sect; + int sect; auto sp = actor->s; sect = -1; @@ -1233,7 +1233,7 @@ void ceilingglass(DDukeActor* actor, int sectnum, int n) void lotsofcolourglass(DDukeActor* actor, int wallnum, int n) { int j, xv, yv, z, x1, y1; - short sect = -1; + int sect = -1; int a;; auto sp = actor->s; diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index e50961f8c..8b2b4df91 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -54,6 +54,7 @@ int spawn_d(int j, int pn) auto spj = j < 0 ? nullptr : actj->s; auto t = act->temp_data; int sect = sp->sectnum; + auto sectp = sp->sector(); if (isWorldTour()) @@ -166,17 +167,17 @@ int spawn_d(int j, int pn) sp->cstat |= 128; if(j >= 0) { - if(sector[spj->sectnum].lotag == 2) + if(spj->sector()->lotag == 2) { sp->z = getceilzofslope(sp->sectnum,sp->x,sp->y)+(16<<8); sp->cstat |= 8; } - else if( sector[spj->sectnum].lotag == 1) + else if( spj->sector()->lotag == 1) sp->z = getflorzofslope(sp->sectnum,sp->x,sp->y); } - if(sector[sect].floorpicnum == FLOORSLIME || - sector[sect].ceilingpicnum == FLOORSLIME) + if(sectp->floorpicnum == FLOORSLIME || + sectp->ceilingpicnum == FLOORSLIME) sp->pal = 7; case NEON1: case NEON2: @@ -258,7 +259,7 @@ int spawn_d(int j, int pn) case FORCESPHERE: if(j == -1 ) { - sp->cstat = (short) 32768; + sp->cstat = 32768; changespritestat(i,2); } else @@ -582,7 +583,7 @@ int spawn_d(int j, int pn) changespritestat(i, STAT_MISC); break; } - sp->cstat = (short)32768; + sp->cstat = 32768; changespritestat(i,11); break; @@ -655,7 +656,7 @@ int spawn_d(int j, int pn) sp->xrepeat = spj->xrepeat; sp->yrepeat = spj->yrepeat; sp->zvel = 128; - if(sector[sp->sectnum].lotag != 2) + if(sp->sector()->lotag != 2) sp->cstat |= 32768; } changespritestat(i, STAT_DUMMYPLAYER); @@ -711,9 +712,9 @@ int spawn_d(int j, int pn) changespritestat(i,6); break; case TOUCHPLATE: - t[2] = sector[sect].floorz; - if(sector[sect].lotag != 1 && sector[sect].lotag != 2) - sector[sect].floorz = sp->z; + t[2] = sectp->floorz; + if(sectp->lotag != 1 && sectp->lotag != 2) + sectp->floorz = sp->z; if (!isWorldTour()) { if (sp->pal && ud.multimode > 1) @@ -900,9 +901,9 @@ int spawn_d(int j, int pn) case ACTIVATORLOCKED: case ACTIVATOR: - sp->cstat = (short) 32768; + sp->cstat = 32768; if(sp->picnum == ACTIVATORLOCKED) - sector[sp->sectnum].lotag |= 16384; + sp->sector()->lotag |= 16384; changespritestat(i,8); break; @@ -1110,7 +1111,7 @@ int spawn_d(int j, int pn) sp->shade = -16; if(sp->xrepeat <= 8) { - sp->cstat = (short)32768; + sp->cstat = 32768; sp->xrepeat=sp->yrepeat=0; } else sp->cstat = 1+256; diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index 46acf8686..18c4087ee 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -49,6 +49,7 @@ int spawn_r(int j, int pn) auto spj = j < 0? nullptr : actj->s; auto t = act->temp_data; int sect = sp->sectnum; + auto sectp = sp->sector(); switch(sp->picnum) { @@ -221,17 +222,17 @@ int spawn_r(int j, int pn) sp->cstat |= 128; if (j >= 0) { - if (sector[spj->sectnum].lotag == 2) + if (spj->sector()->lotag == 2) { sp->z = getceilzofslope(sp->sectnum, sp->x, sp->y) + (16 << 8); sp->cstat |= 8; } - else if (sector[spj->sectnum].lotag == 1) + else if (spj->sector()->lotag == 1) sp->z = getflorzofslope(sp->sectnum, sp->x, sp->y); } - if(sector[sect].floorpicnum == FLOORSLIME || - sector[sect].ceilingpicnum == FLOORSLIME) + if(sectp->floorpicnum == FLOORSLIME || + sectp->ceilingpicnum == FLOORSLIME) sp->pal = 7; case NEON1: case NEON2: @@ -321,7 +322,7 @@ int spawn_r(int j, int pn) case FORCESPHERE: if (j == -1) { - sp->cstat = (short)32768; + sp->cstat = 32768; changespritestat(i,2); } else @@ -603,16 +604,13 @@ int spawn_r(int j, int pn) changespritestat(i, STAT_MISC); break; } - sp->cstat = (short)32768; + sp->cstat = 32768; changespritestat(i,11); break; case SOUNDFX: { - short tg; sp->cstat |= 32768; changespritestat(i,2); - tg = sp->hitag; - tg = sp->lotag; } break; case EXPLOSION2: @@ -668,7 +666,7 @@ int spawn_r(int j, int pn) sp->xrepeat = spj->xrepeat; sp->yrepeat = spj->yrepeat; sp->zvel = 128; - if(sector[sp->sectnum].lotag != 2) + if(sp->sector()->lotag != 2) sp->cstat |= 32768; } changespritestat(i,13); @@ -718,9 +716,9 @@ int spawn_r(int j, int pn) changespritestat(i,6); break; case TOUCHPLATE: - t[2] = sector[sect].floorz; - if(sector[sect].lotag != 1 && sector[sect].lotag != 2) - sector[sect].floorz = sp->z; + t[2] = sectp->floorz; + if(sectp->lotag != 1 && sectp->lotag != 2) + sectp->floorz = sp->z; if(sp->pal && ud.multimode > 1) { sp->xrepeat=sp->yrepeat=0; @@ -1071,7 +1069,7 @@ int spawn_r(int j, int pn) // sp->xrepeat=sp->yrepeat=0; sp->cstat |= 32768; if (sp->picnum == ACTIVATORLOCKED) - sector[sect].lotag ^= 16384; + sectp->lotag ^= 16384; changeactorstat(act, STAT_ACTIVATOR); break; case DOORSHOCK: @@ -1314,7 +1312,7 @@ int spawn_r(int j, int pn) sp->yrepeat = 16; break; } - sp->shade = sector[sp->sectnum].floorshade; + sp->shade = sp->sector()->floorshade; break; case WATERFOUNTAIN: sp->lotag = 1; @@ -1370,7 +1368,7 @@ int spawn_r(int j, int pn) sp->shade = -16; if(sp->xrepeat <= 8) { - sp->cstat = (short)32768; + sp->cstat = 32768; sp->xrepeat=sp->yrepeat=0; } else sp->cstat = 1+256; diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 9256a53e5..d83760e95 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -13,7 +13,7 @@ struct STATUSBARTYPE { short frag[MAXPLAYERS], got_access, last_extra, shield_amount, curr_weapon; short ammo_amount[MAX_WEAPONS]; - unsigned char inven_icon, jetpack_on, heat_on; + uint8_t inven_icon, jetpack_on, heat_on; short firstaid_amount, steroids_amount, holoduke_amount, jetpack_amount; short heat_amount, scuba_amount, boot_amount; short last_weapon, weapon_pos, kickback_pic; @@ -24,7 +24,8 @@ struct DDukeActor { uint8_t cgg; uint8_t spriteextra; // moved here for easier maintenance. This was originally a hacked in field in the sprite structure called 'filler'. - short picnum, ang, extra, owner, movflag; + short owner; // todo: make a pointer. + short picnum, ang, extra, movflag; short tempang, actorstayput, dispicnum; short timetosleep; int floorz, ceilingz, lastvx, lastvy, aflags; @@ -90,6 +91,10 @@ struct DDukeActor return s->yvel; } + sectortype* getSector() const + { + return §or[s->sectnum]; + } }; @@ -98,7 +103,7 @@ inline DDukeActor* DDukeActor::array() { return hittype; } struct animwalltype { - short wallnum, tag; + int wallnum, tag; }; // Todo - put more state in here @@ -120,9 +125,9 @@ struct TileInfo struct user_defs { - unsigned char god, cashman, eog; - unsigned char clipping; - unsigned char user_pals[MAXPLAYERS]; + uint8_t god, cashman, eog; + uint8_t clipping; + uint8_t user_pals[MAXPLAYERS]; short from_bonus; short last_level, secretlevel; @@ -156,11 +161,7 @@ struct player_struct // This is basically the version from JFDuke but this first block contains a few changes to make it work with other parts of Raze. // The sound code wants to read a vector out of this so we need to define one for the main coordinate. - union - { - vec3_t pos; - struct { int32_t posx, posy, posz; }; - }; + vec3_t pos; // player's horizon and angle structs. PlayerHorizon horizon; @@ -181,8 +182,8 @@ struct player_struct int oweapon_sway; short weapon_pos, kickback_pic, random_club_frame; short oweapon_pos, okickback_pic, orandom_club_frame; - unsigned char hard_landing; - unsigned char ohard_landing; + uint8_t hard_landing; + uint8_t ohard_landing; // Store current psectlotag as determined in processinput() for use with scaling angle aiming. short psectlotag; @@ -198,15 +199,17 @@ struct player_struct int aim_mode, ftt; - short cursectnum, last_extra, subweapon; + int cursectnum, one_parallax_sectnum, access_wallnum; // wall + sector references. Make them pointers later? + + short last_extra, subweapon; short ammo_amount[MAX_WEAPONS], frag, fraggedself; short curr_weapon, last_weapon, tipincs, wantweaponfire; short holoduke_amount, hurt_delay, hbomb_hold_delay; short jumping_counter, airleft, knee_incs, access_incs; - short ftq, access_wallnum; + short ftq; short got_access, weapon_ang, firstaid_amount; - short i, one_parallax_sectnum; + short i; short over_shoulder_on, fist_incs; short cheat_phase; short extra_extra8, quick_kick, last_quick_kick; @@ -221,20 +224,20 @@ struct player_struct short pycount, frag_ps; short transporter_hold, last_full_weapon, footprintshade, boot_amount; - unsigned char on_warping_sector, footprintcount; - unsigned char hbomb_on, jumping_toggle, rapid_fire_hold, on_ground; + uint8_t on_warping_sector, footprintcount; + uint8_t hbomb_on, jumping_toggle, rapid_fire_hold, on_ground; char name[32]; - unsigned char inven_icon, buttonpalette; + uint8_t inven_icon, buttonpalette; - unsigned char jetpack_on, spritebridge, lastrandomspot; - unsigned char scuba_on, footprintpal, heat_on; + uint8_t jetpack_on, spritebridge, lastrandomspot; + uint8_t scuba_on, footprintpal, heat_on; - unsigned char holster_weapon; - unsigned char falling_counter; - unsigned char refresh_inventory; + uint8_t holster_weapon; + uint8_t falling_counter; + uint8_t refresh_inventory; - unsigned char toggle_key_flag, knuckle_incs; // ,select_dir; - unsigned char walking_snd_toggle, palookup; + uint8_t toggle_key_flag, knuckle_incs; // ,select_dir; + uint8_t walking_snd_toggle, palookup; bool quick_kick_msg; int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed; @@ -291,7 +294,28 @@ struct player_struct return (psectlotag == ST_2_UNDERWATER)? avel * 0.875f : avel; } + sectortype* cursector() const + { + return &::sector[cursectnum]; + } + sectortype* one_parallax_sector() const + { + return &::sector[one_parallax_sectnum]; + } + +}; + +struct Cycler +{ + int sectnum; + int16_t lotag; + int16_t hitag; + int16_t shade1; + int16_t shade2; + bool state; + + sectortype* sector() const { return &::sector[sectnum]; } }; // Wrapper around the insane collision info mess from Build. @@ -302,6 +326,11 @@ struct Collision int legacyVal; // should be removed later, but needed for converting back for unadjusted code. DDukeActor* actor; + Collision() = default; + explicit Collision(int v) + { + setFromEngine(v); + } int setNone() { type = kHitNone; @@ -345,6 +374,19 @@ struct Collision else { index = -1; actor = &hittype[value & kHitIndexMask]; } return type; } + + walltype* wall() const + { + assert(type == kHitWall); + return &::wall[index]; + } + + sectortype* sector() const + { + assert(type == kHitSector); + return &::sector[index]; + } + }; diff --git a/source/games/exhumed/all.cpp b/source/games/exhumed/all.cpp index 677466495..9df6c0d08 100644 --- a/source/games/exhumed/all.cpp +++ b/source/games/exhumed/all.cpp @@ -48,3 +48,4 @@ #include "src/wasp.cpp" // This includes the VM so it is last #include "src/d_menu.cpp" + diff --git a/source/games/exhumed/src/2d.cpp b/source/games/exhumed/src/2d.cpp index 49e71090b..261f71d1b 100644 --- a/source/games/exhumed/src/2d.cpp +++ b/source/games/exhumed/src/2d.cpp @@ -107,9 +107,9 @@ void menu_DoPlasma() int ptile = nPlasmaTile; int pclock = I_GetBuildTime(); - if (pclock >= nextPlasmaTic || !PlasmaBuffer) + while (pclock >= nextPlasmaTic || !PlasmaBuffer) { - nextPlasmaTic = pclock + 4; + nextPlasmaTic += 4; if (!PlasmaBuffer) { diff --git a/source/games/exhumed/src/aistuff.h b/source/games/exhumed/src/aistuff.h index e177c0cb1..f8f521c6a 100644 --- a/source/games/exhumed/src/aistuff.h +++ b/source/games/exhumed/src/aistuff.h @@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "compat.h" #include "freelistarray.h" +#include "exhumedactor.h" BEGIN_PS_NS @@ -170,7 +171,7 @@ void DoRegenerates(); // lavadude -void BuildLava(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel); +void BuildLava(DExhumedActor* nSprite, int x, int y, int z, int nSector, short nAngle, int nChannel); DExhumedActor* BuildLavaLimb(DExhumedActor* nSprite, int edx, int ebx); void FuncLavaLimb(int, int, int, int); void FuncLava(int, int, int, int); @@ -180,20 +181,20 @@ void FuncLava(int, int, int, int); extern short nFlashDepth; void InitLights(); -void AddFlash(short nSector, int x, int y, int z, int val); +void AddFlash(int nSector, int x, int y, int z, int val); void SetTorch(int nPlayer, int bTorchOnOff); void UndoFlashes(); void DoLights(); void AddFlow(int nSprite, int nSpeed, int b, int ang = -1); -void BuildFlash(short nPlayer, short nSector, int nVal); -void AddGlow(short nSector, int nVal); -void AddFlicker(short nSector, int nVal); +void BuildFlash(int nPlayer, int nVal); +void AddGlow(int nSector, int nVal); +void AddFlicker(int nSector, int nVal); extern short bTorch; // lion -void BuildLion(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle); +void BuildLion(DExhumedActor* nSprite, int x, int y, int z, int nSector, short nAngle); void FuncLion(int, int, int, int); // move @@ -201,14 +202,14 @@ void FuncLion(int, int, int, int); // 16 bytes struct BlockInfo { + DExhumedActor* pActor; int x; int y; int field_8; - short nSprite; }; extern BlockInfo sBlockInfo[]; -extern int hihit; +extern Collision hiHit; extern DExhumedActor* nChunkSprite[]; extern DExhumedActor* nBodySprite[]; @@ -218,75 +219,28 @@ void ResetMoveFifo(); void InitChunks(); void InitPushBlocks(); void Gravity(DExhumedActor* actor); -short UpdateEnemy(short *nEnemy); -DExhumedActor* UpdateEnemy(DExhumedActor** ppEnemy) -{ - short ndx = (short)(*ppEnemy? (*ppEnemy)->GetSpriteIndex() : -1); - int v = UpdateEnemy(&ndx); - return v == -1 ? nullptr : &exhumedActors[v]; -} - -int MoveCreature(short nSprite); -Collision MoveCreature(DExhumedActor* nSprite) -{ - return Collision(MoveCreature(nSprite->GetSpriteIndex())); -} -int MoveCreatureWithCaution(int nSprite); -inline Collision MoveCreatureWithCaution(DExhumedActor* actor) -{ - return Collision(MoveCreatureWithCaution(actor->GetSpriteIndex())); -} -void WheresMyMouth(int nPlayer, int *x, int *y, int *z, short *sectnum); -int GetSpriteHeight(int nSprite); +DExhumedActor* UpdateEnemy(DExhumedActor** ppEnemy); +Collision MoveCreature(DExhumedActor* nSprite); +Collision MoveCreatureWithCaution(DExhumedActor* actor); +void WheresMyMouth(int nPlayer, vec3_t* pos, int *sectnum); int GetActorHeight(DExhumedActor* nSprite); DExhumedActor* insertActor(int, int); DExhumedActor* GrabBody(); DExhumedActor* GrabBodyGunSprite(); void CreatePushBlock(int nSector); void FuncCreatureChunk(int a, int, int nRun); -int FindPlayer(int nSprite, int nDistance, bool dontengage = false); -inline DExhumedActor* FindPlayer(DExhumedActor* nSprite, int nDistance, bool dontengage = false) -{ - int targ = FindPlayer(nSprite->GetSpriteIndex(), nDistance, dontengage); - return targ > -1 ? &exhumedActors[targ] : nullptr; -} +DExhumedActor* FindPlayer(DExhumedActor* nSprite, int nDistance, bool dontengage = false); -int BuildCreatureChunk(int nVal, int nPic); -DExhumedActor* BuildCreatureChunk(DExhumedActor* pSrc, int nPic, bool bSpecial = false) -{ - int s = pSrc->GetSpriteIndex(); - if (bSpecial) s |= 0x4000; - int c = BuildCreatureChunk(s, nPic); - return c < 0 ? nullptr : &exhumedActors[c]; -} +DExhumedActor* BuildCreatureChunk(DExhumedActor* pSrc, int nPic, bool bSpecial = false); void BuildNear(int x, int y, int walldist, int nSector); -int PlotCourseToSprite(int nSprite1, int nSprite2); -inline int PlotCourseToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2) -{ - if (nSprite1 == nullptr || nSprite2 == nullptr) - return -1; - - return PlotCourseToSprite(nSprite1->GetSpriteIndex(), nSprite2->GetSpriteIndex()); -} -void CheckSectorFloor(short nSector, int z, int *x, int *y); +int PlotCourseToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2); +void CheckSectorFloor(int nSector, int z, int *x, int *y); int GetAngleToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2); -int GetWallNormal(short nWall); -int GetUpAngle(short nSprite1, int nVal, short nSprite2, int ecx); -int GetUpAngle(DExhumedActor* nSprite1, int nVal, DExhumedActor* nSprite2, int ecx) -{ - return GetUpAngle(nSprite1->GetSpriteIndex(), nVal, nSprite2->GetSpriteIndex(), ecx); -} -void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel); -int AngleChase(int nSprite, int nSprite2, int ebx, int ecx, int push1); -inline Collision AngleChase(DExhumedActor* nSprite, DExhumedActor* nSprite2, int ebx, int ecx, int push1) -{ - return Collision(AngleChase(nSprite->GetSpriteIndex(), nSprite2? nSprite2->GetSpriteIndex() : -1, ebx, ecx, push1)); -} -void SetQuake(short nSprite, int nVal); -void SetQuake(DExhumedActor* nSprite, int nVal) -{ - SetQuake(nSprite->GetSpriteIndex(), nVal); -} +int GetWallNormal(int nWall); +int GetUpAngle(DExhumedActor* nSprite1, int nVal, DExhumedActor* nSprite2, int ecx); +void MoveSector(int nSector, int nAngle, int *nXVel, int *nYVel); +Collision AngleChase(DExhumedActor* nSprite, DExhumedActor* nSprite2, int ebx, int ecx, int push1); +void SetQuake(DExhumedActor* nSprite, int nVal); // mummy @@ -329,19 +283,19 @@ void FuncObject(int, int, int, int); void FuncTrap(int, int, int, int); void FuncEnergyBlock(int, int, int, int); void FuncSpark(int, int, int, int); -void SnapBobs(short nSectorA, short nSectorB); -short FindWallSprites(short nSector); +void SnapBobs(int nSectorA, int nSectorB); +DExhumedActor* FindWallSprites(int nSector); void AddMovingSector(int nSector, int edx, int ebx, int ecx); -void ProcessTrailSprite(int nSprite, int nLotag, int nHitag); +void ProcessTrailSprite(DExhumedActor* nSprite, int nLotag, int nHitag); void AddSectorBob(int nSector, int nHitag, int bx); -int BuildObject(int const nSprite, int nOjectType, int nHitag); +DExhumedActor* BuildObject(DExhumedActor* nSprite, int nOjectType, int nHitag); int BuildArrow(DExhumedActor* nSprite, int nVal); int BuildFireBall(DExhumedActor*, int a, int b); -void BuildDrip(int nSprite); -DExhumedActor* BuildEnergyBlock(short nSector); -int BuildElevC(int arg1, int nChannel, int nSector, int nWallSprite, int arg5, int arg6, int nCount, ...); -int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5, int nCount, ...); -int BuildWallFace(short nChannel, short nWall, int nCount, ...); +void BuildDrip(DExhumedActor* nSprite); +DExhumedActor* BuildEnergyBlock(int nSector); +int BuildElevC(int arg1, int nChannel, int nSector, DExhumedActor* nWallSprite, int arg5, int arg6, int nCount, ...); +int BuildElevF(int nChannel, int nSector, DExhumedActor* nWallSprite, int arg_4, int arg_5, int nCount, ...); +int BuildWallFace(short nChannel, int nWall, int nCount, ...); int BuildSlide(int nChannel, int edx, int ebx, int ecx, int arg1, int arg2, int arg3); // queen @@ -380,18 +334,18 @@ void FuncRa(int, int, int, int); void InitRats(); void SetRatVel(short nSprite); -void BuildRat(DExhumedActor* nSprite, int x, int y, int z, short nSector, int nAngle); +void BuildRat(DExhumedActor* nSprite, int x, int y, int z, int nSector, int nAngle); int FindFood(short nSprite); void FuncRat(int a, int, int b, int nRun); // rex -void BuildRex(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel); +void BuildRex(DExhumedActor* nSprite, int x, int y, int z, int nSector, short nAngle, int nChannel); void FuncRex(int, int, int, int); // roach -void BuildRoach(int nType, DExhumedActor* nSprite, int x, int y, int z, short nSector, int angle); +void BuildRoach(int nType, DExhumedActor* nSprite, int x, int y, int z, int nSector, int angle); void FuncRoach(int a, int, int nDamage, int nRun); // runlist @@ -419,23 +373,10 @@ struct RunChannel short d; }; -enum class EMessageType -{ - ProcessChannel = 1, - Tick, - Process, - Use, - TouchFloor, - LeaveSector, - EnterSector, - Damage, - Draw, - RadialDamage -}; struct RunListEvent { - EMessageType nMessage; + int nMessage; int nParam; // mostly the player, sometimes the channel list int nObjIndex; DExhumedActor* pObjActor; @@ -446,6 +387,8 @@ struct RunListEvent int nRadialDamage; // Radial damage needs a bit more info. int nDamageRadius; DExhumedActor* pRadialActor; + + bool isRadialEvent() const { return nMessage == 1; } }; struct ExhumedAI @@ -730,7 +673,6 @@ struct AISWPressWall : public ExhumedAI void Use(RunListEvent* ev) override; }; -void runlist_DispatchEvent(ExhumedAI* ai, int nObject, int nMessage, int nDamage, int nRun); typedef void(*AiFunc)(int, int, int, int nRun); @@ -738,8 +680,6 @@ extern FreeListArray RunData; extern RunChannel sRunChannels[kMaxChannels]; extern short NewRun; -extern int nRadialOwner; -extern short nRadialSpr; void runlist_InitRun(); @@ -757,34 +697,22 @@ int runlist_AllocChannel(int a); void runlist_DoSubRunRec(int RunPtr); void runlist_SubRunRec(int RunPtr); void runlist_ProcessWallTag(int nWall, short nLotag, short nHitag); -int runlist_CheckRadialDamage(short nSprite); -inline int runlist_CheckRadialDamage(DExhumedActor* actor) -{ - return runlist_CheckRadialDamage(actor->GetSpriteIndex()); -} -void runlist_RadialDamageEnemy(short nSprite, short nDamage, short nRadius); -inline void runlist_RadialDamageEnemy(DExhumedActor* nSprite, short nSprite2, short nDamage) -{ - return runlist_RadialDamageEnemy(nSprite->GetSpriteIndex(), nSprite2, nDamage); -} -void runlist_DamageEnemy(int nSprite, int nSprite2, short nDamage); -inline void runlist_DamageEnemy(DExhumedActor* nSprite, DExhumedActor* nSprite2, short nDamage) -{ - return runlist_DamageEnemy(nSprite? nSprite->GetSpriteIndex() : -1, nSprite2? nSprite2->GetSpriteIndex() : -1, nDamage); -} -void runlist_SignalRun(int NxtPtr, int edx); +int runlist_CheckRadialDamage(DExhumedActor* actor); +void runlist_RadialDamageEnemy(DExhumedActor* nSprite, short nSprite2, short nDamage); +void runlist_DamageEnemy(DExhumedActor* nSprite, DExhumedActor* nSprite2, short nDamage); +void runlist_SignalRun(int NxtPtr, int edx, void(ExhumedAI::* func)(RunListEvent*), RunListEvent* ev = nullptr); void runlist_CleanRunRecs(); void runlist_ExecObjects(); // scorp -void BuildScorp(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel); +void BuildScorp(DExhumedActor* nSprite, int x, int y, int z, int nSector, short nAngle, int nChannel); void FuncScorp(int, int, int, int); // set -void BuildSet(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel); +void BuildSet(DExhumedActor* nSprite, int x, int y, int z, int nSector, short nAngle, int nChannel); void FuncSoul(int, int, int, int); void FuncSet(int, int, int, int); @@ -802,7 +730,7 @@ struct Snake short sC; short nRun; - char c[8]; + uint8_t c[8]; short sE; short nSnakePlayer; }; @@ -818,7 +746,7 @@ void FuncSnake(int, int, int, int); // spider -DExhumedActor* BuildSpider(DExhumedActor* nSprite, int x, int y, int z, short nSector, int nAngle); +DExhumedActor* BuildSpider(DExhumedActor* nSprite, int x, int y, int z, int nSector, int nAngle); void FuncSpider(int a, int, int b, int nRun); // switch @@ -840,11 +768,11 @@ std::pair BuildSwPressSector(int nChannel, int nLink, int nSector, int std::pair BuildSwStepOn(int nChannel, int nLink, int nSector); std::pair BuildSwReady(int nChannel, short nLink); -std::pair BuildSwPressWall(short nChannel, short nLink, short nWall); +std::pair BuildSwPressWall(short nChannel, short nLink, int nWall); // wasp -DExhumedActor* BuildWasp(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, bool bEggWasp); +DExhumedActor* BuildWasp(DExhumedActor* nSprite, int x, int y, int z, int nSector, short nAngle, bool bEggWasp); void FuncWasp(int eax, int, int edx, int nRun); diff --git a/source/games/exhumed/src/anims.cpp b/source/games/exhumed/src/anims.cpp index 65bc70ea0..2dd30a570 100644 --- a/source/games/exhumed/src/anims.cpp +++ b/source/games/exhumed/src/anims.cpp @@ -111,6 +111,8 @@ DExhumedActor* BuildAnim(DExhumedActor* pActor, int val, int val2, int x, int y, pActor->nIndex = 0; pActor->nIndex2 = SeqOffsets[val] + val2; pActor->pTarget = nullptr; + pActor->nDamage = pActor->nRun; + pActor->nPhase = ITEM_MAGIC; if (nFlag & 0x80) { pSprite->cstat |= 0x2; // set transluscence @@ -234,17 +236,11 @@ void AIAnim::Draw(RunListEvent* ev) ev->pTSprite->owner = -1; } -void FuncAnim(int nObject, int nMessage, int nDamage, int nRun) -{ - AIAnim ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - void BuildExplosion(DExhumedActor* pActor) { auto pSprite = &pActor->s(); - short nSector = pSprite->sectnum; + int nSector = pSprite->sectnum; int edx = 36; @@ -252,7 +248,7 @@ void BuildExplosion(DExhumedActor* pActor) { edx = 75; } - else if (pSprite->z == sector[nSector].floorz) + else if (pSprite->z == pSprite->sector()->floorz) { edx = 34; } diff --git a/source/games/exhumed/src/anubis.cpp b/source/games/exhumed/src/anubis.cpp index cc619f969..ac6e354f0 100644 --- a/source/games/exhumed/src/anubis.cpp +++ b/source/games/exhumed/src/anubis.cpp @@ -58,7 +58,7 @@ void BuildAnubis(DExhumedActor* ap, int x, int y, int z, int nSector, int nAngle x = sp->x; y = sp->y; - z = sector[sp->sectnum].floorz; + z = sp->sector()->floorz; nAngle = sp->ang; } @@ -70,7 +70,7 @@ void BuildAnubis(DExhumedActor* ap, int x, int y, int z, int nSector, int nAngle sp->shade = -12; sp->yoffset = 0; sp->picnum = 1; - sp->pal = sector[sp->sectnum].ceilingpal; + sp->pal = sp->sector()->ceilingpal; sp->clipdist = 60; sp->ang = nAngle; sp->xrepeat = 40; @@ -406,12 +406,12 @@ void AIAnubis::Damage(RunListEvent* ev) pDrumSprite->x = sp->x; pDrumSprite->y = sp->y; - pDrumSprite->z = sector[pDrumSprite->sectnum].floorz; + pDrumSprite->z = pDrumSprite->sector()->floorz; pDrumSprite->xrepeat = 40; pDrumSprite->yrepeat = 40; pDrumSprite->shade = -64; - BuildObject(pDrumActor->GetSpriteIndex(), 2, 0); + BuildObject(pDrumActor, 2, 0); } ap->pTarget = ev->pOtherActor; @@ -430,7 +430,7 @@ void AIAnubis::Damage(RunListEvent* ev) sp->xvel = 0; sp->yvel = 0; sp->zvel = 0; - sp->z = sector[sp->sectnum].floorz; + sp->z = sp->sector()->floorz; sp->cstat &= 0xFEFE; ap->nHealth = 0; @@ -440,7 +440,7 @@ void AIAnubis::Damage(RunListEvent* ev) if (nAction < 11) { DropMagic(ap); - ap->nAction = (ev->nMessage == EMessageType::RadialDamage) + 11; + ap->nAction = int(ev->isRadialEvent()) + 11; ap->nFrame = 0; } } @@ -448,10 +448,4 @@ void AIAnubis::Damage(RunListEvent* ev) } -void FuncAnubis(int nObject, int nMessage, int nDamage, int nRun) -{ - AIAnubis ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/exhumed/src/bubbles.cpp b/source/games/exhumed/src/bubbles.cpp index 1c0f2ea89..eb4859863 100644 --- a/source/games/exhumed/src/bubbles.cpp +++ b/source/games/exhumed/src/bubbles.cpp @@ -35,7 +35,7 @@ void DestroyBubble(DExhumedActor* pActor) DeleteActor(pActor); } -DExhumedActor* BuildBubble(int x, int y, int z, short nSector) +DExhumedActor* BuildBubble(vec3_t pos, int nSector) { int nSize = RandomSize(3); if (nSize > 4) { @@ -45,9 +45,7 @@ DExhumedActor* BuildBubble(int x, int y, int z, short nSector) auto pActor = insertActor(nSector, 402); auto pSprite = &pActor->s(); - pSprite->x = x; - pSprite->y = y; - pSprite->z = z; + pSprite->pos = pos; pSprite->cstat = 0; pSprite->shade = -32; pSprite->pal = 0; @@ -95,11 +93,11 @@ void AIBubble::Tick(RunListEvent* ev) pSprite->z += pSprite->zvel; - short nSector = pSprite->sectnum; + int nSector = pSprite->sectnum; if (pSprite->z <= sector[nSector].ceilingz) { - short nSectAbove = SectAbove[nSector]; + int nSectAbove = SectAbove[nSector]; if (pSprite->hitag > -1 && nSectAbove != -1) { BuildAnim(nullptr, 70, 0, pSprite->x, pSprite->y, sector[nSectAbove].floorz, nSectAbove, 64, 0); @@ -118,11 +116,6 @@ void AIBubble::Draw(RunListEvent* ev) ev->pTSprite->owner = -1; } -void FuncBubble(int nObject, int nMessage, int nDamage, int nRun) -{ - AIBubble ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} void DoBubbleMachines() { @@ -136,7 +129,7 @@ void DoBubbleMachines() pActor->nCount = (RandomWord() % pActor->nFrame) + 30; auto pSprite = &pActor->s(); - BuildBubble(pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum); + BuildBubble(pSprite->pos, pSprite->sectnum); } } } @@ -153,12 +146,12 @@ void BuildBubbleMachine(DExhumedActor* pActor) void DoBubbles(int nPlayer) { - int x, y, z; - short nSector; + vec3_t pos; + int nSector; - WheresMyMouth(nPlayer, &x, &y, &z, &nSector); + WheresMyMouth(nPlayer, &pos, &nSector); - auto pActor = BuildBubble(x, y, z, nSector); + auto pActor = BuildBubble(pos, nSector); pActor->s().hitag = nPlayer; } END_PS_NS diff --git a/source/games/exhumed/src/bullet.cpp b/source/games/exhumed/src/bullet.cpp index 972f2d396..13cf53524 100644 --- a/source/games/exhumed/src/bullet.cpp +++ b/source/games/exhumed/src/bullet.cpp @@ -487,7 +487,7 @@ HITSPRITE: HITWALL: if (wall[hitwall].picnum == kEnergy1) { - short nSector = wall[hitwall].nextsector; + int nSector =wall[hitwall].nextsector; if (nSector > -1) { short nDamage = BulletInfo[pBullet->nType].nDamage; @@ -612,7 +612,7 @@ DExhumedActor* BuildBullet(DExhumedActor* pActor, int nType, int nZOffset, int n return nullptr; } - short nSector; + int nSector; if (pSprite->statnum == 100) { @@ -707,7 +707,7 @@ DExhumedActor* BuildBullet(DExhumedActor* pActor, int nType, int nZOffset, int n pBulletSprite->z += nZOffset; pBulletSprite->backuppos(); - int var_18; + int var_18 = 0; nSector = pBulletSprite->sectnum; @@ -879,9 +879,4 @@ void AIBullet::Draw(RunListEvent* ev) } } -void FuncBullet(int nObject, int nMessage, int nDamage, int nRun) -{ - AIBullet ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/engine.h b/source/games/exhumed/src/engine.h index 8fc751b18..0e6e76450 100644 --- a/source/games/exhumed/src/engine.h +++ b/source/games/exhumed/src/engine.h @@ -37,11 +37,7 @@ enum }; -int movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask); -inline Collision movesprite(DExhumedActor* spritenum, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask) -{ - return Collision(movesprite(spritenum->GetSpriteIndex(), dx, dy, dz, ceildist, flordist, clipmask)); -} +Collision movesprite(DExhumedActor* spritenum, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask); void precache(); void resettiming(); @@ -64,7 +60,7 @@ extern int initx; extern int inity; extern int initz; extern short inita; -extern short initsect; +extern int initsect; extern short nCurChunkNum; extern DExhumedActor* nBodyGunSprite[50]; @@ -92,7 +88,7 @@ enum ECounter }; extern int Counters[kNumCounters]; -void SnapSectors(short nSectorA, short nSectorB, short b); +void SnapSectors(int nSectorA, int nSectorB, int b); extern short SectSound[]; extern short SectDamage[]; @@ -100,7 +96,7 @@ extern short SectSpeed[]; extern int SectBelow[]; extern short SectFlag[]; extern int SectDepth[]; -extern short SectSoundSect[]; +extern int SectSoundSect[]; extern int SectAbove[]; void LoadObjects(); @@ -114,7 +110,6 @@ void FixPalette(); int HavePLURemap(); uint8_t RemapPLU(uint8_t pal); -//extern unsigned char kenpal[]; extern short overscanindex; extern char *origpalookup[]; @@ -133,7 +128,7 @@ void DrawMap(double const smoothratio); void InitRandom(); int RandomBit(); -char RandomByte(); +uint8_t RandomByte(); uint16_t RandomWord(); int RandomLong(); int RandomSize(int nSize); diff --git a/source/games/exhumed/src/enginesubs.cpp b/source/games/exhumed/src/enginesubs.cpp index b9244c95f..968a451dd 100644 --- a/source/games/exhumed/src/enginesubs.cpp +++ b/source/games/exhumed/src/enginesubs.cpp @@ -42,16 +42,34 @@ void precache() for (i = 0; i < numsectors; i++) { - short j = sector[i].ceilingpicnum; - markTileForPrecache(j, sector[i].ceilingpal); - j = sector[i].floorpicnum; - markTileForPrecache(j, sector[i].floorpal); + auto sectp = §or[i]; + int j = sectp->ceilingpicnum; + markTileForPrecache(j, sectp->ceilingpal); + if (picanm[j].sf & PICANM_ANIMTYPE_MASK) + for (int k = 1; k <= picanm[j].num; k++) markTileForPrecache(j + k, sectp->ceilingpal); + + j = sectp->floorpicnum; + markTileForPrecache(j, sectp->floorpal); + if (picanm[j].sf & PICANM_ANIMTYPE_MASK) + for (int k = 1; k <= picanm[j].num; k++) markTileForPrecache(j + k, sectp->floorpal); } for (i = 0; i < numwalls; i++) { - short j = wall[i].picnum; - markTileForPrecache(j, wall[i].pal); + auto wallp = &wall[i]; + int j = wallp->picnum; + markTileForPrecache(j, wallp->pal); + if (picanm[j].sf & PICANM_ANIMTYPE_MASK) + for (int k = 1; k <= picanm[j].num; k++) markTileForPrecache(j + k, wallp->pal); + + if (wallp->nextsector != -1) + { + int j = wallp->overpicnum; + markTileForPrecache(j, wallp->pal); + if (picanm[j].sf & PICANM_ANIMTYPE_MASK) + for (int k = 1; k <= picanm[j].num; k++) markTileForPrecache(j + k, wallp->pal); + + } } ExhumedSpriteIterator it; diff --git a/source/games/exhumed/src/exhumed.cpp b/source/games/exhumed/src/exhumed.cpp index 545a38683..3e086e245 100644 --- a/source/games/exhumed/src/exhumed.cpp +++ b/source/games/exhumed/src/exhumed.cpp @@ -100,8 +100,6 @@ short nFreeze; short nSnakeCam = -1; -short nLocalSpr; - int nNetPlayerCount = 0; short nClockVal; @@ -153,7 +151,7 @@ short bInDemo = false; short bSlipMode = false; short bDoFlashes = true; -short besttarget; +DExhumedActor* bestTarget; short scan_char = 0; @@ -176,7 +174,7 @@ void DoClockBeep() ExhumedStatIterator it(407); while (auto i = it.Next()) { - PlayFX2(StaticSound[kSound74], i->GetSpriteIndex()); + PlayFX2(StaticSound[kSound74], i); } } @@ -429,11 +427,11 @@ void GameInterface::Ticker() sPlayerInput[nLocalPlayer].xVel = lPlayerXVel; sPlayerInput[nLocalPlayer].yVel = lPlayerYVel; sPlayerInput[nLocalPlayer].buttons = lLocalCodes; - sPlayerInput[nLocalPlayer].nTarget = besttarget; + sPlayerInput[nLocalPlayer].pTarget = bestTarget; sPlayerInput[nLocalPlayer].nAngle = localInput.avel; sPlayerInput[nLocalPlayer].pan = localInput.horz; - Ra[nLocalPlayer].pTarget = &exhumedActors[besttarget]; + Ra[nLocalPlayer].pTarget = bestTarget; lLocalCodes = 0; @@ -508,25 +506,21 @@ void GameInterface::app_init() enginecompatibility_mode = ENGINECOMPATIBILITY_19950829; } -void mychangespritesect(int nSprite, int nSector) +void DeleteActor(DExhumedActor* actor) { - changespritesect(nSprite, nSector); -} - -void mydeletesprite(int nSprite) -{ - if (nSprite < 0 || nSprite > kMaxSprites) { - I_Error("bad sprite value %d handed to mydeletesprite", nSprite); + if (!actor) + { + return; } - FVector3 pos = GetSoundPos(&sprite[nSprite].pos); - soundEngine->RelinkSound(SOURCE_Actor, &sprite[nSprite], nullptr, &pos); + FVector3 pos = GetSoundPos(&actor->s().pos); + soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos); - deletesprite(nSprite); - sprite[nSprite].ox = 0x80000000; + deletesprite(actor->GetSpriteIndex()); + actor->s().ox = 0x80000000; - if (nSprite == besttarget) { - besttarget = -1; + if (actor == bestTarget) { + bestTarget = nullptr; } } @@ -629,12 +623,11 @@ void SerializeState(FSerializer& arc) InitEnergyTile(); } - arc ("besttarget", besttarget) + arc ("besttarget", bestTarget) ("creaturestotal", nCreaturesTotal) ("creatureskilled", nCreaturesKilled) ("freeze", nFreeze) ("snakecam", nSnakeCam) - ("localspr", nLocalSpr) ("clockval", nClockVal) // kTile3603 ("redticks", nRedTicks) ("alarmticks", nAlarmTicks) @@ -648,7 +641,8 @@ void SerializeState(FSerializer& arc) ("bsnakecam", bSnakeCam) ("slipmode", bSlipMode) ("PlayClock", PlayClock) - ("spiritsprite", nSpiritSprite) + ("spiritsprite", pSpiritSprite) + .SparseArray("actors", exhumedActors, kMaxSprites, activeSprites) .EndObject(); } } diff --git a/source/games/exhumed/src/exhumed.h b/source/games/exhumed/src/exhumed.h index d77b77c40..d8b36a3dd 100644 --- a/source/games/exhumed/src/exhumed.h +++ b/source/games/exhumed/src/exhumed.h @@ -39,6 +39,8 @@ BEGIN_PS_NS enum { kTimerTicks = 120 }; +const int ITEM_MAGIC = 0x4711; + enum basepal_t { BASEPAL = 0, ANIMPAL, @@ -66,12 +68,7 @@ void TintPalette(int a, int b, int c); void EraseScreen(int eax); -void mychangespritesect(int nSprite, int nSector); -void mydeletesprite(int nSprite); -inline void DeleteActor(DExhumedActor* actor) -{ - mydeletesprite(actor->GetSpriteIndex()); -} +void DeleteActor(DExhumedActor* actor); void GrabPalette(); @@ -84,7 +81,6 @@ void StatusMessage(int messageTime, const char *fmt, ...); void DoSpiritHead(); -void CheckKeys2(); void GameTicker(); void InitLevel(MapRecord*); void InitNewGame(); @@ -119,7 +115,7 @@ extern short nEnergyTowers; extern short nEnergyChan; -extern short nSpiritSprite; +extern DExhumedActor* pSpiritSprite; extern short bInDemo; @@ -138,8 +134,6 @@ extern short lastfps; extern int flash; -extern short nLocalSpr; - extern short nSnakeCam; extern short bCoordinates; @@ -249,9 +243,9 @@ struct GameInterface : public ::GameInterface int playerKeyMove() override { return 6; } void WarpToCoords(int x, int y, int z, int a, int h) override; void ToggleThirdPerson() override; - int chaseCamX(binangle ang) { return -ang.bcos() / 12; } - int chaseCamY(binangle ang) { return -ang.bsin() / 12; } - int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() / 384; } + int chaseCamX(binangle ang) { return -(ang.bcos() * 3) >> 5; } + int chaseCamY(binangle ang) { return -(ang.bsin() * 3) >> 5; } + int chaseCamZ(fixedhoriz horiz) { return (horiz.asq16() * 3) >> 10; } void processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override; int GetCurrentSkill() override; diff --git a/source/games/exhumed/src/exhumedactor.h b/source/games/exhumed/src/exhumedactor.h index fae54ac8d..5407f2626 100644 --- a/source/games/exhumed/src/exhumedactor.h +++ b/source/games/exhumed/src/exhumedactor.h @@ -2,8 +2,6 @@ BEGIN_PS_NS -void mydeletesprite(int nSprite); - class DExhumedActor; enum diff --git a/source/games/exhumed/src/fish.cpp b/source/games/exhumed/src/fish.cpp index ed8ea6620..dd43498cf 100644 --- a/source/games/exhumed/src/fish.cpp +++ b/source/games/exhumed/src/fish.cpp @@ -77,7 +77,7 @@ void BuildFishLimb(DExhumedActor* pActor, short anim) pSprite2->hitag = runlist_AddRunRec(NewRun, pChunkActor, 0x200000); } -void BuildBlood(int x, int y, int z, short nSector) +void BuildBlood(int x, int y, int z, int nSector) { BuildAnim(nullptr, kSeqFish, 36, x, y, z, nSector, 75, 128); } @@ -105,7 +105,7 @@ void AIFishLimb::Tick(RunListEvent* ev) } } - int FloorZ = sector[pSprite->sectnum].floorz; + int FloorZ = pSprite->sector()->floorz; if (FloorZ <= pSprite->z) { @@ -145,12 +145,6 @@ void AIFishLimb::Draw(RunListEvent* ev) } -void FuncFishLimb(int nObject, int nMessage, int nDamage, int nRun) -{ - AIFishLimb ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - void BuildFish(DExhumedActor* pActor, int x, int y, int z, int nSector, int nAngle) { spritetype* pSprite; @@ -178,7 +172,7 @@ void BuildFish(DExhumedActor* pActor, int x, int y, int z, int nSector, int nAng pSprite->clipdist = 80; pSprite->xrepeat = 40; pSprite->yrepeat = 40; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->picnum = seq_GetSeqPicnum(kSeqFish, FishSeq[0].a, 0); @@ -293,7 +287,7 @@ void AIFish::Damage(RunListEvent* ev) pSprite->cstat &= 0xFEFE; - if (ev->nMessage == EMessageType::Damage) + if (!ev->isRadialEvent()) { for (int i = 0; i < 3; i++) { @@ -444,7 +438,7 @@ void AIFish::Tick(RunListEvent* ev) int x = pSprite->x; int y = pSprite->y; int z = pSprite->z; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; // loc_2EF54 Collision coll = movesprite(pActor, pSprite->xvel << 13, pSprite->yvel << 13, pSprite->zvel << 2, 0, 0, CLIPMASK0); @@ -514,11 +508,4 @@ void AIFish::Tick(RunListEvent* ev) } } - -void FuncFish(int nObject, int nMessage, int nDamage, int nRun) -{ - AIFish ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/exhumed/src/gameloop.cpp b/source/games/exhumed/src/gameloop.cpp index f7c42b308..615b5f486 100644 --- a/source/games/exhumed/src/gameloop.cpp +++ b/source/games/exhumed/src/gameloop.cpp @@ -65,7 +65,6 @@ void DoTitle(CompletionFunc completion); void GameInterface::Render() { - CheckKeys2(); drawtime.Reset(); drawtime.Clock(); diff --git a/source/games/exhumed/src/grenade.cpp b/source/games/exhumed/src/grenade.cpp index 71e08b5d1..42119c6c4 100644 --- a/source/games/exhumed/src/grenade.cpp +++ b/source/games/exhumed/src/grenade.cpp @@ -49,13 +49,13 @@ void BounceGrenade(DExhumedActor* pActor, short nAngle) void ThrowGrenade(short nPlayer, int, int, int ecx, int push1) { - if (PlayerList[nPlayer].nPlayerGrenade == nullptr) + if (PlayerList[nPlayer].pPlayerGrenade == nullptr) return; - auto pActor = PlayerList[nPlayer].nPlayerGrenade; - short nPlayerSprite = PlayerList[nPlayer].nSprite; - auto pGrenadeSprite = &pActor->s(); - auto pPlayerSprite = &PlayerList[nPlayer].Actor()->s(); + auto pActor = PlayerList[nPlayer].pPlayerGrenade; + auto pGrenadeSprite = &pActor->s(); + auto pPlayerActor = PlayerList[nPlayer].Actor(); + auto pPlayerSprite = &pPlayerActor->s(); short nAngle = pPlayerSprite->ang; @@ -95,7 +95,7 @@ void ThrowGrenade(short nPlayer, int, int, int ecx, int push1) pActor->x = bcos(nAngle, -4) * pActor->nTurn; pActor->y = bsin(nAngle, -4) * pActor->nTurn; - PlayerList[nPlayer].nPlayerGrenade = nullptr; + PlayerList[nPlayer].pPlayerGrenade = nullptr; return; } @@ -140,7 +140,7 @@ void BuildGrenade(int nPlayer) pActor->nPhase = runlist_AddRunRec(pSprite->lotag - 1, pActor, 0x0F0000); pActor->nRun = runlist_AddRunRec(NewRun, pActor, 0x0F0000); - PlayerList[nPlayer].nPlayerGrenade = pActor; + PlayerList[nPlayer].pPlayerGrenade = pActor; } void ExplodeGrenade(DExhumedActor* pActor) @@ -148,8 +148,8 @@ void ExplodeGrenade(DExhumedActor* pActor) int var_28, var_20; auto pGrenadeSprite = &pActor->s(); - short nPlayer = pGrenadeSprite->owner; - short nGrenadeSect = pGrenadeSprite->sectnum; + int nPlayer = pGrenadeSprite->owner; + int nGrenadeSect = pGrenadeSprite->sectnum; pActor->nFrame = 1; @@ -357,10 +357,5 @@ void AIGrenade::RadialDamage(RunListEvent* ev) } } -void FuncGrenade(int nObject, int nMessage, int nDamage, int nRun) -{ - AIGrenade ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/gun.cpp b/source/games/exhumed/src/gun.cpp index ace3ac92c..44ce82271 100644 --- a/source/games/exhumed/src/gun.cpp +++ b/source/games/exhumed/src/gun.cpp @@ -117,13 +117,13 @@ void ResetPlayerWeapons(short nPlayer) PlayerList[nPlayer].field_3A = 0; PlayerList[nPlayer].field_3FOUR = 0; - PlayerList[nPlayer].nPlayerGrenade = nullptr; + PlayerList[nPlayer].pPlayerGrenade = nullptr; PlayerList[nPlayer].nPlayerWeapons = 0x1; // turn on bit 1 only } void InitWeapons() { - for (auto& p : PlayerList) p.nPlayerGrenade = nullptr; + for (auto& p : PlayerList) p.pPlayerGrenade = nullptr; } void SetNewWeapon(short nPlayer, short nWeapon) @@ -231,7 +231,7 @@ void SetWeaponStatus(short nPlayer) uint8_t WeaponCanFire(short nPlayer) { short nWeapon = PlayerList[nPlayer].nCurrentWeapon; - short nSector = PlayerList[nPlayer].nPlayerViewSect; + int nSector =PlayerList[nPlayer].nPlayerViewSect; if (!(SectFlag[nSector] & kSectUnderwater) || WeaponInfo[nWeapon].bFireUnderwater) { @@ -252,7 +252,7 @@ void ResetSwordSeqs() WeaponInfo[kWeaponSword].b[3] = 7; } -int CheckCloseRange(short nPlayer, int *x, int *y, int *z, short *nSector) +Collision CheckCloseRange(short nPlayer, int *x, int *y, int *z, short *nSector) { short hitSect, hitWall, hitSprite; int hitX, hitY, hitZ; @@ -285,9 +285,10 @@ int CheckCloseRange(short nPlayer, int *x, int *y, int *z, short *nSector) DPrintf(DMSG_WARNING, "%s %d: overflow\n", __func__, __LINE__); sqrtNum = INT_MAX; } + Collision c(0); if (ksqrt(sqrtNum) >= ecx) - return 0; + return c; *x = hitX; *y = hitY; @@ -295,13 +296,13 @@ int CheckCloseRange(short nPlayer, int *x, int *y, int *z, short *nSector) *nSector = hitSect; if (hitSprite > -1) { - return hitSprite | 0xC000; + c.setSprite(&exhumedActors[hitSprite]); } if (hitWall > -1) { - return hitWall | 0x8000; + c.setWall(hitWall); } - return 0; + return c; } void CheckClip(short nPlayer) @@ -397,7 +398,7 @@ void MoveWeapons(short nPlayer) if (!WeaponCanFire(nPlayer)) { if (!dword_96E22) { - D3PlayFX(StaticSound[4], PlayerList[nPlayer].nSprite); + D3PlayFX(StaticSound[4], PlayerList[nPlayer].Actor()); } } else @@ -441,7 +442,7 @@ void MoveWeapons(short nPlayer) PlayerList[nPlayer].field_3A = 3; PlayerList[nPlayer].field_3FOUR = 0; - PlayerList[nPlayer].nPistolClip = std::min(6, PlayerList[nPlayer].nAmmo[kWeaponPistol]); + PlayerList[nPlayer].nPistolClip = min(6, PlayerList[nPlayer].nAmmo[kWeaponPistol]); break; } else if (nWeapon == kWeaponGrenade) @@ -631,7 +632,7 @@ loc_flag: if (((!(nSectFlag & kSectUnderwater)) || nWeapon == kWeaponRing) && (nFrameFlag & 4)) { - BuildFlash(nPlayer, pPlayerSprite->sectnum, 512); + BuildFlash(nPlayer, 512); AddFlash( pPlayerSprite->sectnum, pPlayerSprite->x, @@ -727,9 +728,9 @@ loc_flag: var_28 = 9; } - int cRange = CheckCloseRange(nPlayer, &theX, &theY, &theZ, &nSectorB); + auto cRange = CheckCloseRange(nPlayer, &theX, &theY, &theZ, &nSectorB); - if (cRange) + if (cRange.type != kHitNone) { short nDamage = BulletInfo[kWeaponSword].nDamage; @@ -737,17 +738,16 @@ loc_flag: nDamage *= 2; } - if ((cRange & 0xC000) >= 0x8000) + //if (cRange.type != kHitNone) { - if ((cRange & 0xC000) == 0x8000) // hit wall + if (cRange.type == kHitWall) { // loc_2730E: var_28 += 2; } - else if ((cRange & 0xC000) == 0xC000) // hit sprite + else if (cRange.type == kHitSprite) { - //short nSprite2 = cRange & 0x3FFF; - auto pActor2 = &exhumedActors[cRange & 0x3FFF]; + auto pActor2 = cRange.actor; auto pSprite2 = &pActor2->s(); if (pSprite2->cstat & 0x50) @@ -824,27 +824,22 @@ loc_flag: int h = PlayerList[nLocalPlayer].horizon.horiz.asq16() >> 14; nHeight -= h; - int target = 0; - bool gottarg = false; - if (sPlayerInput[nPlayer].nTarget >= 0 && Autoaim(nPlayer)) + DExhumedActor* target = nullptr; + if (sPlayerInput[nPlayer].pTarget != nullptr && Autoaim(nPlayer)) { - int t = sPlayerInput[nPlayer].nTarget; - if (t >= 0 && t < MAXSPRITES) + auto t = sPlayerInput[nPlayer].pTarget; + // only autoaim if target is in front of the player. + auto pTargetSprite = &t->s(); + assert(pTargetSprite->sectnum < kMaxSectors); + int angletotarget = bvectangbam(pTargetSprite->x - pPlayerSprite->x, pTargetSprite->y - pPlayerSprite->y).asbuild(); + int anglediff = (pPlayerSprite->ang - angletotarget) & 2047; + if (anglediff < 512 || anglediff > 1536) { - // only autoaim if target is in front of the player. - auto pTargetSprite = &sprite[t]; - assert(pTargetSprite->sectnum < kMaxSectors); - int angletotarget = bvectangbam(pTargetSprite->x - pPlayerSprite->x, pTargetSprite->y - pPlayerSprite->y).asbuild(); - int anglediff = (pPlayerSprite->ang - angletotarget) & 2047; - if (anglediff < 512 || anglediff > 1536) - { - target = t; - gottarg = true; - } + target = t; } } - BuildBullet(pPlayerActor, nAmmoType, nHeight, nAngle,gottarg? &exhumedActors[target] : nullptr, var_1C); + BuildBullet(pPlayerActor, nAmmoType, nHeight, nAngle, target, var_1C); break; } diff --git a/source/games/exhumed/src/init.cpp b/source/games/exhumed/src/init.cpp index 2392f46e9..ba9d9bdb1 100644 --- a/source/games/exhumed/src/init.cpp +++ b/source/games/exhumed/src/init.cpp @@ -41,7 +41,8 @@ enum }; int initx, inity, initz; -short inita, initsect; +short inita; +int initsect; short nCurChunkNum = 0; @@ -51,7 +52,7 @@ int movefifopos; short nCurBodyGunNum; -short SectSoundSect[kMaxSectors] = { 0 }; +int SectSoundSect[kMaxSectors] = { 0 }; short SectSound[kMaxSectors] = { 0 }; short SectFlag[kMaxSectors] = { 0 }; int SectDepth[kMaxSectors] = { 0 }; @@ -88,7 +89,7 @@ uint8_t LoadLevel(MapRecord* map) nCreaturesKilled = 0; nCreaturesTotal = 0; nFreeze = 0; - nSpiritSprite = -1; + pSpiritSprite = nullptr; PlayClock = 0; memset(Counters, 0, sizeof(Counters)); @@ -104,7 +105,6 @@ uint8_t LoadLevel(MapRecord* map) InitPushBlocks(); InitPlayer(); InitItems(); - InitInput(); if (map->gameflags & LEVEL_EX_COUNTDOWN) { InitEnergyTile(); @@ -136,7 +136,7 @@ uint8_t LoadLevel(MapRecord* map) for (i = 0; i < kMaxPlayers; i++) { - PlayerList[i].nSprite = -1; + PlayerList[i].pActor = nullptr; } psky_t* pSky = tileSetupSky(DEFAULTPSKY); @@ -215,16 +215,16 @@ void SetAbove(short nCurSector, short nAboveSector) SectAbove[nCurSector] = nAboveSector; } -void SnapSectors(short nSectorA, short nSectorB, short b) +void SnapSectors(int nSectorA, int nSectorB, int b) { // edx - nSectorA // eax - nSectorB - short nWallA = sector[nSectorA].wallptr; - short nWallB = sector[nSectorB].wallptr; + int nWallA = sector[nSectorA].wallptr; + int nWallB = sector[nSectorB].wallptr; - short num1 = sector[nSectorA].wallnum; - short num2 = sector[nSectorB].wallnum; + int num1 = sector[nSectorA].wallnum; + int num2 = sector[nSectorB].wallnum; int nCount = 0; @@ -319,9 +319,8 @@ void InitSectFlag() } } -void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) +void ProcessSpriteTag(DExhumedActor* pActor, short nLotag, short nHitag) { - auto pActor = &exhumedActors[nSprite]; auto pSprite = &pActor->s(); int nChannel = runlist_AllocChannel(nHitag % 1000); @@ -334,7 +333,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) if (nLotag >= 900 && nLotag <= 949) { - ProcessTrailSprite(nSprite, nLotag, nHitag); + ProcessTrailSprite(pActor, nLotag, nHitag); return; } @@ -632,7 +631,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case 99: // underwater type 2 { - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; SetAbove(nSector, nHitag); SectFlag[nSector] |= kSectUnderwater; @@ -641,7 +640,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case 98: { - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; SetBelow(nSector, nHitag); SnapSectors(nSector, nHitag, 1); @@ -662,7 +661,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) nDamage = 1; } - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; SectDamage[nSector] = nDamage; SectFlag[nSector] |= kSectLava; @@ -679,7 +678,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case 94: // water { - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; SectDepth[nSector] = nHitag << 8; DeleteActor(pActor); @@ -692,13 +691,13 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case 90: { - BuildObject(nSprite, 3, nHitag); + BuildObject(pActor, 3, nHitag); return; } case 79: case 89: { - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; SectSpeed[nSector] = nSpeed; SectFlag[nSector] |= pSprite->ang; @@ -715,7 +714,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case 80: // underwater { - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; SectFlag[nSector] |= kSectUnderwater; DeleteActor(pActor); @@ -725,7 +724,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) { AddFlow(pSprite->sectnum, nSpeed, 1, pSprite->ang); - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; SectFlag[nSector] |= 0x8000; DeleteActor(pActor); @@ -740,12 +739,12 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case 76: // Explosion Trigger (Exploding Fire Cauldron) { - BuildObject(nSprite, 0, nHitag); + BuildObject(pActor, 0, nHitag); return; } case 75: // Explosion Target (Cauldrons, fireballs and grenades will destroy nearby 75 sprites) { - BuildObject(nSprite, 1, nHitag); + BuildObject(pActor, 1, nHitag); return; } case 71: @@ -757,7 +756,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case 70: { - BuildDrip(nSprite); + BuildDrip(pActor); return; } case 63: @@ -776,7 +775,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag) } case kTagRamses: // Ramses head { - nSpiritSprite = nSprite; + pSpiritSprite = pActor; pSprite->cstat |= 0x8000; return; } @@ -812,7 +811,7 @@ void ExamineSprites() pSprite->lotag = 0; pSprite->hitag = 0; - ProcessSpriteTag(ac->GetSpriteIndex(), lotag, hitag); + ProcessSpriteTag(ac, lotag, hitag); } else { @@ -849,17 +848,18 @@ void LoadObjects() for (int nSector = 0; nSector < numsectors; nSector++) { - short hitag = sector[nSector].hitag; - short lotag = sector[nSector].lotag; + auto sectp = §or[nSector]; + short hitag = sectp->hitag; + short lotag = sectp->lotag; - sector[nSector].hitag = 0; - sector[nSector].lotag = 0; - sector[nSector].extra = -1; + sectp->hitag = 0; + sectp->lotag = 0; + sectp->extra = -1; if (hitag || lotag) { - sector[nSector].lotag = runlist_HeadRun() + 1; - sector[nSector].hitag = lotag; + sectp->lotag = runlist_HeadRun() + 1; + sectp->hitag = lotag; runlist_ProcessSectorTag(nSector, lotag, hitag); } diff --git a/source/games/exhumed/src/input.cpp b/source/games/exhumed/src/input.cpp index 1801b721c..95f96f998 100644 --- a/source/games/exhumed/src/input.cpp +++ b/source/games/exhumed/src/input.cpp @@ -25,45 +25,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS -short nInputStack = 0; - -short bStackNode[kMaxPlayers]; - -short nTypeStack[kMaxPlayers]; PlayerInput sPlayerInput[kMaxPlayers]; -int *pStackPtr; - -// (nInputStack * 32) - 11; - -void PushInput(PlayerInput *pInput, int edx) -{ - if (!bStackNode[edx]) - { -// memcpy(sInputStack[nInputStack], pInput, - } -} - -int PopInput() -{ - if (!nInputStack) - return -1; - - nInputStack--; - - // TEMP - return 0; -} - -void InitInput() -{ - memset(nTypeStack, 0, sizeof(nTypeStack)); - nInputStack = 0; - memset(bStackNode, 0, sizeof(bStackNode)); - -// pStackPtr = &sInputStack; -} - void ClearSpaceBar(short nPlayer) { sPlayerInput[nPlayer].actions &= SB_OPEN; @@ -71,22 +34,6 @@ void ClearSpaceBar(short nPlayer) } -void BackupInput() -{ - -} - -void SendInput() -{ - -} - - -void CheckKeys2() -{ -} - - void GameInterface::GetInput(InputPacket* packet, ControlInfo* const hidInput) { if (paused || M_Active()) diff --git a/source/games/exhumed/src/input.h b/source/games/exhumed/src/input.h index f0fa8eb7a..b57eac2e7 100644 --- a/source/games/exhumed/src/input.h +++ b/source/games/exhumed/src/input.h @@ -33,10 +33,10 @@ enum { // 32 bytes struct PlayerInput { + DExhumedActor* pTarget; int xVel; int yVel; uint16_t buttons; - short nTarget; float nAngle; float pan; int8_t nItem; @@ -54,8 +54,6 @@ struct PlayerInput }; -void InitInput(); - void ClearSpaceBar(short nPlayer); int GetLocalInput(); diff --git a/source/games/exhumed/src/items.cpp b/source/games/exhumed/src/items.cpp index 29696bf44..6ad3da237 100644 --- a/source/games/exhumed/src/items.cpp +++ b/source/games/exhumed/src/items.cpp @@ -146,7 +146,7 @@ void BuildItemAnim(DExhumedActor* pActor) void DestroyItemAnim(DExhumedActor* actor) { - if (actor && actor->s().owner == 0) + if (actor && actor->s().owner >= 0) DestroyAnim(actor); } @@ -184,7 +184,7 @@ static bool UseEye(short nPlayer) pSprite->cstat |= 0x8000; - if (PlayerList[nPlayer].nPlayerFloorSprite >= 0) { + if (PlayerList[nPlayer].pPlayerFloorSprite != nullptr) { pSprite->cstat |= 0x8000; } diff --git a/source/games/exhumed/src/lavadude.cpp b/source/games/exhumed/src/lavadude.cpp index 83c50f8d7..3b7d24ab6 100644 --- a/source/games/exhumed/src/lavadude.cpp +++ b/source/games/exhumed/src/lavadude.cpp @@ -40,7 +40,7 @@ static actionSeq LavadudeSeq[] = { DExhumedActor* BuildLavaLimb(DExhumedActor* pActor, int move, int ebx) { auto pSprite = &pActor->s(); - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; auto pLimbActor = insertActor(nSector, 118); auto pLimbSprite = &pLimbActor->s(); @@ -103,13 +103,8 @@ void AILavaDudeLimb::Draw(RunListEvent* ev) seq_PlotSequence(ev->nParam, (SeqOffsets[kSeqLavag] + 30) + pActor->s().picnum, 0, 1); } -void FuncLavaLimb(int nObject, int nMessage, int nDamage, int nRun) -{ - AILavaDudeLimb ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} -void BuildLava(DExhumedActor* pActor, int x, int y, int, short nSector, short nAngle, int nChannel) +void BuildLava(DExhumedActor* pActor, int x, int y, int, int nSector, short nAngle, int nChannel) { spritetype* pSprite; if (pActor == nullptr) @@ -301,7 +296,7 @@ void AILavaDude::Tick(RunListEvent* ev) int x = pSprite->x; int y = pSprite->y; int z = pSprite->z; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; auto coll = movesprite(pActor, pSprite->xvel << 8, pSprite->yvel << 8, 0, 0, 0, CLIPMASK0); @@ -464,10 +459,4 @@ void AILavaDude::Tick(RunListEvent* ev) pSprite->pal = 1; } - -void FuncLava(int nObject, int nMessage, int nDamage, int nRun) -{ - AILavaDude ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/light.cpp b/source/games/exhumed/src/light.cpp index 84db404ec..2456e0f1c 100644 --- a/source/games/exhumed/src/light.cpp +++ b/source/games/exhumed/src/light.cpp @@ -46,9 +46,7 @@ const char *GradList[kMaxGrads] = { int rtint = 0; int gtint = 0; int btint = 0; -//char *origpalookup[kMaxPalookups]; -//unsigned char curpal[768]; -//unsigned char kenpal[768]; + palette_t *fadedestpal; palette_t *fadecurpal; short nPalDelay; diff --git a/source/games/exhumed/src/lighting.cpp b/source/games/exhumed/src/lighting.cpp index 04d376050..af9cf2ea7 100644 --- a/source/games/exhumed/src/lighting.cpp +++ b/source/games/exhumed/src/lighting.cpp @@ -49,21 +49,21 @@ struct Glow { short field_0; short field_2; - short nSector; + int nSector; short field_6; }; struct Flicker { short field_0; - short nSector; + int nSector; unsigned int field_4; }; struct Flow { - short objindex; - short type; + int objindex; + int type; int xdelta; int ydelta; int angcos; @@ -212,9 +212,10 @@ void InitLights() nLastFlash = -1; } -void AddFlash(short nSector, int x, int y, int z, int val) +void AddFlash(int nSector, int x, int y, int z, int val) { assert(nSector >= 0 && nSector < kMaxSectors); + auto sectp = §or[nSector]; int var_28 = 0; int var_1C = val >> 8; @@ -230,8 +231,8 @@ void AddFlash(short nSector, int x, int y, int z, int val) int var_14 = 0; - short startwall = sector[nSector].wallptr; - short endwall = sector[nSector].wallptr + sector[nSector].wallnum; + int startwall = sectp->wallptr; + int endwall = sectp->wallptr + sectp->wallnum; for (int i = startwall; i < endwall; i++) { @@ -271,7 +272,7 @@ void AddFlash(short nSector, int x, int y, int z, int val) if (wall[i].pal < 5) { - if (!pNextSector || pNextSector->floorz < sector[nSector].floorz) + if (!pNextSector || pNextSector->floorz < sectp->floorz) { short nFlash = GrabFlash(); if (nFlash < 0) { @@ -302,7 +303,7 @@ void AddFlash(short nSector, int x, int y, int z, int val) } } - if (var_14 && sector[nSector].floorpal < 4) + if (var_14 && sectp->floorpal < 4) { short nFlash = GrabFlash(); if (nFlash < 0) { @@ -311,40 +312,40 @@ void AddFlash(short nSector, int x, int y, int z, int val) sFlash[nFlash].nType = var_20 | 1; sFlash[nFlash].nIndex = nSector; - sFlash[nFlash].shade = sector[nSector].floorshade; + sFlash[nFlash].shade = sectp->floorshade; - sector[nSector].floorpal += 7; + sectp->floorpal += 7; - int edx = sector[nSector].floorshade + var_28; + int edx = sectp->floorshade + var_28; int eax = edx; if (edx < -127) { eax = -127; } - sector[nSector].floorshade = eax; + sectp->floorshade = eax; - if (!(sector[nSector].ceilingstat & 1)) + if (!(sectp->ceilingstat & 1)) { - if (sector[nSector].ceilingpal < 4) + if (sectp->ceilingpal < 4) { short nFlash2 = GrabFlash(); if (nFlash2 >= 0) { sFlash[nFlash2].nType = var_20 | 3; sFlash[nFlash2].nIndex = nSector; - sFlash[nFlash2].shade = sector[nSector].ceilingshade; + sFlash[nFlash2].shade = sectp->ceilingshade; - sector[nSector].ceilingpal += 7; + sectp->ceilingpal += 7; - int edx = sector[nSector].ceilingshade + var_28; + int edx = sectp->ceilingshade + var_28; int eax = edx; if (edx < -127) { eax = -127; } - sector[nSector].ceilingshade = eax; + sectp->ceilingshade = eax; } } } @@ -403,12 +404,12 @@ void UndoFlashes() int edi = -1; - for (short nFlash = nFirstFlash; nFlash >= 0; nFlash = sFlash[nFlash].next) + for (int nFlash = nFirstFlash; nFlash >= 0; nFlash = sFlash[nFlash].next) { assert(nFlash < 2000 && nFlash >= 0); uint8_t type = sFlash[nFlash].nType & 0x3F; - short nIndex = sFlash[nFlash].nIndex; + int nIndex = sFlash[nFlash].nIndex; if (sFlash[nFlash].nType & 0x80) { @@ -540,7 +541,7 @@ loc_1868A: } } -void AddGlow(short nSector, int nVal) +void AddGlow(int nSector, int nVal) { if (nGlowCount >= kMaxGlows) { return; @@ -555,7 +556,7 @@ void AddGlow(short nSector, int nVal) } // ok -void AddFlicker(short nSector, int nVal) +void AddFlicker(int nSector, int nVal) { if (nFlickerCount >= kMaxFlickers) { return; @@ -587,7 +588,8 @@ void DoGlows() { sGlow[i].field_2++; - short nSector = sGlow[i].nSector; + int nSector =sGlow[i].nSector; + auto sectp = §or[nSector]; short nShade = sGlow[i].field_0; if (sGlow[i].field_2 >= sGlow[i].field_6) @@ -596,11 +598,11 @@ void DoGlows() sGlow[i].field_0 = -sGlow[i].field_0; } - sector[nSector].ceilingshade += nShade; - sector[nSector].floorshade += nShade; + sectp->ceilingshade += nShade; + sectp->floorshade += nShade; - int startwall = sector[nSector].wallptr; - int endwall = startwall + sector[nSector].wallnum - 1; + int startwall = sectp->wallptr; + int endwall = startwall + sectp->wallnum - 1; for (int nWall = startwall; nWall <= endwall; nWall++) { @@ -620,8 +622,9 @@ void DoFlickers() for (int i = 0; i < nFlickerCount; i++) { - short nSector = sFlicker[i].nSector; - + int nSector =sFlicker[i].nSector; + auto sectp = §or[nSector]; + unsigned int eax = (sFlicker[i].field_4 & 1); unsigned int edx = (sFlicker[i].field_4 & 1) << 31; unsigned int ebp = sFlicker[i].field_4 >> 1; @@ -644,11 +647,11 @@ void DoFlickers() shade = -sFlicker[i].field_0; } - sector[nSector].ceilingshade += shade; - sector[nSector].floorshade += shade; + sectp->ceilingshade += shade; + sectp->floorshade += shade; - int startwall = sector[nSector].wallptr; - int endwall = startwall + sector[nSector].wallnum - 1; + int startwall = sectp->wallptr; + int endwall = startwall + sectp->wallnum - 1; for (int nWall = endwall; nWall >= startwall; nWall--) { @@ -725,7 +728,7 @@ void DoFlows() sFlowInfo[i].xdelta &= sFlowInfo[i].xacc; sFlowInfo[i].ydelta &= sFlowInfo[i].yacc; - short nSector = sFlowInfo[i].objindex; + int nSector =sFlowInfo[i].objindex; sector[nSector].setfloorxpan(sFlowInfo[i].xdelta / 16384.f); sector[nSector].setfloorypan(sFlowInfo[i].ydelta / 16384.f); break; @@ -733,7 +736,7 @@ void DoFlows() case 1: { - short nSector = sFlowInfo[i].objindex; + int nSector =sFlowInfo[i].objindex; sector[nSector].setceilingxpan(sFlowInfo[i].xdelta / 16384.f); sector[nSector].setceilingypan(sFlowInfo[i].ydelta / 16384.f); @@ -745,7 +748,7 @@ void DoFlows() case 2: { - short nWall = sFlowInfo[i].objindex; + int nWall = sFlowInfo[i].objindex; wall[nWall].setxpan(sFlowInfo[i].xdelta / 16384.f); wall[nWall].setypan(sFlowInfo[i].ydelta / 16384.f); @@ -765,7 +768,7 @@ void DoFlows() case 3: { - short nWall = sFlowInfo[i].objindex; + int nWall = sFlowInfo[i].objindex; wall[nWall].setxpan(sFlowInfo[i].xdelta / 16384.f); wall[nWall].setypan(sFlowInfo[i].ydelta / 16384.f); @@ -818,7 +821,7 @@ void SetTorch(int nPlayer, int bTorchOnOff) StatusMessage(150, GStrings(buf)); } -void BuildFlash(short nPlayer, short, int nVal) +void BuildFlash(int nPlayer, int nVal) { if (nPlayer == nLocalPlayer) { diff --git a/source/games/exhumed/src/lion.cpp b/source/games/exhumed/src/lion.cpp index 026fd87e5..91f33820d 100644 --- a/source/games/exhumed/src/lion.cpp +++ b/source/games/exhumed/src/lion.cpp @@ -41,7 +41,7 @@ static actionSeq LionSeq[] = { }; -void BuildLion(DExhumedActor* pActor, int x, int y, int z, short nSector, short nAngle) +void BuildLion(DExhumedActor* pActor, int x, int y, int z, int nSector, short nAngle) { spritetype* pSprite; if (pActor == nullptr) @@ -55,7 +55,7 @@ void BuildLion(DExhumedActor* pActor, int x, int y, int z, short nSector, short pSprite = &pActor->s(); x = pSprite->x; y = pSprite->y; - z = sector[pSprite->sectnum].floorz; + z = pSprite->sector()->floorz; nAngle = pSprite->ang; } @@ -68,7 +68,7 @@ void BuildLion(DExhumedActor* pActor, int x, int y, int z, short nSector, short pSprite->xrepeat = 40; pSprite->yrepeat = 40; pSprite->picnum = 1; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->ang = nAngle; @@ -140,7 +140,7 @@ void AILion::Damage(RunListEvent* ev) { DropMagic(pActor); - if (ev->nMessage == EMessageType::RadialDamage) + if (ev->isRadialEvent()) { pActor->nAction = 11; } @@ -555,12 +555,4 @@ void AILion::Tick(RunListEvent* ev) } } - - -void FuncLion(int nObject, int nMessage, int nDamage, int nRun) -{ - AILion ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/exhumed/src/map.cpp b/source/games/exhumed/src/map.cpp index bde79b458..55b7abd4e 100644 --- a/source/games/exhumed/src/map.cpp +++ b/source/games/exhumed/src/map.cpp @@ -88,7 +88,7 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a, double const s { int nTile = pSprite->picnum; int ceilZ, ceilHit, floorZ, floorHit; - getzrange_old(pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0); + getzrange(&pSprite->pos, pSprite->sectnum, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0); int nTop, nBottom; GetSpriteExtents(pSprite, &nTop, &nBottom); int nScale = (pSprite->yrepeat + ((floorZ - nBottom) >> 8)) * z; diff --git a/source/games/exhumed/src/move.cpp b/source/games/exhumed/src/move.cpp index ac83fdcdc..eb83372d0 100644 --- a/source/games/exhumed/src/move.cpp +++ b/source/games/exhumed/src/move.cpp @@ -30,17 +30,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS -short NearSector[kMaxSectors] = { 0 }; - short nPushBlocks; // TODO - moveme? short overridesect; -short NearCount = -1; DExhumedActor* nBodySprite[50]; -int hihit, sprceiling, sprfloor, lohit; +int sprceiling, sprfloor; +Collision loHit, hiHit; enum { @@ -58,7 +56,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, Bloc if (arc.BeginObject(keyname)) { arc("at8", w.field_8) - ("sprite", w.nSprite) + ("sprite", w.pActor) ("x", w.x) ("y", w.y) .EndObject(); @@ -70,17 +68,11 @@ void SerializeMove(FSerializer& arc) { if (arc.BeginObject("move")) { - arc("nearcount", NearCount) - .Array("nearsector", NearSector, NearCount) - ("pushcount", nPushBlocks) + arc ("pushcount", nPushBlocks) .Array("blocks", sBlockInfo, nPushBlocks) ("chunkcount", nCurChunkNum) .Array("chunks", nChunkSprite, kMaxMoveChunks) ("overridesect", overridesect) - ("hihit", hihit) - ("lohit", lohit) - ("sprceiling", sprceiling) - ("sprfloor", sprfloor) .Array("bodysprite", nBodySprite, 50) .EndObject(); } @@ -231,19 +223,19 @@ void clipwall() } -void BuildNear(int x, int y, int walldist, int nSector) +int BelowNear(DExhumedActor* pActor, int x, int y, int walldist, int nSector) { - NearSector[0] = nSector; - NearCount = 1; + unsigned nearstart = GlobalSectorList.Size(); + GlobalSectorList.Push(nSector); - int i = 0; + unsigned i = nearstart; - while (i < NearCount) + while (i < GlobalSectorList.Size()) { - short nSector = NearSector[i]; + int nSector = GlobalSectorList[i]; - short nWall = sector[nSector].wallptr; - short nWallCount = sector[nSector].wallnum; + int nWall = sector[nSector].wallptr; + int nWallCount = sector[nSector].wallnum; while (1) { @@ -258,21 +250,20 @@ void BuildNear(int x, int y, int walldist, int nSector) if (nNextSector >= 0) { - int j = 0; - for (; j < NearCount; j++) + unsigned j = nearstart; + for (; j < GlobalSectorList.Size(); j++) { // loc_14F4D: - if (nNextSector == NearSector[j]) + if (nNextSector == GlobalSectorList[j]) break; } - if (j >= NearCount) + if (j >= GlobalSectorList.Size()) { vec2_t pos = { x, y }; if (clipinsidebox(&pos, nWall, walldist)) { - NearSector[NearCount] = wall[nWall].nextsector; - NearCount++; + GlobalSectorList.Push(wall[nWall].nextsector); } } } @@ -280,32 +271,28 @@ void BuildNear(int x, int y, int walldist, int nSector) nWall++; } } -} -int BelowNear(DExhumedActor* pActor) -{ - auto pSprite = &pActor->s(); - short nSector = pSprite->sectnum; + auto pSprite = &pActor->s(); + nSector = pSprite->sectnum; int z = pSprite->z; - int var_24, z2; + int z2; - if ((lohit & 0xC000) == 0xC000) + if (loHit.type == kHitSprite) { - var_24 = lohit & 0xC000; - z2 = sprite[lohit & 0x3FFF].z; + z2 = loHit.actor->s().z; } else { z2 = sector[nSector].floorz + SectDepth[nSector]; - if (NearCount > 0) + if (GlobalSectorList.Size() > nearstart) { short edx; - for (int i = 0; i < NearCount; i++) + for (unsigned i = nearstart; i < GlobalSectorList.Size(); i++) { - int nSect2 = NearSector[i]; + int nSect2 = GlobalSectorList[i]; while (nSect2 >= 0) { @@ -324,6 +311,7 @@ int BelowNear(DExhumedActor* pActor) } } } + GlobalSectorList.Resize(nearstart); if (z2 < pSprite->z) { @@ -333,7 +321,7 @@ int BelowNear(DExhumedActor* pActor) bTouchFloor = true; - return 0x20000; + return kHitAux2; } else { @@ -341,10 +329,10 @@ int BelowNear(DExhumedActor* pActor) } } -int movespritez(short nSprite, int z, int height, int, int clipdist) +Collision movespritez(DExhumedActor* pActor, int z, int height, int, int clipdist) { - spritetype* pSprite = &sprite[nSprite]; - short nSector = pSprite->sectnum; + spritetype* pSprite = &pActor->s(); + int nSector =pSprite->sectnum; assert(nSector >= 0 && nSector < kMaxSectors); overridesect = nSector; @@ -355,7 +343,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; - int nRet = 0; + Collision nRet(0); short nSectFlags = SectFlag[nSector]; @@ -374,11 +362,11 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) } // loc_151E7: - while (ebp > sector[pSprite->sectnum].floorz && SectBelow[pSprite->sectnum] >= 0) + while (ebp > pSprite->sector()->floorz && SectBelow[pSprite->sectnum] >= 0) { edi = SectBelow[pSprite->sectnum]; - mychangespritesect(nSprite, edi); + ChangeActorSect(pActor, edi); } if (edi != nSector) @@ -387,8 +375,8 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) if (SectFlag[edi] & kSectUnderwater) { - if (nSprite == PlayerList[nLocalPlayer].nSprite) { - D3PlayFX(StaticSound[kSound2], nSprite); + if (pActor == PlayerList[nLocalPlayer].Actor()) { + D3PlayFX(StaticSound[kSound2], pActor); } if (pSprite->statnum <= 107) { @@ -398,22 +386,27 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) } else { - while ((ebp < sector[pSprite->sectnum].ceilingz) && (SectAbove[pSprite->sectnum] >= 0)) + while ((ebp < pSprite->sector()->ceilingz) && (SectAbove[pSprite->sectnum] >= 0)) { edi = SectAbove[pSprite->sectnum]; - mychangespritesect(nSprite, edi); + ChangeActorSect(pActor, edi); } } // This function will keep the player from falling off cliffs when you're too close to the edge. // This function finds the highest and lowest z coordinates that your clipping BOX can get to. - getzrange_old(pSprite->x, pSprite->y, pSprite->z - 256, pSprite->sectnum, + int hihit, lohit; + vec3_t pos = pSprite->pos; + pos.z -= 256; + getzrange(&pSprite->pos, pSprite->sectnum, &sprceiling, &hihit, &sprfloor, &lohit, 128, CLIPMASK0); + hiHit.setFromEngine(hihit); + loHit.setFromEngine(lohit); int mySprfloor = sprfloor; - if ((lohit & 0xC000) != 0xC000) { + if (loHit.type != kHitSprite) { mySprfloor += SectDepth[pSprite->sectnum]; } @@ -423,30 +416,30 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) { bTouchFloor = true; - if ((lohit & 0xC000) == 0xC000) + if (loHit.type == kHitSprite) { // Path A - short nFloorSprite = lohit & 0x3FFF; + auto pFloorSprite = &loHit.actor->s(); - if (pSprite->statnum == 100 && sprite[nFloorSprite].statnum != 0 && sprite[nFloorSprite].statnum < 100) + if (pSprite->statnum == 100 && pFloorSprite->statnum != 0 && pFloorSprite->statnum < 100) { short nDamage = (z >> 9); if (nDamage) { - runlist_DamageEnemy(nFloorSprite, nSprite, nDamage << 1); + runlist_DamageEnemy(loHit.actor, pActor, nDamage << 1); } pSprite->zvel = -z; } else { - if (sprite[nFloorSprite].statnum == 0 || sprite[nFloorSprite].statnum > 199) + if (pFloorSprite->statnum == 0 || pFloorSprite->statnum > 199) { - nRet |= 0x20000; + nRet.exbits |= kHitAux2; } else { - nRet |= lohit; + nRet = loHit; } pSprite->zvel = 0; @@ -457,7 +450,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) // Path B if (SectBelow[pSprite->sectnum] == -1) { - nRet |= 0x20000; + nRet.exbits |= kHitAux2; short nSectDamage = SectDamage[pSprite->sectnum]; @@ -465,13 +458,13 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) { if (pSprite->hitag < 15) { - IgniteSprite(&exhumedActors[nSprite]); + IgniteSprite(pActor); pSprite->hitag = 20; } nSectDamage >>= 2; nSectDamage = nSectDamage - (nSectDamage>>2); if (nSectDamage) { - runlist_DamageEnemy(nSprite, -1, nSectDamage); + runlist_DamageEnemy(pActor, nullptr, nSectDamage); } } @@ -486,10 +479,10 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) } else { - if ((ebp - height) < sprceiling && ((hihit & 0xC000) == 0xC000 || SectAbove[pSprite->sectnum] == -1)) + if ((ebp - height) < sprceiling && (hiHit.type == kHitSprite || SectAbove[pSprite->sectnum] == -1)) { ebp = sprceiling + height; - nRet |= 0x10000; + nRet.exbits |= kHitAux1; } } @@ -498,7 +491,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) if ((SectDepth[nSector] != 0) || (edi != nSector && (SectFlag[edi] & kSectUnderwater))) { assert(nSector >= 0 && nSector < kMaxSectors); - BuildSplash(&exhumedActors[nSprite], nSector); + BuildSplash(pActor, nSector); } } @@ -507,19 +500,12 @@ int movespritez(short nSprite, int z, int height, int, int clipdist) if (pSprite->statnum == 100) { - BuildNear(pSprite->x, pSprite->y, clipdist + (clipdist / 2), pSprite->sectnum); - nRet |= BelowNear(&exhumedActors[nSprite]); + nRet.exbits |= BelowNear(pActor, pSprite->x, pSprite->y, clipdist + (clipdist / 2), pSprite->sectnum); } return nRet; } -int GetSpriteHeight(int nSprite) -{ - auto pSprite = &sprite[nSprite]; - return tileHeight(pSprite->picnum) * pSprite->yrepeat * 4; -} - int GetActorHeight(DExhumedActor* actor) { return tileHeight(actor->s().picnum) * actor->s().yrepeat * 4; @@ -532,39 +518,37 @@ DExhumedActor* insertActor(int sect, int stat) } -int movesprite(short nSprite, int dx, int dy, int dz, int, int flordist, unsigned int clipmask) +Collision movesprite(DExhumedActor* pActor, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask) { - spritetype *pSprite = &sprite[nSprite]; + spritetype *pSprite = &pActor->s(); bTouchFloor = false; int x = pSprite->x; int y = pSprite->y; int z = pSprite->z; - int nSpriteHeight = GetSpriteHeight(nSprite); + int nSpriteHeight = GetActorHeight(pActor); int nClipDist = (int8_t)pSprite->clipdist << 2; - short nSector = pSprite->sectnum; + int nSector = pSprite->sectnum; assert(nSector >= 0 && nSector < kMaxSectors); int floorZ = sector[nSector].floorz; - int nRet = 0; - if ((SectFlag[nSector] & kSectUnderwater) || (floorZ < z)) { dx >>= 1; dy >>= 1; } - nRet |= movespritez(nSprite, dz, nSpriteHeight, flordist, nClipDist); + Collision nRet = movespritez(pActor, dz, nSpriteHeight, flordist, nClipDist); nSector = pSprite->sectnum; // modified in movespritez so re-grab this variable if (pSprite->statnum == 100) { - short nPlayer = GetPlayerFromSprite(nSprite); + short nPlayer = GetPlayerFromActor(pActor); int varA = 0; int varB = 0; @@ -585,11 +569,17 @@ int movesprite(short nSprite, int dx, int dy, int dz, int, int flordist, unsigne CheckSectorFloor(overridesect, pSprite->z, &dx, &dy); } - nRet |= (uint16_t)clipmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask); + int colv = clipmove(&pSprite->pos, &nSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask); + Collision coll(colv); + if (coll.type != kHitNone) // originally this or'ed the two values which can create unpredictable bad values in some edge cases. + { + coll.exbits = nRet.exbits; + nRet = coll; + } if ((nSector != pSprite->sectnum) && nSector >= 0) { - if (nRet & 0x20000) { + if (nRet.exbits & kHitAux2) { dz = 0; } @@ -600,11 +590,11 @@ int movesprite(short nSprite, int dx, int dy, int dz, int, int flordist, unsigne } else { - mychangespritesect(nSprite, nSector); + ChangeActorSect(pActor, nSector); if (pSprite->pal < 5 && !pSprite->hitag) { - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; } } } @@ -615,7 +605,7 @@ int movesprite(short nSprite, int dx, int dy, int dz, int, int flordist, unsigne void Gravity(DExhumedActor* actor) { auto pSprite = &actor->s(); - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; if (SectFlag[nSector] & kSectUnderwater) { @@ -659,23 +649,23 @@ void Gravity(DExhumedActor* actor) } } -int MoveCreature(short nSprite) +Collision MoveCreature(DExhumedActor* pActor) { - auto pSprite = &sprite[nSprite]; - return movesprite(nSprite, pSprite->xvel << 8, pSprite->yvel << 8, pSprite->zvel, 15360, -5120, CLIPMASK0); + auto pSprite = &pActor->s(); + return movesprite(pActor, pSprite->xvel << 8, pSprite->yvel << 8, pSprite->zvel, 15360, -5120, CLIPMASK0); } -int MoveCreatureWithCaution(int nSprite) +Collision MoveCreatureWithCaution(DExhumedActor* pActor) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); int x = pSprite->x; int y = pSprite->y; int z = pSprite->z; short nSectorPre = pSprite->sectnum; - int ecx = MoveCreature(nSprite); + auto ecx = MoveCreature(pActor); - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; if (nSector != nSectorPre) { @@ -690,12 +680,12 @@ int MoveCreatureWithCaution(int nSprite) pSprite->y = y; pSprite->z = z; - mychangespritesect(nSprite, nSectorPre); + ChangeActorSect(pActor, nSectorPre); pSprite->ang = (pSprite->ang + 256) & kAngleMask; pSprite->xvel = bcos(pSprite->ang, -2); pSprite->yvel = bsin(pSprite->ang, -2); - return 0; + return Collision(0); } } @@ -713,13 +703,13 @@ int GetAngleToSprite(DExhumedActor* a1, DExhumedActor* a2) return GetMyAngle(pSprite2->x - pSprite1->x, pSprite2->y - pSprite1->y); } -int PlotCourseToSprite(int nSprite1, int nSprite2) +int PlotCourseToSprite(DExhumedActor* pActor1, DExhumedActor* pActor2) { - if (nSprite1 < 0 || nSprite2 < 0) + if (pActor1 == nullptr || pActor2 == nullptr) return -1; - auto pSprite1 = &sprite[nSprite1]; - auto pSprite2 = &sprite[nSprite2]; + auto pSprite1 = &pActor1->s(); + auto pSprite2 = &pActor2->s(); int x = pSprite2->x - pSprite1->x; int y = pSprite2->y - pSprite1->y; @@ -739,46 +729,42 @@ int PlotCourseToSprite(int nSprite1, int nSprite2) return ksqrt(diff); } -int FindPlayer(int nSprite, int nDistance, bool dontengage) +DExhumedActor* FindPlayer(DExhumedActor* pActor, int nDistance, bool dontengage) { - auto pSprite = &sprite[nSprite]; - int var_18 = 0; - if (nSprite >= 0 || !dontengage) - var_18 = 1; - - if (nSprite < 0) - nSprite = -nSprite; + auto pSprite = &pActor->s(); + int var_18 = !dontengage; if (nDistance < 0) nDistance = 100; int x = pSprite->x; int y = pSprite->y; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; - int z = pSprite->z - GetSpriteHeight(nSprite); + int z = pSprite->z - GetActorHeight(pActor); nDistance <<= 8; - short nPlayerSprite; + DExhumedActor* pPlayerActor = nullptr; int i = 0; while (1) { if (i >= nTotalPlayers) - return -1; + return nullptr; - nPlayerSprite = PlayerList[i].nSprite; + pPlayerActor = PlayerList[i].Actor(); + auto pPlayerSprite = &pPlayerActor->s(); - if ((sprite[nPlayerSprite].cstat & 0x101) && (!(sprite[nPlayerSprite].cstat & 0x8000))) + if ((pPlayerSprite->cstat & 0x101) && (!(pPlayerSprite->cstat & 0x8000))) { - int v9 = abs(sprite[nPlayerSprite].x - x); + int v9 = abs(pPlayerSprite->x - x); if (v9 < nDistance) { - int v10 = abs(sprite[nPlayerSprite].y - y); + int v10 = abs(pPlayerSprite->y - y); - if (v10 < nDistance && cansee(sprite[nPlayerSprite].x, sprite[nPlayerSprite].y, sprite[nPlayerSprite].z - 7680, sprite[nPlayerSprite].sectnum, x, y, z, nSector)) + if (v10 < nDistance && cansee(pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z - 7680, pPlayerSprite->sectnum, x, y, z, nSector)) { break; } @@ -789,13 +775,13 @@ int FindPlayer(int nSprite, int nDistance, bool dontengage) } if (var_18) { - PlotCourseToSprite(nSprite, nPlayerSprite); + PlotCourseToSprite(pActor, pPlayerActor); } - return nPlayerSprite; + return pPlayerActor; } -void CheckSectorFloor(short nSector, int z, int *x, int *y) +void CheckSectorFloor(int nSector, int z, int *x, int *y) { short nSpeed = SectSpeed[nSector]; @@ -818,10 +804,10 @@ void CheckSectorFloor(short nSector, int z, int *x, int *y) } } -int GetUpAngle(short nSprite1, int nVal, short nSprite2, int ecx) +int GetUpAngle(DExhumedActor* pActor1, int nVal, DExhumedActor* pActor2, int ecx) { - auto pSprite1 = &sprite[nSprite1]; - auto pSprite2 = &sprite[nSprite2]; + auto pSprite1 = &pActor1->s(); + auto pSprite2 = &pActor2->s(); int x = pSprite2->x - pSprite1->x; int y = pSprite2->y - pSprite1->y; @@ -856,11 +842,12 @@ int GrabPushBlock() void CreatePushBlock(int nSector) { + auto sectp = §or[nSector]; int nBlock = GrabPushBlock(); int i; - int startwall = sector[nSector].wallptr; - int nWalls = sector[nSector].wallnum; + int startwall = sectp->wallptr; + int nWalls = sectp->wallnum; int xSum = 0; int ySum = 0; @@ -877,14 +864,14 @@ void CreatePushBlock(int nSector) sBlockInfo[nBlock].x = xAvg; sBlockInfo[nBlock].y = yAvg; - int nSprite = insertsprite(nSector, 0); - auto pSprite = &sprite[nSprite]; + auto pActor = insertActor(nSector, 0); + auto pSprite = &pActor->s(); - sBlockInfo[nBlock].nSprite = nSprite; + sBlockInfo[nBlock].pActor = pActor; pSprite->x = xAvg; pSprite->y = yAvg; - pSprite->z = sector[nSector].floorz - 256; + pSprite->z = sectp->floorz - 256; pSprite->cstat = 0x8000; int var_28 = 0; @@ -911,10 +898,10 @@ void CreatePushBlock(int nSector) sBlockInfo[nBlock].field_8 = var_28; pSprite->clipdist = (var_28 & 0xFF) << 2; - sector[nSector].extra = nBlock; + sectp->extra = nBlock; } -void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel) +void MoveSector(int nSector, int nAngle, int *nXVel, int *nYVel) { if (nSector == -1) { return; @@ -933,52 +920,54 @@ void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel) nXVect = bcos(nAngle, 6); nYVect = bsin(nAngle, 6); } + sectortype *pSector = §or[nSector]; + - short nBlock = sector[nSector].extra; + short nBlock = pSector->extra; short nSectFlag = SectFlag[nSector]; - sectortype *pSector = §or[nSector]; - int nFloorZ = sector[nSector].floorz; - int startwall = sector[nSector].wallptr; - int nWalls = sector[nSector].wallnum; + int nFloorZ = pSector->floorz; + int startwall = pSector->wallptr; + int nWalls = pSector->wallnum; walltype *pStartWall = &wall[startwall]; short nNextSector = wall[startwall].nextsector; BlockInfo *pBlockInfo = &sBlockInfo[nBlock]; - int x = sBlockInfo[nBlock].x; + vec3_t pos; + + pos.x = sBlockInfo[nBlock].x; int x_b = sBlockInfo[nBlock].x; - int y = sBlockInfo[nBlock].y; + pos.y = sBlockInfo[nBlock].y; int y_b = sBlockInfo[nBlock].y; - short nSectorB = nSector; + int nSectorB = nSector; int nZVal; - int z; int bUnderwater = nSectFlag & kSectUnderwater; if (nSectFlag & kSectUnderwater) { - nZVal = sector[nSector].ceilingz; - z = sector[nNextSector].ceilingz + 256; + nZVal = pSector->ceilingz; + pos.z = sector[nNextSector].ceilingz + 256; - sector[nSector].ceilingz = sector[nNextSector].ceilingz; + pSector->ceilingz = sector[nNextSector].ceilingz; } else { - nZVal = sector[nSector].floorz; - z = sector[nNextSector].floorz - 256; + nZVal = pSector->floorz; + pos.z = sector[nNextSector].floorz - 256; - sector[nSector].floorz = sector[nNextSector].floorz; + pSector->floorz = sector[nNextSector].floorz; } - clipmove_old((int32_t*)&x, (int32_t*)&y, (int32_t*)&z, &nSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1); + clipmove(&pos, &nSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1); - int yvect = y - y_b; - int xvect = x - x_b; + int yvect = pos.y - y_b; + int xvect = pos.x - x_b; if (nSectorB != nNextSector && nSectorB != nSector) { @@ -989,15 +978,13 @@ void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel) { if (!bUnderwater) { - z = nZVal; - x = x_b; - y = y_b; + pos = { x_b, y_b, nZVal }; - clipmove_old((int32_t*)&x, (int32_t*)&y, (int32_t*)&z, &nSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1); + clipmove(&pos, &nSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1); - int ebx = x; + int ebx = pos.x; int ecx = x_b; - int edx = y; + int edx = pos.y; int eax = xvect; int esi = y_b; @@ -1051,15 +1038,15 @@ void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel) } else { - z = sp->z; + pos.z = sp->z; - if ((nSectFlag & kSectUnderwater) || z != nZVal || sp->cstat & 0x8000) + if ((nSectFlag & kSectUnderwater) || pos.z != nZVal || sp->cstat & 0x8000) { - x = sp->x; - y = sp->y; + pos.x = sp->x; + pos.y = sp->y; nSectorB = nSector; - clipmove_old(&x, &y, &z, &nSectorB, -xvect, -yvect, 4 * sp->clipdist, 0, 0, CLIPMASK0); + clipmove(&pos, &nSectorB, -xvect, -yvect, 4 * sp->clipdist, 0, 0, CLIPMASK0); if (nSectorB >= 0 && nSectorB < kMaxSectors && nSectorB != nSector) { ChangeActorSect(pActor, nSectorB); @@ -1074,12 +1061,10 @@ void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel) auto pSprite = &pActor->s(); if (pSprite->statnum >= 99) { - x = pSprite->x; - y = pSprite->y; - z = pSprite->z; + pos = pSprite->pos; nSectorB = nNextSector; - clipmove_old((int32_t*)&x, (int32_t*)&y, (int32_t*)&z, &nSectorB, + clipmove(&pos, &nSectorB, -xvect - (bcos(nAngle) * (4 * pSprite->clipdist)), -yvect - (bsin(nAngle) * (4 * pSprite->clipdist)), 4 * pSprite->clipdist, 0, 0, CLIPMASK0); @@ -1128,7 +1113,7 @@ void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel) if (pSprite->statnum >= 99 && nZVal == pSprite->z && !(pSprite->cstat & 0x8000)) { nSectorB = nSector; - clipmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSectorB, xvect, yvect, 4 * pSprite->clipdist, 5120, -5120, CLIPMASK0); + clipmove(&pSprite->pos, &nSectorB, xvect, yvect, 4 * pSprite->clipdist, 5120, -5120, CLIPMASK0); } } } @@ -1158,9 +1143,9 @@ void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel) initsect = pSprite->sectnum; } -void SetQuake(short nSprite, int nVal) +void SetQuake(DExhumedActor* pActor, int nVal) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); int x = pSprite->x; int y = pSprite->y; @@ -1168,10 +1153,11 @@ void SetQuake(short nSprite, int nVal) for (int i = 0; i < nTotalPlayers; i++) { - int nPlayerSprite = PlayerList[i].nSprite; + auto pPlayerActor = PlayerList[i].Actor(); - uint32_t xDiff = abs((int32_t)((sprite[nPlayerSprite].x - x) >> 8)); - uint32_t yDiff = abs((int32_t)((sprite[nPlayerSprite].y - y) >> 8)); + + uint32_t xDiff = abs((int32_t)((pPlayerActor->s().x - x) >> 8)); + uint32_t yDiff = abs((int32_t)((pPlayerActor->s().y - y) >> 8)); uint32_t sqrtNum = xDiff * xDiff + yDiff * yDiff; @@ -1207,9 +1193,9 @@ void SetQuake(short nSprite, int nVal) } } -int AngleChase(int nSprite, int nSprite2, int ebx, int ecx, int push1) +Collision AngleChase(DExhumedActor* pActor, DExhumedActor* pActor2, int ebx, int ecx, int push1) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); int nClipType = pSprite->statnum != 107; /* bjd - need to handle cliptype to clipmask change that occured in later build engine version */ @@ -1222,14 +1208,14 @@ int AngleChase(int nSprite, int nSprite2, int ebx, int ecx, int push1) short nAngle; - if (nSprite2 < 0) + if (pActor2 == nullptr) { pSprite->zvel = 0; nAngle = pSprite->ang; } else { - auto pSprite2 = &sprite[nSprite2]; + auto pSprite2 = &pActor2->s(); int nHeight = tileHeight(pSprite2->picnum) * pSprite2->yrepeat * 2; @@ -1300,10 +1286,10 @@ int AngleChase(int nSprite, int nSprite2, int ebx, int ecx, int push1) int z = bsin(pSprite->zvel) * ksqrt(sqrtNum); - return movesprite(nSprite, x >> 2, y >> 2, (z >> 13) + bsin(ecx, -5), 0, 0, nClipType); + return movesprite(pActor, x >> 2, y >> 2, (z >> 13) + bsin(ecx, -5), 0, 0, nClipType); } -int GetWallNormal(short nWall) +int GetWallNormal(int nWall) { nWall &= kMaxWalls-1; @@ -1313,20 +1299,18 @@ int GetWallNormal(short nWall) return (nAngle + 512) & kAngleMask; } -void WheresMyMouth(int nPlayer, int *x, int *y, int *z, short *sectnum) +void WheresMyMouth(int nPlayer, vec3_t* pos, int *sectnum) { auto pActor = PlayerList[nPlayer].Actor(); auto pSprite = &pActor->s(); - *x = pSprite->x; - *y = pSprite->y; + int height = GetActorHeight(pActor) >> 1; - int height = GetActorHeight(pActor) / 2; - - *z = pSprite->z - height; *sectnum = pSprite->sectnum; + *pos = pSprite->pos; + pos->z -= height; - clipmove_old((int32_t*)x, (int32_t*)y, (int32_t*)z, sectnum, + clipmove(pos, sectnum, bcos(pSprite->ang, 7), bsin(pSprite->ang, 7), 5120, 1280, 1280, CLIPMASK1); @@ -1438,34 +1422,21 @@ DExhumedActor* GrabChunkSprite() return pActor; } -int BuildCreatureChunk(int nVal, int nPic) +DExhumedActor* BuildCreatureChunk(DExhumedActor* pSrc, int nPic, bool bSpecial) { - int var_14; - auto actor = GrabChunkSprite(); if (actor == nullptr) { - return -1; + return nullptr; } auto pSprite = &actor->s(); + auto pSrcSpr = &pSrc->s(); - if (nVal & 0x4000) - { - nVal &= 0x3FFF; - var_14 = 1; - } - else - { - var_14 = 0; - } + pSprite->x = pSrcSpr->x; + pSprite->y = pSrcSpr->y; + pSprite->z = pSrcSpr->z; - nVal &= 0xFFFF; - - pSprite->x = sprite[nVal].x; - pSprite->y = sprite[nVal].y; - pSprite->z = sprite[nVal].z; - - ChangeActorSect(actor, sprite[nVal].sectnum); + ChangeActorSect(actor, pSrcSpr->sectnum); pSprite->cstat = 0x80; pSprite->shade = -12; @@ -1475,7 +1446,7 @@ int BuildCreatureChunk(int nVal, int nPic) pSprite->yvel = (RandomSize(5) - 16) << 7; pSprite->zvel = (-(RandomSize(8) + 512)) << 3; - if (var_14) + if (bSpecial) { pSprite->xvel *= 4; pSprite->yvel *= 4; @@ -1493,25 +1464,24 @@ int BuildCreatureChunk(int nVal, int nPic) // GrabTimeSlot(3); pSprite->extra = -1; - pSprite->owner = runlist_AddRunRec(pSprite->lotag - 1, actor->GetSpriteIndex(), 0xD0000); - pSprite->hitag = runlist_AddRunRec(NewRun, actor->GetSpriteIndex(), 0xD0000); + pSprite->owner = runlist_AddRunRec(pSprite->lotag - 1, actor, 0xD0000); + pSprite->hitag = runlist_AddRunRec(NewRun, actor, 0xD0000); - return actor->GetSpriteIndex(); + return actor; } void AICreatureChunk::Tick(RunListEvent* ev) { - int nSprite = RunData[ev->nRun].nObjIndex; - assert(nSprite >= 0 && nSprite < kMaxSprites); - auto pActor = &exhumedActors[nSprite]; - auto pSprite = &sprite[nSprite]; + auto pActor = ev->pObjActor; + if (!pActor) return; + auto pSprite = &pActor->s(); Gravity(pActor); int nSector = pSprite->sectnum; pSprite->pal = sector[nSector].ceilingpal; - int nVal = movesprite(nSprite, pSprite->xvel << 10, pSprite->yvel << 10, pSprite->zvel, 2560, -2560, CLIPMASK1); + auto nVal = movesprite(pActor, pSprite->xvel << 10, pSprite->yvel << 10, pSprite->zvel, 2560, -2560, CLIPMASK1); if (pSprite->z >= sector[nSector].floorz) { @@ -1525,31 +1495,31 @@ void AICreatureChunk::Tick(RunListEvent* ev) } else { - if (!nVal) + if (!nVal.type && !nVal.exbits) return; short nAngle; - if (nVal & 0x20000) + if (nVal.exbits & kHitAux2) { pSprite->cstat = 0x8000; } else { - if ((nVal & 0x3C000) == 0x10000) + if (nVal.exbits & kHitAux1) { pSprite->xvel >>= 1; pSprite->yvel >>= 1; pSprite->zvel = -pSprite->zvel; return; } - else if ((nVal & 0x3C000) == 0xC000) + else if (nVal.type == kHitSprite) { - nAngle = sprite[nVal & 0x3FFF].ang; + nAngle = nVal.actor->s().ang; } - else if ((nVal & 0x3C000) == 0x8000) + else if (nVal.type == kHitWall) { - nAngle = GetWallNormal(nVal & 0x3FFF); + nAngle = GetWallNormal(nVal.index); } else { @@ -1570,27 +1540,20 @@ void AICreatureChunk::Tick(RunListEvent* ev) runlist_FreeRun(pSprite->lotag - 1); runlist_SubRunRec(pSprite->hitag); - changespritestat(nSprite, 0); + ChangeActorStat(pActor, 0); pSprite->hitag = 0; pSprite->lotag = 0; } -void FuncCreatureChunk(int nObject, int nMessage, int nDamage, int nRun) +DExhumedActor* UpdateEnemy(DExhumedActor** ppEnemy) { - AICreatureChunk ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); - -} - -short UpdateEnemy(short *nEnemy) -{ - if (*nEnemy >= 0) + if (*ppEnemy) { - if (!(sprite[*nEnemy].cstat & 0x101)) { - *nEnemy = -1; + if (!((*ppEnemy)->s().cstat & 0x101)) { + *ppEnemy = nullptr; } } - return *nEnemy; + return *ppEnemy; } END_PS_NS diff --git a/source/games/exhumed/src/mummy.cpp b/source/games/exhumed/src/mummy.cpp index 128d90d51..efb40fc72 100644 --- a/source/games/exhumed/src/mummy.cpp +++ b/source/games/exhumed/src/mummy.cpp @@ -67,7 +67,7 @@ void BuildMummy(DExhumedActor* pActor, int x, int y, int z, int nSector, int nAn pSprite->zvel = 0; pSprite->xrepeat = 42; pSprite->yrepeat = 42; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->ang = nAngle; @@ -458,7 +458,7 @@ void AIMummy::Damage(RunListEvent* ev) pSprite->xvel = 0; pSprite->yvel = 0; pSprite->zvel = 0; - pSprite->z = sector[pSprite->sectnum].floorz; + pSprite->z = pSprite->sector()->floorz; } else { @@ -475,10 +475,4 @@ void AIMummy::Damage(RunListEvent* ev) return; } -void FuncMummy(int nObject, int nMessage, int nDamage, int nRun) -{ - AIMummy ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/exhumed/src/object.cpp b/source/games/exhumed/src/object.cpp index f772c06b7..e4d29a135 100644 --- a/source/games/exhumed/src/object.cpp +++ b/source/games/exhumed/src/object.cpp @@ -50,7 +50,7 @@ struct TrailPoint { int x; int y; - char nTrailPointVal; + uint8_t nTrailPointVal; short nTrailPointPrev; short nTrailPointNext; @@ -58,9 +58,9 @@ struct TrailPoint struct Bob { - short nSector; - char field_2; - char field_3; + int nSector; + uint8_t field_2; + uint8_t field_3; int z; short sBobID; @@ -68,30 +68,30 @@ struct Bob struct Drip { - short nSprite; - short field_2; + DExhumedActor* pActor; + short nCount; }; // 56 bytes struct Elev { + DExhumedActor* pActor; short field_0; short nChannel; - short nSector; + int nSector; int field_6; int field_A; short nCountZOffsets; // count of items in zOffsets short nCurZOffset; int zOffsets[8]; // different Z offsets short field_32; - short nSprite; short field_36; }; // 16 bytes struct MoveSect { - short nSector; + int nSector; short nTrail; short nTrailPoint; short field_6; @@ -102,21 +102,10 @@ struct MoveSect }; -struct Object -{ - short field_0; - short nHealth; - short field_4; - short nSprite; - short field_8; - short field_10; - short field_12; -}; - struct wallFace { short nChannel; - short nWall; + int nWall; short field_4; short field_6[8]; }; @@ -149,7 +138,7 @@ struct slideData struct Point { - short nSector; + int nSector; short field_2; short field_4; short field_6; @@ -181,7 +170,7 @@ TArray sBob; TArray sTrail; TArray sTrailPoint; TArray Elevator; -TArray ObjectList; +TArray ObjectList; TArray sMoveSect; TArray SlideData; TArray WallFace; @@ -237,8 +226,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Drip& w, Drip* def { if (arc.BeginObject(keyname)) { - arc("sprite", w.nSprite) - ("at2", w.field_2) + arc("sprite", w.pActor) + ("at2", w.nCount) .EndObject(); } return arc; @@ -256,7 +245,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Elev& w, Elev* def ("curz", w.nCurZOffset) .Array("zofs", w.zOffsets, 8) ("at32", w.field_32) - ("sprite", w.nSprite) + ("sprite", w.pActor) ("at36", w.field_36) .EndObject(); } @@ -278,22 +267,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, MoveSect& w, MoveS } return arc; } -FSerializer& Serialize(FSerializer& arc, const char* keyname, Object& w, Object* def) -{ - if (arc.BeginObject(keyname)) - { - arc("at0", w.field_0) - ("health", w.nHealth) - ("at4", w.field_4) - ("at8", w.field_8) - ("sprite", w.nSprite) - ("at8", w.field_8) - ("at10", w.field_10) - ("at12", w.field_12) - .EndObject(); - } - return arc; -} + FSerializer& Serialize(FSerializer& arc, const char* keyname, wallFace& w, wallFace* def) { if (arc.BeginObject(keyname)) @@ -441,7 +415,7 @@ DExhumedActor* BuildWallSprite(int nSector) } // done -short FindWallSprites(short nSector) +DExhumedActor* FindWallSprites(int nSector) { int var_24 = 0x7FFFFFFF; int ecx = 0x7FFFFFFF; @@ -516,10 +490,10 @@ short FindWallSprites(short nSector) pSprite->hitag = 0; } - return pAct->GetSpriteIndex(); + return pAct; } -int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5, int nCount, ...) +int BuildElevF(int nChannel, int nSector, DExhumedActor* nWallSprite, int arg_4, int arg_5, int nCount, ...) { auto ElevCount = Elevator.Reserve(1); @@ -533,11 +507,11 @@ int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5, Elevator[ElevCount].nCurZOffset = 0; Elevator[ElevCount].field_36 = 0; - if (nWallSprite < 0) { - nWallSprite = BuildWallSprite(nSector)->GetSpriteIndex(); + if (nWallSprite == nullptr) { + nWallSprite = BuildWallSprite(nSector); } - Elevator[ElevCount].nSprite = nWallSprite; + Elevator[ElevCount].pActor = nWallSprite; va_list zlist; va_start(zlist, nCount); @@ -559,7 +533,7 @@ int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5, return ElevCount; } -int BuildElevC(int arg1, int nChannel, int nSector, int nWallSprite, int arg5, int arg6, int nCount, ...) +int BuildElevC(int arg1, int nChannel, int nSector, DExhumedActor* nWallSprite, int arg5, int arg6, int nCount, ...) { int edi = arg5; @@ -581,11 +555,11 @@ int BuildElevC(int arg1, int nChannel, int nSector, int nWallSprite, int arg5, i Elevator[ElevCount].nChannel = nChannel; Elevator[ElevCount].nSector = nSector; - if (nWallSprite < 0) { - nWallSprite = BuildWallSprite(nSector)->GetSpriteIndex(); + if (nWallSprite == nullptr) { + nWallSprite = BuildWallSprite(nSector); } - Elevator[ElevCount].nSprite = nWallSprite; + Elevator[ElevCount].pActor = nWallSprite; va_list zlist; va_start(zlist, nCount); @@ -636,7 +610,7 @@ int LongSeek(int* pZVal, int a2, int a3, int a4) } // done -int CheckSectorSprites(short nSector, int nVal) +int CheckSectorSprites(int nSector, int nVal) { int b = 0; @@ -656,7 +630,7 @@ int CheckSectorSprites(short nSector, int nVal) b = 1; - runlist_DamageEnemy(pActor->GetSpriteIndex(), -1, 5); + runlist_DamageEnemy(pActor, nullptr, 5); if (pSprite->statnum == 100 && PlayerList[GetPlayerFromActor(pActor)].nHealth <= 0) { @@ -689,8 +663,8 @@ void MoveSectorSprites(int nSector, int z) { int newz = sector[nSector].floorz; int oldz = newz - z; - int minz = std::min(newz, oldz); - int maxz = std::max(newz, oldz); + int minz = min(newz, oldz); + int maxz = max(newz, oldz); ExhumedSectIterator it(nSector); while (auto pActor = it.Next()) { @@ -703,7 +677,7 @@ void MoveSectorSprites(int nSector, int z) } } -void StartElevSound(short nSprite, int nVal) +void StartElevSound(DExhumedActor* pActor, int nVal) { short nSound; @@ -714,7 +688,7 @@ void StartElevSound(short nSprite, int nVal) nSound = nStoneSound; } - D3PlayFX(StaticSound[nSound], nSprite); + D3PlayFX(StaticSound[nSound], pActor); } void AIElev::ProcessChannel(RunListEvent* ev) @@ -750,7 +724,7 @@ void AIElev::ProcessChannel(RunListEvent* ev) if (Elevator[nElev].field_32 < 0) { Elevator[nElev].field_32 = runlist_AddRunRec(NewRun, &RunData[nRun]); - StartElevSound(Elevator[nElev].nSprite, var_18); + StartElevSound(Elevator[nElev].pActor, var_18); edi = 1; } @@ -785,7 +759,7 @@ void AIElev::ProcessChannel(RunListEvent* ev) { Elevator[nElev].field_32 = runlist_AddRunRec(NewRun, &RunData[nRun]); - StartElevSound(Elevator[nElev].nSprite, var_18); + StartElevSound(Elevator[nElev].pActor, var_18); } } else @@ -810,8 +784,8 @@ void AIElev::Tick(RunListEvent* ev) assert(nChannel >= 0 && nChannel < kMaxChannels); - short nSector = Elevator[nElev].nSector; - auto pElevSpr = &exhumedActors[Elevator[nElev].nSprite]; + int nSector =Elevator[nElev].nSector; + auto pElevSpr = Elevator[nElev].pActor; int ebp = 0; // initialise to *something* @@ -831,7 +805,7 @@ void AIElev::Tick(RunListEvent* ev) if (var_18 & 0x10) { Elevator[nElev].nCurZOffset ^= 1; - StartElevSound(pElevSpr->GetSpriteIndex(), var_18); + StartElevSound(pElevSpr, var_18); } else { @@ -840,7 +814,7 @@ void AIElev::Tick(RunListEvent* ev) Elevator[nElev].field_32 = -1; runlist_ReadyChannel(nChannel); - D3PlayFX(StaticSound[nStopSound], Elevator[nElev].nSprite); + D3PlayFX(StaticSound[nStopSound], Elevator[nElev].pActor); } } else @@ -874,14 +848,14 @@ void AIElev::Tick(RunListEvent* ev) { Elevator[nElev].nCurZOffset ^= 1; - StartElevSound(Elevator[nElev].nSprite, var_18); + StartElevSound(Elevator[nElev].pActor, var_18); } else { runlist_SubRunRec(nRun); Elevator[nElev].field_32 = -1; - StopSpriteSound(Elevator[nElev].nSprite); - D3PlayFX(StaticSound[nStopSound], Elevator[nElev].nSprite); + StopActorSound(Elevator[nElev].pActor); + D3PlayFX(StaticSound[nStopSound], Elevator[nElev].pActor); runlist_ReadyChannel(nChannel); } @@ -928,19 +902,13 @@ void AIElev::Tick(RunListEvent* ev) } -void FuncElev(int nObject, int nMessage, int nDamage, int nRun) -{ - AIElev ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - // done void InitWallFace() { WallFace.Clear(); } -int BuildWallFace(short nChannel, short nWall, int nCount, ...) +int BuildWallFace(short nChannel, int nWall, int nCount, ...) { auto WallFaceCount = WallFace.Reserve(1); @@ -982,12 +950,6 @@ void AIWallFace::ProcessChannel(RunListEvent* ev) } } -void FuncWallFace(int nObject, int nMessage, int nDamage, int nRun) -{ - AIWallFace ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - // done void InitPoint() { @@ -1031,7 +993,7 @@ int BuildSlide(int nChannel, int nStartWall, int nWall1, int ecx, int nWall2, in { auto nSlide = SlideData.Reserve(1); - short nSector = IdentifySector(nStartWall); + int nSector =IdentifySector(nStartWall); SlideData[nSlide].field_4a = -1; SlideData[nSlide].nChannel = nChannel; @@ -1044,8 +1006,8 @@ int BuildSlide(int nChannel, int nStartWall, int nWall1, int ecx, int nWall2, in PointList[nPoint].nNext = -1; PointList[nPoint].nSector = nSector; - short startwall = sector[nSector].wallptr; - short endwall = startwall + sector[nSector].wallnum; + int startwall = sector[nSector].wallptr; + int endwall = startwall + sector[nSector].wallnum; for (int nWall = startwall; nWall < endwall; nWall++) { @@ -1169,7 +1131,7 @@ void AISlide::Tick(RunListEvent* ev) if (cx == 1) { - short nWall = SlideData[nSlide].field_4; + int nWall = SlideData[nSlide].field_4; int x = wall[nWall].x; int y = wall[nWall].y; @@ -1227,7 +1189,7 @@ void AISlide::Tick(RunListEvent* ev) } else if (cx == 0) // right branch { - short nWall = SlideData[nSlide].field_0; + int nWall = SlideData[nSlide].field_0; int x = wall[nWall].x; int y = wall[nWall].y; @@ -1291,12 +1253,6 @@ void AISlide::Tick(RunListEvent* ev) } } -void FuncSlide(int nObject, int nMessage, int nDamage, int nRun) -{ - AISlide ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - int BuildTrap(DExhumedActor* pActor, int edx, int ebx, int ecx) { auto pSprite = &pActor->s(); @@ -1339,8 +1295,8 @@ int BuildTrap(DExhumedActor* pActor, int edx, int ebx, int ecx) sTrap[nTrap].field_6 = -1; sTrap[nTrap].field_8 = -1; - short nSector = pSprite->sectnum; - short nWall = sector[nSector].wallptr; + int nSector =pSprite->sectnum; + int nWall = sector[nSector].wallptr; int i = 0; @@ -1408,7 +1364,7 @@ void AITrap::Tick(RunListEvent* ev) if (nType == 14) { - short nWall = sTrap[nTrap].field_6; + int nWall = sTrap[nTrap].field_6; if (nWall > -1) { wall[nWall].picnum = sTrap[nTrap].field_A; @@ -1440,7 +1396,7 @@ void AITrap::Tick(RunListEvent* ev) { pBullet->s().clipdist = 50; - short nWall = sTrap[nTrap].field_6; + int nWall = sTrap[nTrap].field_6; if (nWall > -1) { wall[nWall].picnum = sTrap[nTrap].field_A + 1; @@ -1459,12 +1415,6 @@ void AITrap::Tick(RunListEvent* ev) } } -void FuncTrap(int nObject, int nMessage, int nDamage, int nRun) -{ - AITrap ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - int BuildArrow(DExhumedActor* nSprite, int nVal) { return BuildTrap(nSprite, 0, -1, nVal); @@ -1592,12 +1542,6 @@ void AISpark::Tick(RunListEvent* ev) } -void FuncSpark(int nObject, int nMessage, int nDamage, int nRun) -{ - AISpark ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - void DimLights() { static short word_96786 = 0; @@ -1614,8 +1558,8 @@ void DimLights() if (sector[i].floorshade < 100) sector[i].floorshade++; - short startwall = sector[i].wallptr; - short endwall = startwall + sector[i].wallnum; + int startwall = sector[i].wallptr; + int endwall = startwall + sector[i].wallnum; for (int nWall = startwall; nWall < endwall; nWall++) { @@ -1692,10 +1636,10 @@ void DoFinale() } } -DExhumedActor* BuildEnergyBlock(short nSector) +DExhumedActor* BuildEnergyBlock(int nSector) { - short startwall = sector[nSector].wallptr; - short nWalls = sector[nSector].wallnum; + int startwall = sector[nSector].wallptr; + int nWalls = sector[nSector].wallnum; int x = 0; int y = 0; @@ -1780,10 +1724,10 @@ void ExplodeEnergyBlock(DExhumedActor* pActor) { auto pSprite = &pActor->s(); - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; - short startwall = sector[nSector].wallptr; - short nWalls = sector[nSector].wallnum; + int startwall = sector[nSector].wallptr; + int nWalls = sector[nSector].wallnum; int i; @@ -1861,8 +1805,8 @@ void ExplodeEnergyBlock(DExhumedActor* pActor) sector[i].floorpal = 0; } - short startwall = sector[i].wallptr; - short endwall = startwall + sector[i].wallnum; + int startwall = sector[i].wallptr; + int endwall = startwall + sector[i].wallnum; for (int nWall = startwall; nWall < endwall; nWall++) { @@ -1917,7 +1861,7 @@ void AIEnergyBlock::RadialDamage(RunListEvent* ev) if (!pActor) return; auto spr = &pActor->s(); - short nSector = spr->sectnum; + int nSector =spr->sectnum; if (sector[nSector].extra == -1) { return; @@ -1943,21 +1887,11 @@ void AIEnergyBlock::RadialDamage(RunListEvent* ev) } - -void FuncEnergyBlock(int nObject, int nMessage, int nDamage, int nRun) +DExhumedActor* BuildObject(DExhumedActor* pActor, int nOjectType, int nHitag) { - AIEnergyBlock ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} + auto spr = &pActor->s(); -int BuildObject(int const nSprite, int nOjectType, int nHitag) -{ - auto spr = &sprite[nSprite]; - - auto nObject = ObjectList.Reserve(1); - ObjectList[nObject] = {}; - - changespritestat(nSprite, ObjectStatnum[nOjectType]); + ChangeActorStat(pActor, ObjectStatnum[nOjectType]); // 0x7FFD to ensure set as blocking ('B' and 'H') sprite and also disable translucency and set not invisible spr->cstat = (spr->cstat | 0x101) & 0x7FFD; @@ -1967,34 +1901,34 @@ int BuildObject(int const nSprite, int nOjectType, int nHitag) spr->extra = -1; spr->lotag = runlist_HeadRun() + 1; spr->hitag = 0; - spr->owner = runlist_AddRunRec(spr->lotag - 1, nObject, 0x170000); + spr->owner = runlist_AddRunRec(spr->lotag - 1, pActor, 0x170000); // GrabTimeSlot(3); - + pActor->nPhase = ObjectList.Push(pActor); if (spr->statnum == kStatDestructibleSprite) { - ObjectList[nObject].nHealth = 4; + pActor->nHealth = 4; } else { - ObjectList[nObject].nHealth = 120; + pActor->nHealth = 120; } - ObjectList[nObject].nSprite = nSprite; - ObjectList[nObject].field_4 = runlist_AddRunRec(NewRun, nObject, 0x170000); + pActor->nRun = runlist_AddRunRec(NewRun, pActor, 0x170000); short nSeq = ObjectSeq[nOjectType]; if (nSeq > -1) { - ObjectList[nObject].field_8 = SeqOffsets[nSeq]; + pActor->nIndex = SeqOffsets[nSeq]; if (!nOjectType) // if not Explosion Trigger (e.g. Exploding Fire Cauldron) { - ObjectList[nObject].field_0 = RandomSize(4) % (SeqSize[ObjectList[nObject].field_8] - 1); + pActor->nFrame = RandomSize(4) % (SeqSize[pActor->nIndex] - 1); } - int nSprite2 = insertsprite(spr->sectnum, 0); - auto pSprite2 = &sprite[nSprite2]; - ObjectList[nObject].field_10 = nSprite2; + auto pActor2 = insertActor(spr->sectnum, 0); + auto pSprite2 = &pActor2->s(); + pActor->pTarget = pActor2; + pActor->nIndex2 = -1; pSprite2->cstat = 0x8000; pSprite2->x = spr->x; @@ -2003,45 +1937,42 @@ int BuildObject(int const nSprite, int nOjectType, int nHitag) } else { - ObjectList[nObject].field_0 = 0; - ObjectList[nObject].field_8 = -1; + pActor->nFrame = 0; + pActor->nIndex = -1; if (spr->statnum == kStatDestructibleSprite) { - ObjectList[nObject].field_10 = -1; + pActor->nIndex2 = -1; } else { - ObjectList[nObject].field_10 = -nHitag; + pActor->nIndex2 = -nHitag; } } spr->backuppos(); - return nObject | 0x170000; + return pActor; } // in-game destructable wall mounted screen -void ExplodeScreen(short nSprite) +void ExplodeScreen(DExhumedActor* pActor) { - auto pSprite = &sprite[nSprite]; - pSprite->z -= GetSpriteHeight(nSprite) / 2; + auto pSprite = &pActor->s(); + pSprite->z -= GetActorHeight(pActor) / 2; for (int i = 0; i < 30; i++) { - BuildSpark(&exhumedActors[nSprite], 0); // shoot out blue orbs + BuildSpark(pActor, 0); // shoot out blue orbs } pSprite->cstat = 0x8000; - PlayFX2(StaticSound[kSound78], nSprite); + PlayFX2(StaticSound[kSound78], pActor); } void AIObject::Tick(RunListEvent* ev) { - short nObject = RunData[ev->nRun].nObjIndex; - auto pObject = &ObjectList[nObject]; - - auto pActor = &exhumedActors[pObject->nSprite];// ev->pObjActor; - short nSprite = pObject->nSprite; - auto pSprite = &sprite[nSprite]; + auto pActor = ev->pObjActor; + if (!pActor) return; + auto pSprite = &pActor->s(); short nStat = pSprite->statnum; - short bx = pObject->field_8; + short bx = pActor->nIndex; if (nStat == 97 || (!(pSprite->cstat & 0x101))) { return; @@ -2054,38 +1985,38 @@ void AIObject::Tick(RunListEvent* ev) // do animation if (bx != -1) { - pObject->field_0++; - if (pObject->field_0 >= SeqSize[bx]) { - pObject->field_0 = 0; + pActor->nFrame++; + if (pActor->nFrame >= SeqSize[bx]) { + pActor->nFrame = 0; } - pSprite->picnum = seq_GetSeqPicnum2(bx, pObject->field_0); + pSprite->picnum = seq_GetSeqPicnum2(bx, pActor->nFrame); } - if (pObject->nHealth >= 0) { + if (pActor->nHealth >= 0) { goto FUNCOBJECT_GOTO; } - pObject->nHealth++; + pActor->nHealth++; - if (pObject->nHealth) + if (pActor->nHealth) { FUNCOBJECT_GOTO: if (nStat != kStatExplodeTarget) { - int nMov = movesprite(nSprite, pSprite->xvel << 6, pSprite->yvel << 6, pSprite->zvel, 0, 0, CLIPMASK0); + auto nMov = movesprite(pActor, pSprite->xvel << 6, pSprite->yvel << 6, pSprite->zvel, 0, 0, CLIPMASK0); if (pSprite->statnum == kStatExplodeTrigger) { pSprite->pal = 1; } - if (nMov & 0x20000) + if (nMov.exbits & kHitAux2) { pSprite->xvel -= pSprite->xvel >> 3; pSprite->yvel -= pSprite->yvel >> 3; } - if (((nMov & 0xC000) > 0x8000) && ((nMov & 0xC000) == 0xC000)) + if (nMov.type == kHitSprite) { pSprite->yvel = 0; pSprite->xvel = 0; @@ -2099,7 +2030,7 @@ void AIObject::Tick(RunListEvent* ev) int var_18; // red branch - if ((nStat == kStatExplodeTarget) || (pSprite->z < sector[pSprite->sectnum].floorz)) + if ((nStat == kStatExplodeTarget) || (pSprite->z < pSprite->sector()->floorz)) { var_18 = 36; } @@ -2109,43 +2040,44 @@ void AIObject::Tick(RunListEvent* ev) } AddFlash(pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 128); - BuildAnim(nullptr, var_18, 0, pSprite->x, pSprite->y, sector[pSprite->sectnum].floorz, pSprite->sectnum, 240, 4); + BuildAnim(nullptr, var_18, 0, pSprite->x, pSprite->y, pSprite->sector()->floorz, pSprite->sectnum, 240, 4); // int edi = nSprite | 0x4000; if (nStat == kStatExplodeTrigger) { for (int i = 4; i < 8; i++) { - BuildCreatureChunk(nSprite | 0x4000, seq_GetSeqPicnum(kSeqFirePot, (i >> 2) + 1, 0)); + BuildCreatureChunk(pActor, seq_GetSeqPicnum(kSeqFirePot, (i >> 2) + 1, 0), true); } - runlist_RadialDamageEnemy(nSprite, 200, 20); + runlist_RadialDamageEnemy(pActor, 200, 20); } else if (nStat == kStatExplodeTarget) { for (int i = 0; i < 8; i++) { - BuildCreatureChunk(nSprite | 0x4000, seq_GetSeqPicnum(kSeqFirePot, (i >> 1) + 3, 0)); + BuildCreatureChunk(pActor, seq_GetSeqPicnum(kSeqFirePot, (i >> 1) + 3, 0), true); } } if (!(currentLevel->gameflags & LEVEL_EX_MULTI) || nStat != kStatExplodeTrigger) { runlist_SubRunRec(pSprite->owner); - runlist_SubRunRec(pObject->field_4); + runlist_SubRunRec(pActor->nRun); - mydeletesprite(nSprite); + DeleteActor(pActor); return; } else { StartRegenerate(pActor); - pObject->nHealth = 120; + pActor->nHealth = 120; - pSprite->x = sprite[pObject->field_10].x; - pSprite->y = sprite[pObject->field_10].y; - pSprite->z = sprite[pObject->field_10].z; + auto pTargSpr = &pActor->pTarget->s(); + pSprite->x = pTargSpr->x; + pSprite->y = pTargSpr->y; + pSprite->z = pTargSpr->z; - mychangespritesect(nSprite, sprite[pObject->field_10].sectnum); + ChangeActorSect(pActor, pTargSpr->sectnum); return; } } @@ -2153,74 +2085,71 @@ void AIObject::Tick(RunListEvent* ev) void AIObject::Damage(RunListEvent* ev) { - short nObject = RunData[ev->nRun].nObjIndex; - auto pObject = &ObjectList[nObject]; - - short nSprite = pObject->nSprite; - auto pSprite = &sprite[nSprite]; + auto pActor = ev->pObjActor; + if (!pActor) return; + auto pSprite = &pActor->s(); short nStat = pSprite->statnum; - short bx = pObject->field_8; + short bx = pActor->nIndex; - if (nStat >= 150 || pObject->nHealth <= 0) { + if (nStat >= 150 || pActor->nHealth <= 0) { return; } if (nStat == 98) { - D3PlayFX((StaticSound[kSound47] | 0x2000) | (RandomSize(2) << 9), nSprite); + D3PlayFX((StaticSound[kSound47] | 0x2000) | (RandomSize(2) << 9), pActor); return; } - pObject->nHealth -= (short)ev->nDamage; - if (pObject->nHealth > 0) { + pActor->nHealth -= (short)ev->nDamage; + if (pActor->nHealth > 0) { return; } if (nStat == kStatDestructibleSprite) { - ExplodeScreen(nSprite); + ExplodeScreen(pActor); } else { - pObject->nHealth = -(RandomSize(3) + 1); + pActor->nHealth = -(RandomSize(3) + 1); } } void AIObject::Draw(RunListEvent* ev) { - short nObject = RunData[ev->nRun].nObjIndex; - auto pObject = &ObjectList[nObject]; - short bx = pObject->field_8; + auto pActor = ev->pObjActor; + if (!pActor) return; + short bx = pActor->nIndex; if (bx > -1) { - seq_PlotSequence(ev->nParam, bx, pObject->field_0, 1); + seq_PlotSequence(ev->nParam, bx, pActor->nFrame, 1); } return; } void AIObject::RadialDamage(RunListEvent* ev) { - short nObject = RunData[ev->nRun].nObjIndex; - auto pObject = &ObjectList[nObject]; + auto pActor = ev->pObjActor; + if (!pActor) return; - short nSprite = pObject->nSprite; - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); short nStat = pSprite->statnum; - if (pObject->nHealth > 0 && pSprite->cstat & 0x101 + if (pActor->nHealth > 0 && pSprite->cstat & 0x101 && (nStat != kStatExplodeTarget - || sprite[nRadialSpr].statnum == 201 + || ev->pRadialActor->s().statnum == 201 || (nRadialBullet != 3 && nRadialBullet > -1) - || sprite[nRadialSpr].statnum == kStatExplodeTrigger)) + || ev->pRadialActor->s().statnum == kStatExplodeTrigger)) { - int nDamage = runlist_CheckRadialDamage(nSprite); + int nDamage = runlist_CheckRadialDamage(pActor); if (nDamage <= 0) { return; } if (pSprite->statnum != kStatAnubisDrum) { - pObject->nHealth -= nDamage; + pActor->nHealth -= nDamage; } if (pSprite->statnum == kStatExplodeTarget) @@ -2236,47 +2165,40 @@ void AIObject::RadialDamage(RunListEvent* ev) pSprite->zvel >>= 1; } - if (pObject->nHealth > 0) { + if (pActor->nHealth > 0) { return; } if (pSprite->statnum == kStatExplodeTarget) { - pObject->nHealth = -1; - short ax = pObject->field_10; + pActor->nHealth = -1; + short ax = pActor->nIndex2; - if (ax < 0 || ObjectList[ax].nHealth <= 0) { + if (ax < 0 || ObjectList[ax]->nHealth <= 0) { return; } - ObjectList[ax].nHealth = -1; + ObjectList[ax]->nHealth = -1; } else if (pSprite->statnum == kStatDestructibleSprite) { - pObject->nHealth = 0; + pActor->nHealth = 0; - ExplodeScreen(nSprite); + ExplodeScreen(pActor); } else { - pObject->nHealth = -(RandomSize(4) + 1); + pActor->nHealth = -(RandomSize(4) + 1); } } } - -void FuncObject(int nObject, int nMessage, int nDamage, int nRun) +void BuildDrip(DExhumedActor* pActor) { - AIObject ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - -void BuildDrip(int nSprite) -{ - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); auto nDrips = sDrip.Reserve(1); - sDrip[nDrips].nSprite = nSprite; - sDrip[nDrips].field_2 = RandomSize(8) + 90; + sDrip[nDrips].pActor = pActor; + sDrip[nDrips].nCount = RandomSize(8) + 90; pSprite->cstat = 0x8000u; } @@ -2284,11 +2206,11 @@ void DoDrips() { for (unsigned i = 0; i < sDrip.Size(); i++) { - sDrip[i].field_2--; - if (sDrip[i].field_2 <= 0) + sDrip[i].nCount--; + if (sDrip[i].nCount <= 0) { - short nSprite = sDrip[i].nSprite; - auto pSprite = &sprite[nSprite]; + auto pActor = sDrip[i].pActor; + auto pSprite = &pActor->s(); short nSeqOffset = SeqOffsets[kSeqDrips]; @@ -2296,9 +2218,9 @@ void DoDrips() nSeqOffset++; } - seq_MoveSequence(nSprite, nSeqOffset, RandomSize(2) % SeqSize[nSeqOffset]); + seq_MoveSequence(pActor, nSeqOffset, RandomSize(2) % SeqSize[nSeqOffset]); - sDrip[i].field_2 = RandomSize(8) + 90; + sDrip[i].nCount = RandomSize(8) + 90; } } @@ -2307,7 +2229,7 @@ void DoDrips() sBob[i].field_2 += 4; int edx = bsin(sBob[i].field_2 << 3, -4); - short nSector = sBob[i].nSector; + int nSector =sBob[i].nSector; if (sBob[i].field_3) { @@ -2324,7 +2246,7 @@ void DoDrips() } } -void SnapBobs(short nSectorA, short nSectorB) +void SnapBobs(int nSectorA, int nSectorB) { int ecx = -1; int ebx = ecx; @@ -2405,9 +2327,9 @@ int FindTrail(int nVal) } // ok ? -void ProcessTrailSprite(int nSprite, int nLotag, int nHitag) +void ProcessTrailSprite(DExhumedActor* pActor, int nLotag, int nHitag) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); auto nPoint = sTrailPoint.Reserve(1); sTrailPoint[nPoint].x = pSprite->x; @@ -2461,7 +2383,7 @@ void ProcessTrailSprite(int nSprite, int nLotag, int nHitag) } } - mydeletesprite(nSprite); + DeleteActor(pActor); } // ok? @@ -2508,7 +2430,7 @@ void DoMovingSects() continue; } - short nSector = sMoveSect[i].nSector; + int nSector =sMoveSect[i].nSector; short nBlock = sector[nSector].extra; BlockInfo* pBlockInfo = &sBlockInfo[nBlock]; @@ -2646,7 +2568,7 @@ void PostProcess() runlist_ChangeChannel(sMoveSect[i].field_14, 1); } - short nSector = sMoveSect[i].nSector; + int nSector =sMoveSect[i].nSector; if (SectFlag[nSector] & kSectUnderwater) { @@ -2746,45 +2668,47 @@ void PostProcess() if (wall[nWall].picnum == kTile3603) { wall[nWall].pal = 1; - int nSprite = insertsprite(i, 407); - auto pSprite = &sprite[nSprite]; - pSprite->cstat = 0x8000; + auto pActor = insertActor(i, 407); + pActor->s().cstat = 0x8000; } nWall++; } } - for (i = 0; i < kMaxSprites; i++) + ExhumedLinearSpriteIterator it; + while (auto act = it.Next()) { - if (sprite[i].statnum < kMaxStatus && sprite[i].picnum == kTile3603) + auto spr = &act->s(); + if (spr->statnum < kMaxStatus && spr->picnum == kTile3603) { - changespritestat(i, 407); - sprite[i].pal = 1; + ChangeActorStat(act, 407); + spr->pal = 1; } } } for (unsigned i = 0; i < ObjectList.Size(); i++) { - int nObjectSprite = ObjectList[i].nSprite; + auto pObjectActor = ObjectList[i]; - if (sprite[nObjectSprite].statnum == kStatExplodeTarget) + if (pObjectActor->s().statnum == kStatExplodeTarget) { - if (!ObjectList[i].field_10) { - ObjectList[i].field_10 = -1; + if (!pObjectActor->nIndex2) { + pObjectActor->nIndex2 = -1; } else { - int edi = ObjectList[i].field_10; - ObjectList[i].field_10 = -1; + int edi = pObjectActor->nIndex2; + pObjectActor->nIndex2 = -1; for (unsigned j = 0; j < ObjectList.Size(); j++) { - if (i != j && sprite[ObjectList[j].nSprite].statnum == kStatExplodeTarget && edi == ObjectList[j].field_10) + + if (i != j && ObjectList[j]->s().statnum == kStatExplodeTarget && edi == ObjectList[j]->nIndex2) { - ObjectList[i].field_10 = j; - ObjectList[j].field_10 = i; + pObjectActor->nIndex2 = j; + ObjectList[j]->nIndex2 = i; } } } diff --git a/source/games/exhumed/src/osdcmds.cpp b/source/games/exhumed/src/osdcmds.cpp index 1ed52053a..9d66bfadc 100644 --- a/source/games/exhumed/src/osdcmds.cpp +++ b/source/games/exhumed/src/osdcmds.cpp @@ -69,31 +69,25 @@ static int osdcmd_doors(CCmdFuncPtr parm) return CCMD_OK; } -extern int initx; -extern int inity; -extern int initz; -extern short inita; -extern short initsect; - static int osdcmd_spawn(CCmdFuncPtr parm) { if (parm->numparms != 1) return CCMD_SHOWHELP; auto c = parm->parms[0]; - - if (!stricmp(c, "anubis")) BuildAnubis(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, false); - else if (!stricmp(c, "spider")) BuildSpider(nullptr, initx, inity, sector[initsect].floorz, initsect, inita); - else if (!stricmp(c, "mummy")) BuildMummy(nullptr, initx, inity, sector[initsect].floorz, initsect, inita); + auto sectp = §or[initsect]; + if (!stricmp(c, "anubis")) BuildAnubis(nullptr, initx, inity, sectp->floorz, initsect, inita, false); + else if (!stricmp(c, "spider")) BuildSpider(nullptr, initx, inity, sectp->floorz, initsect, inita); + else if (!stricmp(c, "mummy")) BuildMummy(nullptr, initx, inity, sectp->floorz, initsect, inita); else if (!stricmp(c, "fish")) BuildFish(nullptr, initx, inity, initz + PlayerList[nLocalPlayer].eyelevel, initsect, inita); - else if (!stricmp(c, "lion")) BuildLion(nullptr, initx, inity, sector[initsect].floorz, initsect, inita); - else if (!stricmp(c, "lava")) BuildLava(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); - else if (!stricmp(c, "rex")) BuildRex(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); - else if (!stricmp(c, "set")) BuildSet(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); - else if (!stricmp(c, "queen")) BuildQueen(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); - else if (!stricmp(c, "roach")) BuildRoach(0, nullptr, initx, inity, sector[initsect].floorz, initsect, inita); - else if (!stricmp(c, "roach2")) BuildRoach(1, nullptr, initx, inity, sector[initsect].floorz, initsect, inita); - else if (!stricmp(c, "wasp")) BuildWasp(nullptr, initx, inity, sector[initsect].floorz - 25600, initsect, inita, false); - else if (!stricmp(c, "scorp")) BuildScorp(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); - else if (!stricmp(c, "rat")) BuildRat(nullptr, initx, inity, sector[initsect].floorz, initsect, inita); + else if (!stricmp(c, "lion")) BuildLion(nullptr, initx, inity, sectp->floorz, initsect, inita); + else if (!stricmp(c, "lava")) BuildLava(nullptr, initx, inity, sectp->floorz, initsect, inita, nNetPlayerCount); + else if (!stricmp(c, "rex")) BuildRex(nullptr, initx, inity, sectp->floorz, initsect, inita, nNetPlayerCount); + else if (!stricmp(c, "set")) BuildSet(nullptr, initx, inity, sectp->floorz, initsect, inita, nNetPlayerCount); + else if (!stricmp(c, "queen")) BuildQueen(nullptr, initx, inity, sectp->floorz, initsect, inita, nNetPlayerCount); + else if (!stricmp(c, "roach")) BuildRoach(0, nullptr, initx, inity, sectp->floorz, initsect, inita); + else if (!stricmp(c, "roach2")) BuildRoach(1, nullptr, initx, inity, sectp->floorz, initsect, inita); + else if (!stricmp(c, "wasp")) BuildWasp(nullptr, initx, inity, sectp->floorz - 25600, initsect, inita, false); + else if (!stricmp(c, "scorp")) BuildScorp(nullptr, initx, inity, sectp->floorz, initsect, inita, nNetPlayerCount); + else if (!stricmp(c, "rat")) BuildRat(nullptr, initx, inity, sectp->floorz, initsect, inita); else Printf("Unknown creature type %s\n", c); return CCMD_OK; } diff --git a/source/games/exhumed/src/player.cpp b/source/games/exhumed/src/player.cpp index a2efda470..bcde8b458 100644 --- a/source/games/exhumed/src/player.cpp +++ b/source/games/exhumed/src/player.cpp @@ -98,7 +98,7 @@ void RestoreSavePoint(int nPlayer, int *x, int *y, int *z, short *nSector, short *nAngle = PlayerList[nPlayer].sPlayerSave.nAngle; } -void SetSavePoint(int nPlayer, int x, int y, int z, short nSector, short nAngle) +void SetSavePoint(int nPlayer, int x, int y, int z, int nSector, short nAngle) { PlayerList[nPlayer].sPlayerSave.x = x; PlayerList[nPlayer].sPlayerSave.y = y; @@ -107,9 +107,9 @@ void SetSavePoint(int nPlayer, int x, int y, int z, short nSector, short nAngle) PlayerList[nPlayer].sPlayerSave.nAngle = nAngle; } -void feebtag(int x, int y, int z, int nSector, short *nSprite, int nVal2, int nVal3) +void feebtag(int x, int y, int z, int nSector, DExhumedActor **nSprite, int nVal2, int nVal3) { - *nSprite = -1; + *nSprite = nullptr; int startwall = sector[nSector].wallptr; @@ -149,7 +149,7 @@ void feebtag(int x, int y, int z, int nSector, short *nSprite, int nVal2, int nV if (theSqrt < nVal3 && ((nStat != 950 && nStat != 949) || !(var_14 & 1)) && ((nStat != 912 && nStat != 913) || !(var_20 & 2))) { nVal3 = theSqrt; - *nSprite = pActor->GetSpriteIndex(); + *nSprite = pActor; } } } @@ -168,7 +168,7 @@ void feebtag(int x, int y, int z, int nSector, short *nSprite, int nVal2, int nV void InitPlayer() { for (int i = 0; i < kMaxPlayers; i++) { - PlayerList[i].nSprite = -1; + PlayerList[i].pActor = nullptr; } } @@ -188,7 +188,7 @@ void InitPlayerInventory(short nPlayer) PlayerList[nPlayer].nLives = kDefaultLives; - PlayerList[nPlayer].nSprite = -1; + PlayerList[nPlayer].pActor = nullptr; PlayerList[nPlayer].nRun = -1; PlayerList[nPlayer].nPistolClip = 6; @@ -207,57 +207,52 @@ void InitPlayerInventory(short nPlayer) PlayerList[nPlayer].nPlayerColor = pixels[tileWidth(nPlayer + kTile3571) * tileHeight(nPlayer + kTile3571) / 2]; } -short GetPlayerFromSprite(short nSprite) +short GetPlayerFromActor(DExhumedActor* pActor) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); return RunData[pSprite->owner].nObjIndex; } void RestartPlayer(short nPlayer) { auto plr = &PlayerList[nPlayer]; - int nSprite = plr->nSprite; - auto nSpr = &sprite[nSprite]; - int nDopSprite = PlayerList[nPlayer].nDoppleSprite; + auto pActor = plr->Actor(); + auto pDopSprite = plr->pDoppleSprite; - int floorspr; + DExhumedActor* floorsprt; - if (nSprite > -1) + if (pActor) { - runlist_DoSubRunRec(nSpr->owner); + auto nSpr = &pActor->s(); + runlist_DoSubRunRec(nSpr->owner); runlist_FreeRun(nSpr->lotag - 1); - changespritestat(nSprite, 0); + ChangeActorStat(pActor, 0); - plr->nSprite = -1; + plr->pActor = nullptr; - int nFloorSprite = PlayerList[nPlayer].nPlayerFloorSprite; - if (nFloorSprite > -1) { - mydeletesprite(nFloorSprite); + auto pFloorSprite = plr->pPlayerFloorSprite; + if (pFloorSprite != nullptr) { + DeleteActor(pFloorSprite); } - if (nDopSprite > -1) + if (pDopSprite) { - auto sp = &sprite[nDopSprite]; + auto sp = &pDopSprite->s(); runlist_DoSubRunRec(sp->owner); runlist_FreeRun(sp->lotag - 1); - mydeletesprite(nDopSprite); + DeleteActor(pDopSprite); } } - auto actor = GrabBody(); - nSprite = actor->GetSpriteIndex(); - nSpr = &actor->s(); + pActor = GrabBody(); + auto nSpr = &pActor->s(); - mychangespritesect(nSprite, PlayerList[nPlayer].sPlayerSave.nSector); - changespritestat(nSprite, 100); + ChangeActorSect(pActor, plr->sPlayerSave.nSector); + ChangeActorStat(pActor, 100); - assert(nSprite >= 0 && nSprite < kMaxSprites); - - int nDSprite = insertsprite(nSpr->sectnum, 100); - PlayerList[nPlayer].nDoppleSprite = nDSprite; - - assert(nDSprite >= 0 && nDSprite < kMaxSprites); + auto pDActor = insertActor(nSpr->sectnum, 100); + plr->pDoppleSprite = pDActor; if (nTotalPlayers > 1) { @@ -272,13 +267,12 @@ void RestartPlayer(short nPlayer) nSpr->x = nstspr->x; nSpr->y = nstspr->y; nSpr->z = nstspr->z; - mychangespritesect(nSprite, nstspr->sectnum); + ChangeActorSect(pActor, nstspr->sectnum); plr->angle.ang = buildang(nstspr->ang&kAngleMask); nSpr->ang = plr->angle.ang.asbuild(); - floorspr = insertsprite(nSpr->sectnum, 0); - assert(floorspr >= 0 && floorspr < kMaxSprites); - auto fspr = &sprite[floorspr]; + floorsprt = insertActor(nSpr->sectnum, 0); + auto fspr = &floorsprt->s(); fspr->x = nSpr->x; fspr->y = nSpr->y; @@ -290,19 +284,19 @@ void RestartPlayer(short nPlayer) } else { - nSpr->x = PlayerList[nPlayer].sPlayerSave.x; - nSpr->y = PlayerList[nPlayer].sPlayerSave.y; - nSpr->z = sector[PlayerList[nPlayer].sPlayerSave.nSector].floorz; - plr->angle.ang = buildang(PlayerList[nPlayer].sPlayerSave.nAngle&kAngleMask); + nSpr->x = plr->sPlayerSave.x; + nSpr->y = plr->sPlayerSave.y; + nSpr->z = sector[plr->sPlayerSave.nSector].floorz; + plr->angle.ang = buildang(plr->sPlayerSave.nAngle&kAngleMask); nSpr->ang = plr->angle.ang.asbuild(); - floorspr = -1; + floorsprt = nullptr; } plr->angle.backup(); plr->horizon.backup(); - PlayerList[nPlayer].nPlayerFloorSprite = floorspr; + plr->pPlayerFloorSprite = floorsprt; nSpr->cstat = 0x101; nSpr->shade = -12; @@ -314,7 +308,7 @@ void RestartPlayer(short nPlayer) nSpr->yoffset = 0; nSpr->picnum = seq_GetSeqPicnum(kSeqJoe, 18, 0); - int nHeight = GetSpriteHeight(nSprite); + int nHeight = GetActorHeight(pActor); nSpr->xvel = 0; nSpr->yvel = 0; nSpr->zvel = 0; @@ -325,7 +319,7 @@ void RestartPlayer(short nPlayer) nSpr->extra = -1; nSpr->lotag = runlist_HeadRun() + 1; - auto nDSpr = &sprite[nDSprite]; + auto nDSpr = &pDActor->s(); nDSpr->x = nSpr->x; nDSpr->y = nSpr->y; nDSpr->z = nSpr->z; @@ -347,30 +341,30 @@ void RestartPlayer(short nPlayer) } plr->field_2 = 0; - plr->nSprite = nSprite; + plr->pActor = pActor; plr->bIsMummified = false; if (plr->invincibility >= 0) { plr->invincibility = 0; } - PlayerList[nPlayer].nTorch = 0; + plr->nTorch = 0; plr->nMaskAmount = 0; SetTorch(nPlayer, 0); - PlayerList[nPlayer].nInvisible = 0; + plr->nInvisible = 0; plr->bIsFiring = 0; plr->field_3FOUR = 0; - PlayerList[nPlayer].nPlayerViewSect = PlayerList[nPlayer].sPlayerSave.nSector; + plr->nPlayerViewSect = plr->sPlayerSave.nSector; plr->field_3A = 0; - PlayerList[nPlayer].nDouble = 0; + plr->nDouble = 0; plr->nSeq = kSeqJoe; - PlayerList[nPlayer].nPlayerPushSound = -1; + plr->nPlayerPushSound = -1; plr->field_38 = -1; @@ -391,19 +385,19 @@ void RestartPlayer(short nPlayer) plr->nMagic = 0; } - PlayerList[nPlayer].nPlayerGrenade = nullptr; - PlayerList[nPlayer].oeyelevel = PlayerList[nPlayer].eyelevel = -14080; + plr->pPlayerGrenade = nullptr; + plr->oeyelevel = plr->eyelevel = -14080; dVertPan[nPlayer] = 0; nTemperature[nPlayer] = 0; - PlayerList[nPlayer].nYDamage = 0; - PlayerList[nPlayer].nXDamage = 0; + plr->nYDamage = 0; + plr->nXDamage = 0; plr->nDestVertPan = plr->horizon.ohoriz = plr->horizon.horiz = q16horiz(0); - PlayerList[nPlayer].nBreathTimer = 90; + plr->nBreathTimer = 90; - PlayerList[nPlayer].nTauntTimer = RandomSize(3) + 3; + plr->nTauntTimer = RandomSize(3) + 3; nDSpr->owner = runlist_AddRunRec(nDSpr->lotag - 1, nPlayer, 0xA0000); nSpr->owner = runlist_AddRunRec(nSpr->lotag - 1, nPlayer, 0xA0000); @@ -416,19 +410,16 @@ void RestartPlayer(short nPlayer) if (nPlayer == nLocalPlayer) { - nLocalSpr = nSprite; - RestoreGreenPal(); - plr->bPlayerPan = plr->bLockPan = false; } - PlayerList[nPlayer].ototalvel = PlayerList[nPlayer].totalvel = 0; + plr->ototalvel = plr->totalvel = 0; memset(&sPlayerInput[nPlayer], 0, sizeof(PlayerInput)); sPlayerInput[nPlayer].nItem = -1; - PlayerList[nPlayer].nDeathType = 0; + plr->nDeathType = 0; nQuake[nPlayer] = 0; } @@ -445,17 +436,17 @@ void StartDeathSeq(int nPlayer, int nVal) { FreeRa(nPlayer); - short nSprite = PlayerList[nPlayer].nSprite; - auto pSprite = &sprite[nSprite]; + auto pActor = PlayerList[nPlayer].Actor(); + auto pSprite = &pActor->s(); PlayerList[nPlayer].nHealth = 0; - short nLotag = sector[pSprite->sectnum].lotag; + short nLotag = pSprite->sector()->lotag; if (nLotag > 0) { - runlist_SignalRun(nLotag - 1, nPlayer | 0x70000); + runlist_SignalRun(nLotag - 1, nPlayer, &ExhumedAI::EnterSector); } - if (PlayerList[nPlayer].nPlayerGrenade) + if (PlayerList[nPlayer].pPlayerGrenade) { ThrowGrenade(nPlayer, 0, 0, 0, -10000); } @@ -467,7 +458,7 @@ void StartDeathSeq(int nPlayer, int nVal) if (nWeapon > kWeaponSword && nWeapon <= kWeaponRing) { - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; if (SectBelow[nSector] > -1) { nSector = SectBelow[nSector]; } @@ -568,8 +559,8 @@ int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount) void SetPlayerMummified(int nPlayer, int bIsMummified) { - int nSprite = PlayerList[nPlayer].nSprite; - auto pSprite = &sprite[nSprite]; + auto pActor = PlayerList[nPlayer].pActor; + auto pSprite = &pActor->s(); pSprite->yvel = 0; pSprite->xvel = 0; @@ -617,7 +608,8 @@ static void pickupMessage(int no) void UpdatePlayerSpriteAngle(Player* pPlayer) { - inita = sprite[pPlayer->nSprite].ang = pPlayer->angle.ang.asbuild(); + inita = pPlayer->angle.ang.asbuild(); + if (pPlayer->Actor()) pPlayer->Actor()->s().ang = inita; } void AIPlayer::Draw(RunListEvent* ev) @@ -634,36 +626,31 @@ void AIPlayer::RadialDamage(RunListEvent* ev) short nPlayer = RunData[ev->nRun].nObjIndex; assert(nPlayer >= 0 && nPlayer < kMaxPlayers); - short nPlayerSprite = PlayerList[nPlayer].nSprite; + auto pPlayerActor = PlayerList[nPlayer].Actor(); if (PlayerList[nPlayer].nHealth <= 0) { return; } - ev->nDamage = runlist_CheckRadialDamage(nPlayerSprite); + ev->nDamage = runlist_CheckRadialDamage(pPlayerActor); Damage(ev); } void AIPlayer::Damage(RunListEvent* ev) { - int nSprite2; int nDamage = ev->nDamage; short nPlayer = RunData[ev->nRun].nObjIndex; + auto pPlayerActor = PlayerList[nPlayer].Actor(); short nAction = PlayerList[nPlayer].nAction; - short nPlayerSprite = PlayerList[nPlayer].nSprite; - auto pPlayerSprite = &sprite[nPlayerSprite]; - short nDopple = PlayerList[nPlayer].nDoppleSprite; + auto pPlayerSprite = &pPlayerActor->s(); + auto pDopple = PlayerList[nPlayer].pDoppleSprite; if (!nDamage) { return; } - if (ev->nMessage != EMessageType::RadialDamage) - { - nSprite2 = ev->nParam; - } - else nSprite2 = nRadialOwner; + DExhumedActor* pActor2 = (!ev->isRadialEvent()) ? ev->pOtherActor : ev->pRadialActor->pTarget; // ok continue case 0x80000 as normal, loc_1C57C if (!PlayerList[nPlayer].nHealth) { @@ -703,12 +690,12 @@ void AIPlayer::Damage(RunListEvent* ev) PlayerList[nPlayer].field_2 = 0; PlayerList[nPlayer].nAction = 4; - if (nSprite2 > -1) + if (pActor2) { PlayerList[nPlayer].nPlayerSwear--; if (PlayerList[nPlayer].nPlayerSwear <= 0) { - D3PlayFX(StaticSound[kSound52], nDopple); + D3PlayFX(StaticSound[kSound52], pDopple); PlayerList[nPlayer].nPlayerSwear = RandomSize(3) + 4; } } @@ -721,9 +708,9 @@ void AIPlayer::Damage(RunListEvent* ev) else { // player has died - if (nSprite2 > -1 && sprite[nSprite2].statnum == 100) + if (pActor2 && pActor2->s().statnum == 100) { - short nPlayer2 = GetPlayerFromSprite(nSprite2); + short nPlayer2 = GetPlayerFromActor(pActor2); if (nPlayer2 == nPlayer) // player caused their own death { @@ -734,16 +721,16 @@ void AIPlayer::Damage(RunListEvent* ev) PlayerList[nPlayer].nPlayerScore++; } } - else if (nSprite2 < 0) + else if (pActor2 == nullptr) { PlayerList[nPlayer].nPlayerScore--; } - if (ev->nMessage == EMessageType::RadialDamage) + if (ev->isRadialEvent()) { for (int i = 122; i <= 131; i++) { - BuildCreatureChunk(nPlayerSprite, seq_GetSeqPicnum(kSeqJoe, i, 0)); + BuildCreatureChunk(pPlayerActor, seq_GetSeqPicnum(kSeqJoe, i, 0)); } StartDeathSeq(nPlayer, 1); @@ -766,10 +753,9 @@ void AIPlayer::Tick(RunListEvent* ev) assert(nPlayer >= 0 && nPlayer < kMaxPlayers); auto pPlayerActor = PlayerList[nPlayer].Actor(); - int nPlayerSprite = PlayerList[nPlayer].nSprite; auto pPlayerSprite = &pPlayerActor->s(); - short nDopple = PlayerList[nPlayer].nDoppleSprite; + auto pDopple = PlayerList[nPlayer].pDoppleSprite; short nAction = PlayerList[nPlayer].nAction; short nActionB = PlayerList[nPlayer].nAction; @@ -792,7 +778,7 @@ void AIPlayer::Tick(RunListEvent* ev) int var_EC = PlayerList[nPlayer].field_2; pPlayerSprite->picnum = seq_GetSeqPicnum(PlayerList[nPlayer].nSeq, PlayerSeq[nHeightTemplate[nAction]].a, var_EC); - sprite[nDopple].picnum = pPlayerSprite->picnum; + pDopple->s().picnum = pPlayerSprite->picnum; if (PlayerList[nPlayer].nTorch > 0) { @@ -828,10 +814,10 @@ void AIPlayer::Tick(RunListEvent* ev) if (PlayerList[nPlayer].nInvisible == 0) { pPlayerSprite->cstat &= 0x7FFF; // set visible - short nFloorSprite = PlayerList[nPlayer].nPlayerFloorSprite; + auto pFloorSprite = PlayerList[nPlayer].pPlayerFloorSprite; - if (nFloorSprite > -1) { - sprite[nFloorSprite].cstat &= 0x7FFF; // set visible + if (pFloorSprite != nullptr) { + pFloorSprite->s().cstat &= 0x7FFF; // set visible } } else if (PlayerList[nPlayer].nInvisible == 150 && nPlayer == nLocalPlayer) @@ -874,11 +860,11 @@ void AIPlayer::Tick(RunListEvent* ev) if (pPlayerSprite->zvel >= 6500 && zVel < 6500) { - D3PlayFX(StaticSound[kSound17], nPlayerSprite); + D3PlayFX(StaticSound[kSound17], pPlayerActor); } // loc_1A4E6 - short nSector = pPlayerSprite->sectnum; + int nSector =pPlayerSprite->sectnum; short nSectFlag = SectFlag[PlayerList[nPlayer].nPlayerViewSect]; int playerX = pPlayerSprite->x; @@ -907,36 +893,33 @@ void AIPlayer::Tick(RunListEvent* ev) zVel = pPlayerSprite->zvel; - int nMove = 0; // TEMP - + Collision nMove(0); if (bSlipMode) { - nMove = 0; - pPlayerSprite->x += (x >> 14); pPlayerSprite->y += (y >> 14); vec3_t pos = { pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z }; - setsprite(nPlayerSprite, &pos); + setActorPos(pPlayerActor, &pos); - pPlayerSprite->z = sector[pPlayerSprite->sectnum].floorz; + pPlayerSprite->z = pPlayerSprite->sector()->floorz; } else { - nMove = movesprite(nPlayerSprite, x, y, z, 5120, -5120, CLIPMASK0); + nMove = movesprite(pPlayerActor, x, y, z, 5120, -5120, CLIPMASK0); - short var_54 = pPlayerSprite->sectnum; + int var_54 = pPlayerSprite->sectnum; - pushmove_old(&pPlayerSprite->x, &pPlayerSprite->y, &pPlayerSprite->z, &var_54, pPlayerSprite->clipdist << 2, 5120, -5120, CLIPMASK0); + pushmove(&pPlayerSprite->pos, &var_54, pPlayerSprite->clipdist << 2, 5120, -5120, CLIPMASK0); if (var_54 != pPlayerSprite->sectnum) { - mychangespritesect(nPlayerSprite, var_54); + ChangeActorSect(pPlayerActor, var_54); } } // loc_1A6E4 if (inside(pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->sectnum) != 1) { - mychangespritesect(nPlayerSprite, spr_sectnum); + ChangeActorSect(pPlayerActor, spr_sectnum); pPlayerSprite->x = spr_x; pPlayerSprite->y = spr_y; @@ -960,7 +943,7 @@ void AIPlayer::Tick(RunListEvent* ev) { if (nTotalPlayers <= 1) { - auto ang = GetAngleToSprite(pPlayerActor, &exhumedActors[nSpiritSprite]) & kAngleMask; + auto ang = GetAngleToSprite(pPlayerActor, pSpiritSprite) & kAngleMask; PlayerList[nPlayer].angle.settarget(ang, true); pPlayerSprite->ang = ang; @@ -992,7 +975,7 @@ void AIPlayer::Tick(RunListEvent* ev) return; } - if (nMove & 0x3C000) + if (nMove.type || nMove.exbits) { if (bTouchFloor) { @@ -1018,41 +1001,43 @@ void AIPlayer::Tick(RunListEvent* ev) pPlayerSprite->xvel >>= 2; pPlayerSprite->yvel >>= 2; - runlist_DamageEnemy(nPlayerSprite, -1, ((zVel - 6500) >> 7) + 10); + runlist_DamageEnemy(pPlayerActor, nullptr, ((zVel - 6500) >> 7) + 10); if (PlayerList[nPlayer].nHealth <= 0) { pPlayerSprite->xvel = 0; pPlayerSprite->yvel = 0; - StopSpriteSound(nPlayerSprite); + StopActorSound(pPlayerActor); PlayFXAtXYZ(StaticSound[kSoundJonFDie], pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z, pPlayerSprite->sectnum, CHANF_NONE, 1); // CHECKME } else { - D3PlayFX(StaticSound[kSound27] | 0x2000, nPlayerSprite); + D3PlayFX(StaticSound[kSound27] | 0x2000, pPlayerActor); } } } - if (((nMove & 0xC000) == 0x4000) || ((nMove & 0xC000) == 0x8000)) + if (nMove.type == kHitSector || nMove.type == kHitWall) { int sectnum = 0; + int nNormal = 0; - if ((nMove & 0xC000) == 0x4000) + if (nMove.type == kHitSector) { - sectnum = nMove & 0x3FFF; + sectnum = nMove.index; + // Hm... Normal calculation here was broken. } - else if ((nMove & 0xC000) == 0x8000) + else if (nMove.type == kHitWall) { - sectnum = wall[nMove & 0x3FFF].nextsector; + sectnum = wall[nMove.index].nextsector; + nNormal = GetWallNormal(nMove.index); } if (sectnum >= 0) { if ((sector[sectnum].hitag == 45) && bTouchFloor) { - int nNormal = GetWallNormal(nMove & 0x3FFF); int nDiff = AngleDiff(nNormal, (pPlayerSprite->ang + 1024) & kAngleMask); if (nDiff < 0) { @@ -1074,9 +1059,9 @@ void AIPlayer::Tick(RunListEvent* ev) { PlayerList[nPlayer].nPlayerPushSound = 1; short nBlock = sector[PlayerList[nPlayer].nPlayerPushSect].extra; - int nBlockSprite = sBlockInfo[nBlock].nSprite; + auto pBlockActor = sBlockInfo[nBlock].pActor; - D3PlayFX(StaticSound[kSound23], nBlockSprite, 0x4000); + D3PlayFX(StaticSound[kSound23], pBlockActor, 0x4000); } else { @@ -1084,10 +1069,10 @@ void AIPlayer::Tick(RunListEvent* ev) pPlayerSprite->y = spr_y; pPlayerSprite->z = spr_z; - mychangespritesect(nPlayerSprite, spr_sectnum); + ChangeActorSect(pPlayerActor, spr_sectnum); } - movesprite(nPlayerSprite, xvel, yvel, z, 5120, -5120, CLIPMASK0); + movesprite(pPlayerActor, xvel, yvel, z, 5120, -5120, CLIPMASK0); goto sectdone; } } @@ -1100,7 +1085,7 @@ void AIPlayer::Tick(RunListEvent* ev) { if (PlayerList[nPlayer].nPlayerPushSect > -1) { - StopSpriteSound(sBlockInfo[sector[PlayerList[nPlayer].nPlayerPushSect].extra].nSprite); + StopActorSound(sBlockInfo[sector[PlayerList[nPlayer].nPlayerPushSect].extra].pActor); } PlayerList[nPlayer].nPlayerPushSound = -1; @@ -1148,13 +1133,13 @@ sectdone: { if (nViewSect != pPlayerSprite->sectnum) { - if ((nMove & 0xC000) == 0x8000) + if (nMove.type == kHitWall) { int var_C4 = pPlayerSprite->x; int var_D4 = pPlayerSprite->y; int var_C8 = pPlayerSprite->z; - mychangespritesect(nPlayerSprite, nViewSect); + ChangeActorSect(pPlayerActor, nViewSect); pPlayerSprite->x = spr_x; pPlayerSprite->y = spr_y; @@ -1163,9 +1148,10 @@ sectdone: pPlayerSprite->z = var_FC; - if ((movesprite(nPlayerSprite, x, y, 0, 5120, 0, CLIPMASK0) & 0xC000) == 0x8000) + auto coll = movesprite(pPlayerActor, x, y, 0, 5120, 0, CLIPMASK0); + if (coll.type == kHitWall) { - mychangespritesect(nPlayerSprite, pPlayerSprite->sectnum); + ChangeActorSect(pPlayerActor, pPlayerSprite->sectnum); pPlayerSprite->x = var_C4; pPlayerSprite->y = var_D4; @@ -1174,7 +1160,7 @@ sectdone: else { pPlayerSprite->z = var_FC - 256; - D3PlayFX(StaticSound[kSound42], nPlayerSprite); + D3PlayFX(StaticSound[kSound42], pPlayerActor); } } } @@ -1216,7 +1202,7 @@ sectdone: { if (PlayerList[nPlayer].nMaskAmount > 0) { - D3PlayFX(StaticSound[kSound30], nPlayerSprite); + D3PlayFX(StaticSound[kSound30], pPlayerActor); PlayerList[nPlayer].nAir = 100; } @@ -1225,7 +1211,7 @@ sectdone: PlayerList[nPlayer].nAir -= 25; if (PlayerList[nPlayer].nAir > 0) { - D3PlayFX(StaticSound[kSound25], nPlayerSprite); + D3PlayFX(StaticSound[kSound25], pPlayerActor); } else { @@ -1240,11 +1226,11 @@ sectdone: if (PlayerList[nPlayer].nHealth < 300) { - D3PlayFX(StaticSound[kSound79], nPlayerSprite); + D3PlayFX(StaticSound[kSound79], pPlayerActor); } else { - D3PlayFX(StaticSound[kSound19], nPlayerSprite); + D3PlayFX(StaticSound[kSound19], pPlayerActor); } } } @@ -1271,7 +1257,7 @@ sectdone: { if (SectDepth[nTmpSectNum] && !SectSpeed[nTmpSectNum] && !SectDamage[nTmpSectNum]) { - D3PlayFX(StaticSound[kSound42], nPlayerSprite); + D3PlayFX(StaticSound[kSound42], pPlayerActor); } } @@ -1280,7 +1266,7 @@ sectdone: { if (PlayerList[nPlayer].nAir < 50) { - D3PlayFX(StaticSound[kSound14], nPlayerSprite); + D3PlayFX(StaticSound[kSound14], pPlayerActor); } PlayerList[nPlayer].nBreathTimer = 1; @@ -1299,19 +1285,20 @@ sectdone: } // loc_1B1EB - if (nTotalPlayers > 1) + auto pFloorActor = PlayerList[nPlayer].pPlayerFloorSprite; + if (nTotalPlayers > 1 && pFloorActor) { - int nFloorSprite = PlayerList[nPlayer].nPlayerFloorSprite; + auto pFloorSprite = &pFloorActor->s(); - sprite[nFloorSprite].x = pPlayerSprite->x; - sprite[nFloorSprite].y = pPlayerSprite->y; + pFloorSprite->x = pPlayerSprite->x; + pFloorSprite->y = pPlayerSprite->y; - if (sprite[nFloorSprite].sectnum != pPlayerSprite->sectnum) + if (pFloorSprite->sectnum != pPlayerSprite->sectnum) { - mychangespritesect(nFloorSprite, pPlayerSprite->sectnum); + ChangeActorSect(pFloorActor, pPlayerSprite->sectnum); } - sprite[nFloorSprite].z = sector[pPlayerSprite->sectnum].floorz; + pFloorSprite->z = pPlayerSprite->sector()->floorz; } int var_30 = 0; @@ -1330,20 +1317,17 @@ sectdone: short nearTagSector, nearTagWall, nearTagSprite; int nearHitDist; - short nValB; - // neartag finds the nearest sector, wall, and sprite which has its hitag and/or lotag set to a value. neartag(pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z, pPlayerSprite->sectnum, pPlayerSprite->ang, - &nearTagSector, &nearTagWall, &nearTagSprite, (int32_t*)&nearHitDist, 1024, 2, NULL); + &nearTagSector, &nearTagWall, &nearTagSprite, (int32_t*)&nearHitDist, 1024, 2, nullptr); - feebtag(pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z, pPlayerSprite->sectnum, - &nValB, var_30, 768); + DExhumedActor* pActorB; + feebtag(pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z, pPlayerSprite->sectnum, &pActorB, var_30, 768); - auto pActorB = &exhumedActors[nValB]; - auto pSpriteB = &pActorB->s(); // Item pickup code - if (nValB >= 0 && pSpriteB->statnum >= 900) + if (pActorB != nullptr && pActorB->s().statnum >= 900) { + auto pSpriteB = &pActorB->s(); int var_8C = 16; int var_88 = 9; @@ -1365,8 +1349,11 @@ sectdone: // CHECKME - is order of evaluation correct? if (!mplevel || (var_70 >= 25 && (var_70 <= 25 || var_70 == 50))) { - DestroyItemAnim(pActorB); - DeleteActor(pActorB); + // If this is an anim we need to properly destroy it so we need to do some proper detection and not wild guesses. + if (pActorB->nRun == pActorB->nDamage && pActorB->nRun != 0 && pActorB->nPhase == ITEM_MAGIC) + DestroyAnim(pActorB); + else + DeleteActor(pActorB); } else { @@ -1709,7 +1696,7 @@ sectdone: if (PlayerList[nPlayer].nBreathTimer < 89) { - D3PlayFX(StaticSound[kSound13], nPlayerSprite); + D3PlayFX(StaticSound[kSound13], pPlayerActor); } PlayerList[nPlayer].nBreathTimer = 90; @@ -2253,9 +2240,9 @@ sectdone: // CORRECT ? // loc_1BAF9: if (bTouchFloor) { - if (sector[pPlayerSprite->sectnum].lotag > 0) + if (pPlayerSprite->sector()->lotag > 0) { - runlist_SignalRun(sector[pPlayerSprite->sectnum].lotag - 1, nPlayer | 0x50000); + runlist_SignalRun(pPlayerSprite->sector()->lotag - 1, nPlayer, &ExhumedAI::TouchFloor); } } @@ -2263,12 +2250,12 @@ sectdone: { if (sector[nSector].lotag > 0) { - runlist_SignalRun(sector[nSector].lotag - 1, nPlayer | 0x70000); + runlist_SignalRun(sector[nSector].lotag - 1, nPlayer, &ExhumedAI::EnterSector); } - if (sector[pPlayerSprite->sectnum].lotag > 0) + if (pPlayerSprite->sector()->lotag > 0) { - runlist_SignalRun(sector[pPlayerSprite->sectnum].lotag - 1, nPlayer | 0x60000); + runlist_SignalRun(pPlayerSprite->sector()->lotag - 1, nPlayer, &ExhumedAI::LeaveSector); } } @@ -2280,12 +2267,12 @@ sectdone: if (nearTagWall >= 0 && wall[nearTagWall].lotag > 0) { - runlist_SignalRun(wall[nearTagWall].lotag - 1, nPlayer | 0x40000); + runlist_SignalRun(wall[nearTagWall].lotag - 1, nPlayer, &ExhumedAI::Use); } if (nearTagSector >= 0 && sector[nearTagSector].lotag > 0) { - runlist_SignalRun(sector[nearTagSector].lotag - 1, nPlayer | 0x40000); + runlist_SignalRun(sector[nearTagSector].lotag - 1, nPlayer, &ExhumedAI::Use); } } @@ -2302,7 +2289,7 @@ sectdone: // loc_1BC57: // CHECKME - are we finished with 'nSector' variable at this point? if so, maybe set it to pPlayerSprite->sectnum so we can make this code a bit neater. Don't assume pPlayerSprite->sectnum == nSector here!! - if (nStandHeight > (sector[pPlayerSprite->sectnum].floorz - sector[pPlayerSprite->sectnum].ceilingz)) { + if (nStandHeight > (pPlayerSprite->sector()->floorz - pPlayerSprite->sector()->ceilingz)) { var_48 = 1; } @@ -2451,12 +2438,12 @@ sectdone: pPlayer->horizon.applyinput(sPlayerInput[nPlayer].pan, &sPlayerInput[nLocalPlayer].actions); } - if (actions & (SB_LOOK_UP | SB_LOOK_DOWN) || sPlayerInput[nPlayer].pan) + if (actions & (SB_AIM_UP | SB_AIM_DOWN) || sPlayerInput[nPlayer].pan) { pPlayer->nDestVertPan = pPlayer->horizon.horiz; pPlayer->bPlayerPan = pPlayer->bLockPan = true; } - else if (actions & (SB_AIM_UP | SB_AIM_DOWN | SB_CENTERVIEW)) + else if (actions & (SB_LOOK_UP | SB_LOOK_DOWN | SB_CENTERVIEW)) { pPlayer->nDestVertPan = pPlayer->horizon.horiz; pPlayer->bPlayerPan = pPlayer->bLockPan = false; @@ -2467,12 +2454,12 @@ sectdone: pPlayer->bPlayerPan = false; } - if (cl_slopetilting) + if (cl_slopetilting && !pPlayer->bPlayerPan && !pPlayer->bLockPan) { double nVertPan = (pPlayer->nDestVertPan - pPlayer->horizon.horiz).asbuildf() * 0.25; if (nVertPan != 0) { - pPlayer->horizon.addadjustment(abs(nVertPan) >= 4 ? clamp(nVertPan, -4, 4) : nVertPan * 2.); + pPlayer->horizon.addadjustment(abs(nVertPan) >= 4 ? clamp(nVertPan, -4., 4.) : nVertPan * 2.); } } } @@ -2500,14 +2487,14 @@ sectdone: { pPlayerSprite->picnum = seq_GetSeqPicnum(kSeqJoe, 120, 0); pPlayerSprite->cstat = 0; - pPlayerSprite->z = sector[pPlayerSprite->sectnum].floorz; + pPlayerSprite->z = pPlayerSprite->sector()->floorz; } // will invalidate nPlayerSprite RestartPlayer(nPlayer); - nPlayerSprite = PlayerList[nPlayer].nSprite; - nDopple = PlayerList[nPlayer].nDoppleSprite; + pPlayerActor = PlayerList[nPlayer].Actor(); + pDopple = PlayerList[nPlayer].pDoppleSprite; } else { @@ -2527,7 +2514,7 @@ sectdone: int var_AC = SeqOffsets[PlayerList[nPlayer].nSeq] + PlayerSeq[nAction].a; - seq_MoveSequence(nPlayerSprite, var_AC, PlayerList[nPlayer].field_2); + seq_MoveSequence(pPlayerActor, var_AC, PlayerList[nPlayer].field_2); PlayerList[nPlayer].field_2++; if (PlayerList[nPlayer].field_2 >= SeqSize[var_AC]) @@ -2548,17 +2535,17 @@ sectdone: case 16: PlayerList[nPlayer].field_2 = SeqSize[var_AC] - 1; - if (pPlayerSprite->z < sector[pPlayerSprite->sectnum].floorz) { + if (pPlayerSprite->z < pPlayerSprite->sector()->floorz) { pPlayerSprite->z += 256; } if (!RandomSize(5)) { - int mouthX, mouthY, mouthZ; - short mouthSect; - WheresMyMouth(nPlayer, &mouthX, &mouthY, &mouthZ, &mouthSect); + vec3_t pos; + int mouthSect; + WheresMyMouth(nPlayer, &pos, &mouthSect); - BuildAnim(nullptr, 71, 0, mouthX, mouthY, pPlayerSprite->z + 3840, mouthSect, 75, 128); + BuildAnim(nullptr, 71, 0, pos.x, pos.y, pPlayerSprite->z + 3840, mouthSect, 75, 128); } break; case 17: @@ -2620,33 +2607,23 @@ sectdone: } // loc_1C4E1 - sprite[nDopple].x = pPlayerSprite->x; - sprite[nDopple].y = pPlayerSprite->y; - sprite[nDopple].z = pPlayerSprite->z; + pDopple->s().pos = pPlayerSprite->pos; if (SectAbove[pPlayerSprite->sectnum] > -1) { - sprite[nDopple].ang = pPlayerSprite->ang; - mychangespritesect(nDopple, SectAbove[pPlayerSprite->sectnum]); - sprite[nDopple].cstat = 0x101; + pDopple->s().ang = pPlayerSprite->ang; + ChangeActorSect(pDopple, SectAbove[pPlayerSprite->sectnum]); + pDopple->s().cstat = 0x101; } else { - sprite[nDopple].cstat = 0x8000; + pDopple->s().cstat = 0x8000; } MoveWeapons(nPlayer); } - -void FuncPlayer(int nObject, int nMessage, int nDamage, int nRun) -{ - AIPlayer ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - - FSerializer& Serialize(FSerializer& arc, const char* keyname, Player& w, Player* def) { if (arc.BeginObject(keyname)) @@ -2654,7 +2631,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Player& w, Player* arc("health", w.nHealth) ("at2", w.field_2) ("action", w.nAction) - ("sprite", w.nSprite) + ("sprite", w.pActor) ("mummy", w.bIsMummified) ("invincible", w.invincibility) ("air", w.nAir) @@ -2689,18 +2666,18 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Player& w, Player* ("pistolclip", w.nPistolClip) ("xdamage", w.nXDamage) ("ydamage", w.nYDamage) - ("dopplesprite", w.nDoppleSprite) + ("dopplesprite", w.pDoppleSprite) ("oldweapon", w.nPlayerOldWeapon) ("clip", w.nPlayerClip) ("pushsound", w.nPlayerPushSound) ("taunttimer", w.nTauntTimer) ("weapons", w.nPlayerWeapons) ("viewsect", w.nPlayerViewSect) - ("floorspr", w.nPlayerFloorSprite) + ("floorspr", w.pPlayerFloorSprite) ("save", w.sPlayerSave) ("totalvel", w.totalvel) ("eyelevel", w.eyelevel) - ("grenade", w.nPlayerGrenade) + ("grenade", w.pPlayerGrenade) .EndObject(); } @@ -2748,7 +2725,7 @@ DEFINE_FIELD_X(ExhumedPlayer, Player, nInvisible); DEFINE_FIELD_X(ExhumedPlayer, Player, nTorch); DEFINE_FIELD_X(ExhumedPlayer, Player, field_2); DEFINE_FIELD_X(ExhumedPlayer, Player, nAction); -DEFINE_FIELD_X(ExhumedPlayer, Player, nSprite); +DEFINE_FIELD_X(ExhumedPlayer, Player, pActor); DEFINE_FIELD_X(ExhumedPlayer, Player, bIsMummified); DEFINE_FIELD_X(ExhumedPlayer, Player, invincibility); DEFINE_FIELD_X(ExhumedPlayer, Player, nAir); @@ -2795,7 +2772,7 @@ DEFINE_ACTION_FUNCTION(_ExhumedPlayer, IsUnderwater) DEFINE_ACTION_FUNCTION(_ExhumedPlayer, GetAngle) { PARAM_SELF_STRUCT_PROLOGUE(Player); - ACTION_RETURN_INT(sprite[self->nSprite].ang); + ACTION_RETURN_INT(self->Actor()->s().ang); } diff --git a/source/games/exhumed/src/player.h b/source/games/exhumed/src/player.h index 86e3d8747..81f9cb1c7 100644 --- a/source/games/exhumed/src/player.h +++ b/source/games/exhumed/src/player.h @@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS void RestoreSavePoint(int nPlayer, int *x, int *y, int *z, short *nSector, short *nAngle); -void SetSavePoint(int nPlayer, int x, int y, int z, short nSector, short nAngle); +void SetSavePoint(int nPlayer, int x, int y, int z, int nSector, short nAngle); void InitPlayer(); void InitPlayerKeys(short nPlayer); int GrabPlayer(); @@ -52,13 +52,14 @@ struct PlayerSave int x; int y; int z; - short nSector; + int nSector; short nAngle; }; struct Player { - DExhumedActor* Actor() { return nSprite == -1? nullptr : &exhumedActors[nSprite]; } + DExhumedActor* Actor() { return pActor; } + DExhumedActor* pActor; short nHealth; short nLives; short nDouble; @@ -66,7 +67,6 @@ struct Player short nTorch; short field_2; short nAction; - short nSprite; short bIsMummified; short invincibility; short nAir; @@ -102,19 +102,19 @@ struct Player short nPistolClip; int nXDamage; int nYDamage; - short nDoppleSprite; short nPlayerOldWeapon; short nPlayerClip; short nPlayerPushSound; short nTauntTimer; uint16_t nPlayerWeapons; // each set bit represents a weapon the player has short nPlayerViewSect; - short nPlayerFloorSprite; PlayerSave sPlayerSave; int ototalvel; int totalvel; int16_t eyelevel, oeyelevel; - DExhumedActor* nPlayerGrenade; + DExhumedActor* pPlayerGrenade; + DExhumedActor* pPlayerFloorSprite; + DExhumedActor* pDoppleSprite; }; @@ -128,11 +128,7 @@ extern DExhumedActor* nNetStartSprite[kMaxPlayers]; extern short nNetStartSprites; extern short nCurStartSprite; -short GetPlayerFromSprite(short nSprite); -short GetPlayerFromActor(DExhumedActor* actor) -{ - return GetPlayerFromSprite(actor->GetSpriteIndex()); -} +short GetPlayerFromActor(DExhumedActor* actor); void SetPlayerMummified(int nPlayer, int bIsMummified); int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount); void ShootStaff(int nPlayer); diff --git a/source/games/exhumed/src/queen.cpp b/source/games/exhumed/src/queen.cpp index 37ca4dc28..b9c654c3d 100644 --- a/source/games/exhumed/src/queen.cpp +++ b/source/games/exhumed/src/queen.cpp @@ -384,7 +384,7 @@ void BuildTail() int x = pSprite->x; int y = pSprite->x; int z = pSprite->x; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; int i; @@ -437,7 +437,7 @@ void BuildQueenEgg(short nQueen, int nVal) int x = pSprite->x; int y = pSprite->y; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; int nFloorZ = sector[nSector].floorz; short nAngle = pSprite->ang; @@ -690,13 +690,6 @@ void AIQueenEgg::Draw(RunListEvent* ev) seq_PlotSequence(ev->nParam, SeqOffsets[kSeqQueenEgg] + EggSeq[pEgg->nAction].a, pEgg->nFrame, EggSeq[pEgg->nAction].b); } - -void FuncQueenEgg(int nObject, int nMessage, int nDamage, int nRun) -{ - AIQueenEgg ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - void BuildQueenHead(short nQueen) { auto pActor = QueenList[nQueen].pActor; @@ -705,7 +698,7 @@ void BuildQueenHead(short nQueen) int x = pSprite->x; int y = pSprite->y; short nAngle = pSprite->ang; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; int z = sector[nSector].floorz; auto pActor2 = insertActor(nSector, 121); @@ -927,7 +920,7 @@ void AIQueenHead::Tick(RunListEvent* ev) MoveQX[nQHead] = pSprite->x; MoveQY[nQHead] = pSprite->y; MoveQZ[nQHead] = pSprite->z; - assert(pSprite->sectnum >= 0 && pSprite->sectnum < kMaxSectors); + assert(validSectorIndex(pSprite->sectnum)); MoveQS[nQHead] = pSprite->sectnum; MoveQA[nQHead] = pSprite->ang; @@ -980,7 +973,7 @@ void AIQueenHead::Tick(RunListEvent* ev) int x = pSprite->x; int y = pSprite->y; int z = pSprite->z; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; int nAngle = RandomSize(11) & kAngleMask; pSprite->xrepeat = 127 - QueenHead.nIndex2; @@ -1109,13 +1102,6 @@ void AIQueenHead::Draw(RunListEvent* ev) seq_PlotSequence(ev->nParam, nSeq, QueenHead.nFrame, edx); } - -void FuncQueenHead(int nObject, int nMessage, int nDamage, int nRun) -{ - AIQueenHead ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - void BuildQueen(DExhumedActor* pActor, int x, int y, int z, int nSector, int nAngle, int nChannel) { QueenCount--; @@ -1137,7 +1123,7 @@ void BuildQueen(DExhumedActor* pActor, int x, int y, int z, int nSector, int nAn pSprite = &pActor->s(); x = pSprite->x; y = pSprite->y; - z = sector[pSprite->sectnum].floorz; + z = pSprite->sector()->floorz; nAngle = pSprite->ang; } @@ -1531,10 +1517,4 @@ void AIQueen::Draw(RunListEvent* ev) seq_PlotSequence(ev->nParam, SeqOffsets[kSeqQueen] + QueenSeq[nAction].a, QueenList[nQueen].nFrame, QueenSeq[nAction].b); } -void FuncQueen(int nObject, int nMessage, int nDamage, int nRun) -{ - AIQueen ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/exhumed/src/ra.cpp b/source/games/exhumed/src/ra.cpp index be2665865..6e796963f 100644 --- a/source/games/exhumed/src/ra.cpp +++ b/source/games/exhumed/src/ra.cpp @@ -75,9 +75,10 @@ void FreeRa(short nPlayer) void BuildRa(short nPlayer) { - short nPlayerSprite = PlayerList[nPlayer].nSprite; + auto pPlayerActor = PlayerList[nPlayer].Actor(); + auto pPlayerSprite = &pPlayerActor->s(); - auto pActor = insertActor(sprite[nPlayerSprite].sectnum, 203); + auto pActor = insertActor(pPlayerSprite->sectnum, 203); auto pSprite = &pActor->s(); pSprite->cstat = 0x8000; @@ -91,9 +92,7 @@ void BuildRa(short nPlayer) pSprite->pal = 1; pSprite->xrepeat = 64; pSprite->yrepeat = 64; - pSprite->x = sprite[nPlayerSprite].x; - pSprite->y = sprite[nPlayerSprite].y; - pSprite->z = sprite[nPlayerSprite].z; + pSprite->pos = pPlayerSprite->pos; // GrabTimeSlot(3); @@ -122,7 +121,7 @@ void MoveRaToEnemy(short nPlayer) if (pTarget) { auto pTargSprite = &pTarget->s(); - if (!(pTargSprite->cstat & 0x101) || pTargSprite->sectnum == MAXSECTORS) + if (!(pTargSprite->cstat & 0x101) || pTargSprite->statnum == MAXSTATUS) { Ra[nPlayer].pTarget = nullptr; if (nAction == 0 || nAction == 3) { @@ -178,7 +177,7 @@ void AIRa::Tick(RunListEvent* ev) bool bVal = false; - Ra[nPlayer].pTarget = sPlayerInput[nPlayer].nTarget <= -1? nullptr : &exhumedActors[sPlayerInput[nPlayer].nTarget] ; + Ra[nPlayer].pTarget = sPlayerInput[nPlayer].pTarget; pSprite->picnum = seq_GetSeqPicnum2(nSeq, Ra[nPlayer].nFrame); if (Ra[nPlayer].nAction) @@ -299,11 +298,5 @@ void AIRa::Draw(RunListEvent* ev) ev->pTSprite->owner = -1; } -void FuncRa(int nObject, int nMessage, int nDamage, int nRun) -{ - AIRa ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); - -} END_PS_NS diff --git a/source/games/exhumed/src/ramses.cpp b/source/games/exhumed/src/ramses.cpp index 45b30000f..0db4c11ec 100644 --- a/source/games/exhumed/src/ramses.cpp +++ b/source/games/exhumed/src/ramses.cpp @@ -57,7 +57,7 @@ short word_964EC = 10; short nSpiritRepeatX; short nSpiritRepeatY; -short nSpiritSprite; +DExhumedActor* pSpiritSprite; short nPixelsToShow; short nTalkTime = 0; @@ -65,18 +65,19 @@ short nTalkTime = 0; void InitSpiritHead() { nPixels = 0; - auto pSpiritSprite = &sprite[nSpiritSprite]; + auto pSpiritSpr = &pSpiritSprite->s(); - nSpiritRepeatX = pSpiritSprite->xrepeat; - nSpiritRepeatY = pSpiritSprite->yrepeat; + nSpiritRepeatX = pSpiritSpr->xrepeat; + nSpiritRepeatY = pSpiritSpr->yrepeat; tileLoad(kTileRamsesNormal); // Ramses Normal Head - for (int i = 0; i < kMaxSprites; i++) + ExhumedSpriteIterator it; + while (auto act = it.Next()) { - if (sprite[i].statnum) + if (act->s().statnum) { - sprite[i].cstat |= 0x8000; + act->s().cstat |= 0x8000; } } @@ -116,16 +117,16 @@ void InitSpiritHead() } - pSpiritSprite->yrepeat = 140; - pSpiritSprite->xrepeat = 140; - pSpiritSprite->picnum = kTileRamsesWorkTile; + pSpiritSpr->yrepeat = 140; + pSpiritSpr->xrepeat = 140; + pSpiritSpr->picnum = kTileRamsesWorkTile; nHeadStage = 0; // work tile is twice as big as the normal head size Worktile = TileFiles.tileCreate(kTileRamsesWorkTile, kSpiritY * 2, kSpiritX * 2); - pSpiritSprite->cstat &= 0x7FFF; + pSpiritSpr->cstat &= 0x7FFF; nHeadTimeStart = PlayClock; @@ -158,10 +159,10 @@ void InitSpiritHead() nTalkTime = 1; } -void DimSector(short nSector) +void DimSector(int nSector) { - short startwall = sector[nSector].wallptr; - short nWalls = sector[nSector].wallnum; + int startwall = sector[nSector].wallptr; + int nWalls = sector[nSector].wallnum; for (int i = 0; i < nWalls; i++) { @@ -197,7 +198,7 @@ void CopyHeadToWorkTile(short nTile) void DoSpiritHead() { static short dimSectCount = 0; - auto pSpiritSprite = &sprite[nSpiritSprite]; + auto pSpiritSpr = &pSpiritSprite->s(); sPlayerInput[0].actions |= SB_CENTERVIEW; TileFiles.InvalidateTile(kTileRamsesWorkTile); @@ -297,11 +298,11 @@ void DoSpiritHead() case 1: case 2: UpdateSwirlies(); - if (pSpiritSprite->shade > -127) - pSpiritSprite->shade--; + if (pSpiritSpr->shade > -127) + pSpiritSpr->shade--; if (--dimSectCount < 0) { - DimSector(pSpiritSprite->sectnum); + DimSector(pSpiritSpr->sectnum); dimSectCount = 5; } @@ -381,17 +382,17 @@ void DoSpiritHead() if (nHeadStage == 1) { - if (pSpiritSprite->xrepeat > nSpiritRepeatX) + if (pSpiritSpr->xrepeat > nSpiritRepeatX) { - pSpiritSprite->xrepeat -= 2; - if (pSpiritSprite->xrepeat < nSpiritRepeatX) - pSpiritSprite->xrepeat = (uint8_t)nSpiritRepeatX; + pSpiritSpr->xrepeat -= 2; + if (pSpiritSpr->xrepeat < nSpiritRepeatX) + pSpiritSpr->xrepeat = (uint8_t)nSpiritRepeatX; } - if (pSpiritSprite->yrepeat > nSpiritRepeatY) + if (pSpiritSpr->yrepeat > nSpiritRepeatY) { - pSpiritSprite->yrepeat -= 2; - if (pSpiritSprite->yrepeat < nSpiritRepeatY) - pSpiritSprite->yrepeat = (uint8_t)nSpiritRepeatY; + pSpiritSpr->yrepeat -= 2; + if (pSpiritSpr->yrepeat < nSpiritRepeatY) + pSpiritSpr->yrepeat = (uint8_t)nSpiritRepeatY; } int nCount = 0; @@ -427,9 +428,9 @@ void DoSpiritHead() if (nCount < (15 * nPixels) / 16) { SoundBigEntrance(); - AddGlow(pSpiritSprite->sectnum, 20); - AddFlash(pSpiritSprite->sectnum, pSpiritSprite->x, pSpiritSprite->y, - pSpiritSprite->z, 128); + AddGlow(pSpiritSpr->sectnum, 20); + AddFlash(pSpiritSpr->sectnum, pSpiritSpr->x, pSpiritSpr->y, + pSpiritSpr->z, 128); nHeadStage = 3; TintPalette(255, 255, 255); CopyHeadToWorkTile(kTileRamsesNormal); diff --git a/source/games/exhumed/src/random.cpp b/source/games/exhumed/src/random.cpp index f709aeef7..d0fbb3991 100644 --- a/source/games/exhumed/src/random.cpp +++ b/source/games/exhumed/src/random.cpp @@ -52,9 +52,9 @@ int RandomBit() return (((randA == 0) & randC) | (randB & randA)) & 1; } -char RandomByte() +uint8_t RandomByte() { - char randByte = RandomBit() << 7; + uint8_t randByte = RandomBit() << 7; randByte |= RandomBit() << 6; randByte |= RandomBit() << 5; randByte |= RandomBit() << 4; @@ -67,7 +67,7 @@ char RandomByte() uint16_t RandomWord() { - short randWord = RandomByte() << 8; + uint16_t randWord = RandomByte() << 8; randWord |= RandomByte(); return randWord; } diff --git a/source/games/exhumed/src/rat.cpp b/source/games/exhumed/src/rat.cpp index 853bbbd7d..e49c1944d 100644 --- a/source/games/exhumed/src/rat.cpp +++ b/source/games/exhumed/src/rat.cpp @@ -73,7 +73,7 @@ void SetRatVel(spritetype* pSprite) pSprite->yvel = bsin(pSprite->ang, -2); } -void BuildRat(DExhumedActor* pActor, int x, int y, int z, short nSector, int nAngle) +void BuildRat(DExhumedActor* pActor, int x, int y, int z, int nSector, int nAngle) { spritetype* pSprite; if (pActor == nullptr) @@ -97,7 +97,7 @@ void BuildRat(DExhumedActor* pActor, int x, int y, int z, short nSector, int nAn pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->picnum = 1; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->clipdist = 30; pSprite->ang = nAngle; pSprite->xrepeat = 50; @@ -372,11 +372,4 @@ void AIRat::Tick(RunListEvent* ev) } } - -void FuncRat(int nObject, int nMessage, int nDamage, int nRun) -{ - AIRat ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/exhumed/src/rex.cpp b/source/games/exhumed/src/rex.cpp index 103bb24d7..89bf800c1 100644 --- a/source/games/exhumed/src/rex.cpp +++ b/source/games/exhumed/src/rex.cpp @@ -37,7 +37,7 @@ static actionSeq RexSeq[] = { {28, 1} }; -void BuildRex(DExhumedActor* pActor, int x, int y, int z, short nSector, short nAngle, int nChannel) +void BuildRex(DExhumedActor* pActor, int x, int y, int z, int nSector, short nAngle, int nChannel) { spritetype* pSprite; if (pActor == nullptr) @@ -50,7 +50,7 @@ void BuildRex(DExhumedActor* pActor, int x, int y, int z, short nSector, short n pSprite = &pActor->s(); x = pSprite->x; y = pSprite->y; - z = sector[pSprite->sectnum].floorz; + z = pSprite->sector()->floorz; nAngle = pSprite->ang; ChangeActorStat(pActor, 119); @@ -65,7 +65,7 @@ void BuildRex(DExhumedActor* pActor, int x, int y, int z, short nSector, short n pSprite->xrepeat = 64; pSprite->yrepeat = 64; pSprite->picnum = 1; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->ang = nAngle; @@ -455,9 +455,4 @@ void AIRex::Tick(RunListEvent* ev) } -void FuncRex(int nObject, int nMessage, int nDamage, int nRun) -{ - AIRex ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/roach.cpp b/source/games/exhumed/src/roach.cpp index 7e195fdc0..0c4834d12 100644 --- a/source/games/exhumed/src/roach.cpp +++ b/source/games/exhumed/src/roach.cpp @@ -47,7 +47,7 @@ struct Roach }; // TODO - make nType a bool? -void BuildRoach(int nType, DExhumedActor* pActor, int x, int y, int z, short nSector, int angle) +void BuildRoach(int nType, DExhumedActor* pActor, int x, int y, int z, int nSector, int angle) { spritetype* pSprite; if (pActor == nullptr) @@ -61,7 +61,7 @@ void BuildRoach(int nType, DExhumedActor* pActor, int x, int y, int z, short nSe pSprite = &pActor->s(); x = pSprite->x; y = pSprite->y; - z = sector[pSprite->sectnum].floorz; + z = pSprite->sector()->floorz; angle = pSprite->ang; } @@ -73,7 +73,7 @@ void BuildRoach(int nType, DExhumedActor* pActor, int x, int y, int z, short nSe pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->picnum = 1; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->clipdist = 60; pSprite->ang = angle; pSprite->xrepeat = 40; @@ -391,10 +391,4 @@ void AIRoach::Tick(RunListEvent* ev) } } -void FuncRoach(int nObject, int nMessage, int nDamage, int nRun) -{ - AIRoach ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/exhumed/src/runlist.cpp b/source/games/exhumed/src/runlist.cpp index 03a3f05bf..b1b3aee80 100644 --- a/source/games/exhumed/src/runlist.cpp +++ b/source/games/exhumed/src/runlist.cpp @@ -32,13 +32,12 @@ enum }; -short nRadialSpr = -1; +DExhumedActor* pRadialActor; short nStackCount = 0; short word_966BE = 0; short ChannelList = -1; short ChannelLast = -1; -int nRadialOwner; int nDamageRadius; int nRadialDamage; short RunChain; @@ -68,12 +67,10 @@ void SerializeRunList(FSerializer& arc) if (arc.BeginObject("runlist")) { arc("data", RunData) - ("radialspr", nRadialSpr) ("stackcount", nStackCount) ("w966be", word_966BE) ("list", ChannelList) ("last", ChannelLast) - ("radialowner", nRadialOwner) ("damageradius", nDamageRadius) ("radialdamage", nRadialDamage) ("runchain", RunChain) @@ -84,46 +81,88 @@ void SerializeRunList(FSerializer& arc) } } -AiFunc aiFunctions[kFuncMax] = { - FuncElev, - FuncSwReady, - FuncSwPause, - FuncSwStepOn, - FuncSwNotOnPause, - FuncSwPressSector, - FuncSwPressWall, - FuncWallFace, - FuncSlide, - FuncAnubis, - FuncPlayer, - FuncBullet, - FuncSpider, - FuncCreatureChunk, - FuncMummy, - FuncGrenade, - FuncAnim, - FuncSnake, - FuncFish, - FuncLion, - FuncBubble, - FuncLava, - FuncLavaLimb, - FuncObject, - FuncRex, - FuncSet, - FuncQueen, - FuncQueenHead, - FuncRoach, - FuncQueenEgg, - FuncWasp, - FuncTrap, - FuncFishLimb, - FuncRa, - FuncScorp, - FuncSoul, - FuncRat, - FuncEnergyBlock, - FuncSpark, +AIElev aiElev; +AISWReady aiSwReady; +AISWPause aiSwPause; +AISWStepOn aiSwStepOn; +AISWNotOnPause aiSwNotOnPause; +AISWPressSector aiSwPressSector; +AISWPressWall aiSwPressWall; +AIWallFace aiWallFace; +AISlide aiSlide; +AIAnubis aiAnubis; +AIPlayer aiPlayer; +AIBullet aiBullet; +AISpider aiSpider; +AICreatureChunk aiCreatureChunk; +AIMummy aiMummy; +AIGrenade aiGrenade; +AIAnim aiAnim; +AISnake aiSnake; +AIFish aiFish; +AILion aiLion; +AIBubble aiBubble; +AILavaDude aiLava; +AILavaDudeLimb aiLavaLimb; +AIObject aiObject; +AIRex aiRex; +AISet aiSet; +AIQueen aiQueen; +AIQueenHead aiQueenHead; +AIRoach aiRoach; +AIQueenEgg aiQueenEgg; +AIWasp aiWasp; +AITrap aiTrap; +AIFishLimb aiFishLimb; +AIRa aiRa; +AIScorp aiScorp; +AISoul aiSoul; +AIRat aiRat; +AIEnergyBlock aiEnergyBlock; +AISpark aiSpark; + + +ExhumedAI* ais[kFuncMax] = +{ + &aiElev, + &aiSwReady, + &aiSwPause, + &aiSwStepOn, + &aiSwNotOnPause, + &aiSwPressSector, + &aiSwPressWall, + &aiWallFace, + &aiSlide, + &aiAnubis, + &aiPlayer, + &aiBullet, + &aiSpider, + &aiCreatureChunk, + &aiMummy, + &aiGrenade, + &aiAnim, + &aiSnake, + &aiFish, + &aiLion, + &aiBubble, + &aiLava, + &aiLavaLimb, + &aiObject, + &aiRex, + &aiSet, + &aiQueen, + &aiQueenHead, + &aiRoach, + &aiQueenEgg, + &aiWasp, + &aiTrap, + &aiFishLimb, + &aiRa, + &aiScorp, + &aiSoul, + &aiRat, + &aiEnergyBlock, + &aiSpark, }; @@ -179,7 +218,7 @@ void runlist_InitRun() PlayerList[i].nRun = -1; } - nRadialSpr = -1; + pRadialActor = nullptr; } void runlist_UnlinkRun(int nRun) @@ -295,24 +334,27 @@ void runlist_SubRunRec(int RunPtr) RunData[RunPtr].nAIType = -totalmoves; } -void runlist_SendMessageToRunRec(int nRun, int nObject, int nMessage, int nDamage) +void runlist_SendMessage(int nRun, int nObject, void(ExhumedAI::* func)(RunListEvent*), RunListEvent* ev) { int nFunc = RunData[nRun].nAIType >> 16; - if (nFunc < 0) { + if (nFunc < 0 || nFunc >= (int)countof(ais)) { return; } - assert(nFunc >= 0 && nFunc <= kFuncMax); - - if (nFunc > kFuncMax) { - return; + RunListEvent defev; + if (!ev) + { + defev = {}; + ev = &defev; } + ev->nObjIndex = RunData[nRun].nObjIndex; + ev->pObjActor = RunData[nRun].pObjActor; + ev->nParam = nObject; + ev->nRun = nRun; - assert(nFunc < kFuncMax); // REMOVE - // do function pointer call here. - aiFunctions[nFunc](nObject, nMessage, nDamage, nRun); + (ais[nFunc]->*func)(ev); } void runlist_ExplodeSignalRun() @@ -335,7 +377,12 @@ void runlist_ExplodeSignalRun() if (RunData[runPtr].nObjIndex >= 0 || RunData[runPtr].pObjActor) { - runlist_SendMessageToRunRec(runPtr, 0, 0xA0000, 0); + RunListEvent ev{}; + ev.nMessage = 1; + ev.nRadialDamage = nRadialDamage; + ev.nDamageRadius = nDamageRadius; + ev.pRadialActor = pRadialActor; + runlist_SendMessage(runPtr, 0, &ExhumedAI::RadialDamage, &ev); } } } @@ -360,7 +407,7 @@ int runlist_PopMoveRun() return sRunStack[nStackCount]; } -void runlist_SignalRun(int NxtPtr, int edx) +void runlist_SignalRun(int NxtPtr, int edx, void(ExhumedAI::* func)(RunListEvent*), RunListEvent* ev) { if (NxtPtr == RunChain && word_966BE != 0) { runlist_PushMoveRun(edx); @@ -387,7 +434,7 @@ void runlist_SignalRun(int NxtPtr, int edx) NxtPtr = RunData[RunPtr].next; if (RunData[RunPtr].nObjIndex >= 0 || RunData[RunPtr].pObjActor) { - runlist_SendMessageToRunRec(RunPtr, edx & 0xffff, edx & ~0xffff, 0); + runlist_SendMessage(RunPtr, edx, func, ev); } } } @@ -463,13 +510,13 @@ void runlist_ProcessChannels() if (d & 2) { sRunChannels[ChannelList].d = d ^ 2; - runlist_SignalRun(sRunChannels[ChannelList].a, ChannelList | 0x10000); + runlist_SignalRun(sRunChannels[ChannelList].a, ChannelList, &ExhumedAI::ProcessChannel); } if (d & 1) { sRunChannels[ChannelList].d ^= 1; - runlist_SignalRun(sRunChannels[ChannelList].a, 0x30000); + runlist_SignalRun(sRunChannels[ChannelList].a, 0, &ExhumedAI::Process); } if (sRunChannels[ChannelList].d) @@ -522,13 +569,13 @@ void runlist_ProcessChannels() if (d & 2) { sRunChannels[nChannel].d = d ^ 2; - runlist_SignalRun(sRunChannels[nChannel].a, ChannelList | 0x10000); + runlist_SignalRun(sRunChannels[nChannel].a, ChannelList, &ExhumedAI::ProcessChannel); } if (d & 1) { sRunChannels[nChannel].d = d ^ 1; - runlist_SignalRun(sRunChannels[nChannel].a, 0x30000); + runlist_SignalRun(sRunChannels[nChannel].a, 0, &ExhumedAI::Process); } if (sRunChannels[nChannel].d == 0) @@ -586,11 +633,12 @@ int runlist_AllocChannel(int a) void runlist_ExecObjects() { runlist_ProcessChannels(); - runlist_SignalRun(RunChain, 0x20000); + runlist_SignalRun(RunChain, 0, &ExhumedAI::Tick); } void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) { + auto sectp = §or[nSector]; int zListA[8]; int zListB[8]; @@ -616,10 +664,10 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) This function searches z-coordinates of neighboring sectors to find the closest (next) ceiling starting at the given z-coordinate (thez). */ - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].ceilingz); + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -635,10 +683,10 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 2: // Floor Doom door { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].ceilingz, sector[nextSector].floorz); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->ceilingz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -684,10 +732,10 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 5: // Permanent floor raise { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz + 1, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz + 1, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].ceilingz); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -695,10 +743,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 6: // Touchplate floor lower, single { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 400, 400, 2, sector[nextSector].floorz, sector[nSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 400, 400, 2, nextSectorP->floorz, sectp->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -706,16 +755,17 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) runlist_AddRunRec(sRunChannels[nChannel].a,nSwitch.first, nSwitch.second); - sector[nSector].floorz = sector[nextSector].floorz; + sectp->floorz = nextSectorP->floorz; return; } case 7: // Touchplate floor lower, multiple { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -731,10 +781,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 8: // Permanent floor lower { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -742,10 +793,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 9: // Switch activated lift down { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -757,10 +809,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 10: // Touchplate Floor Raise { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -785,12 +838,12 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) */ int zVal = 0; - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - if (nextSector >= 0) { - zVal = sector[nextSector].floorz; + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, -1); + if (nextSectorP != nullptr) { + zVal = nextSectorP->floorz; } - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, zVal); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -805,12 +858,12 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) */ int zVal = 0; - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - if (nextSector >= 0) { - zVal = sector[nextSector].floorz; + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, -1); + if (nextSectorP != nullptr) { + zVal = nextSectorP->floorz; } - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, zVal); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -829,12 +882,12 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) */ int zVal = 0; - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - if (nextSector >= 0) { - zVal = sector[nextSector].floorz; + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP != nullptr) { + zVal = nextSectorP->floorz; } - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, zVal); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -846,10 +899,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 15: // Sector raise/lower { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -857,7 +911,7 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 16: // Stuttering noise (floor makes noise) { - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].ceilingz, sector[nSector].floorz - 8); + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->ceilingz, sectp->floorz - 8); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -873,7 +927,7 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 17: // Reserved? { - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].ceilingz, sector[nSector].floorz - 8); + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->ceilingz, sectp->floorz - 8); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -885,15 +939,15 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 18: // Raises floor AND lowers ceiling { - int ebx = ((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz; + int ebx = ((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].floorz, ebx); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->floorz, ebx); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); - int ebx2 = (((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz) - 8; + int ebx2 = (((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz) - 8; - int nElev2 = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].ceilingz, ebx2); + int nElev2 = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->ceilingz, ebx2); runlist_AddRunRec(sRunChannels[nChannel].a, nElev2, 0); @@ -920,12 +974,12 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) */ int zVal = 0; - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - if (nextSector >= 0) { - zVal = sector[nextSector].floorz; + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP) { + zVal = nextSectorP->floorz; } - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 32767, 200, 2, sector[nSector].floorz, zVal); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 32767, 200, 2, sectp->floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -937,10 +991,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 24: // Ceiling door, channel trigger only { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].ceilingz); + + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -952,10 +1007,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 25: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -967,10 +1023,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 26: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -982,10 +1039,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 27: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -997,10 +1055,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 28: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1012,10 +1071,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 31: // Touchplate { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 0x7FFF, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 0x7FFF, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1027,10 +1087,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 32: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 0x7FFF, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 0x7FFF, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1038,10 +1099,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 33: // Ceiling Crusher { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(20, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nextSector].ceilingz, sector[nSector].floorz); + + int nElev = BuildElevC(20, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, nextSectorP->ceilingz, sectp->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1049,10 +1111,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 34: // Triggerable Ceiling Crusher(Inactive) { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(28, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nextSector].ceilingz, sector[nSector].floorz); + + int nElev = BuildElevC(28, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, nextSectorP->ceilingz, sectp->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1074,10 +1137,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 37: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1085,10 +1149,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 39: // Touchplate { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 0x7FFF, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 0x7FFF, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1147,12 +1212,12 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) */ int zVal = 0; - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, 1); - if (nextSector >= 0) { - zVal = sector[nextSector].ceilingz; + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, 1); + if (nextSectorP != nullptr) { + zVal = nextSectorP->ceilingz; } - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].ceilingz, zVal); + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->ceilingz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1160,10 +1225,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 49: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].ceilingz, sector[nextSector].ceilingz); + + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->ceilingz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1171,10 +1237,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 50: // Floor lower / raise { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 200, 2, sector[nextSector].floorz, sector[nSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 0x7FFF, 200, 2, nextSectorP->floorz, sectp->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1182,15 +1249,15 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 51: { - int edx = ((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz; + int edx = ((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].floorz, edx); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->floorz, edx); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); - int eax = (((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz) - 8; + int eax = (((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz) - 8; - nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sector[nSector].ceilingz, eax); + nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, nSpeed * 100, 2, sectp->ceilingz, eax); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1202,15 +1269,15 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 52: { - int eax = ((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz; + int eax = ((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sector[nSector].floorz); + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sectp->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); - eax = ((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz; + eax = ((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz; - nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sector[nSector].ceilingz); + nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sectp->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1226,15 +1293,15 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 53: { - int eax = ((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz; + int eax = ((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sector[nSector].floorz); + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sectp->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); - eax = ((sector[nSector].floorz - sector[nSector].ceilingz) / 2) + sector[nSector].ceilingz; + eax = ((sectp->floorz - sectp->ceilingz) / 2) + sectp->ceilingz; - nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sector[nSector].ceilingz); + nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, eax, sectp->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1246,10 +1313,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 54: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].ceilingz); + + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1261,10 +1329,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 55: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].ceilingz); + + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1276,10 +1345,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 56: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].ceilingz); + + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1287,10 +1357,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 57: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].ceilingz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->ceilingz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1311,10 +1382,10 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) nEnergyChan = nChannel; } - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].ceilingz); + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1322,10 +1393,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 59: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1341,17 +1413,17 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 61: { - zListB[0] = sector[nSector].floorz; + zListB[0] = sectp->floorz; int var_1C = 1; while (1) { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - if (nextSector < 0 || var_1C >= 8) { + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, -1); + if (nextSectorP == nullptr || var_1C >= 8) { break; } - zListB[var_1C] = sector[nextSector].floorz; + zListB[var_1C] = nextSectorP->floorz; var_1C++; } @@ -1365,17 +1437,17 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 62: { - zListA[0] = sector[nSector].floorz; + zListA[0] = sectp->floorz; int var_20 = 1; while (1) { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - if (nextSector < 0 || var_20 >= 8) { + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr || var_20 >= 8) { break; } - zListA[var_20] = sector[nextSector].floorz; + zListA[var_20] = nextSectorP->floorz; var_20++; } @@ -1396,10 +1468,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 68: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->floorz, 1, 1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, sectp->floorz, nextSectorP->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1408,10 +1481,11 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 70: case 71: { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, -1); - assert(nextSector > -1); + auto nextSectorP = nextsectorneighborzptr(nSector, sectp->ceilingz, -1, -1); + if (nextSectorP == nullptr) break; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, (int)sector[nSector].floorz, (int)sector[nextSector].ceilingz); + + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, (int)sectp->floorz, (int)nextSectorP->ceilingz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); @@ -1427,7 +1501,7 @@ void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) case 75: { - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, (int)sector[nSector].ceilingz, (int)sector[nSector].floorz); + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), nSpeed * 100, nSpeed * 100, 2, (int)sectp->ceilingz, (int)sectp->floorz); runlist_AddRunRec(sRunChannels[nChannel].a, nElev, 0); return; @@ -1560,11 +1634,12 @@ void runlist_ProcessWallTag(int nWall, short nLotag, short nHitag) } } -int runlist_CheckRadialDamage(short nSprite) +int runlist_CheckRadialDamage(DExhumedActor* pActor) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); + auto pRadialSpr = &pRadialActor->s(); - if (nSprite == nRadialSpr) { + if (pActor == pRadialActor) { return 0; } @@ -1572,17 +1647,17 @@ int runlist_CheckRadialDamage(short nSprite) return 0; } - if (pSprite->statnum >= kMaxStatus || sprite[nRadialSpr].statnum >= kMaxStatus) { + if (pSprite->statnum >= kMaxStatus || pRadialSpr->statnum >= kMaxStatus) { return 0; } - if (pSprite->statnum != 100 && nSprite == nRadialOwner) { + if (pSprite->statnum != 100 && pActor == pRadialActor->pTarget) { return 0; } - int x = (pSprite->x - sprite[nRadialSpr].x) >> 8; - int y = (pSprite->y - sprite[nRadialSpr].y) >> 8; - int z = (pSprite->z - sprite[nRadialSpr].z) >> 12; + int x = (pSprite->x - pRadialSpr->x) >> 8; + int y = (pSprite->y - pRadialSpr->y) >> 8; + int z = (pSprite->z - pRadialSpr->z) >> 12; if (abs(x) > nDamageRadius) { return 0; @@ -1617,10 +1692,10 @@ int runlist_CheckRadialDamage(short nSprite) pSprite->cstat = 0x101; if (((kStatExplodeTarget - pSprite->statnum) <= 1) || - cansee(sprite[nRadialSpr].x, - sprite[nRadialSpr].y, - sprite[nRadialSpr].z - 512, - sprite[nRadialSpr].sectnum, + cansee(pRadialSpr->x, + pRadialSpr->y, + pRadialSpr->z - 512, + pRadialSpr->sectnum, pSprite->x, pSprite->y, pSprite->z - 8192, @@ -1655,30 +1730,29 @@ int runlist_CheckRadialDamage(short nSprite) return edi; } -void runlist_RadialDamageEnemy(short nSprite, short nDamage, short nRadius) +void runlist_RadialDamageEnemy(DExhumedActor* pActor, short nDamage, short nRadius) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); if (!nRadius) { return; } - if (nRadialSpr == -1) + if (pRadialActor == nullptr) { nRadialDamage = nDamage * 4; nDamageRadius = nRadius; - nRadialSpr = nSprite; - nRadialOwner = pSprite->owner; + pRadialActor = pActor; runlist_ExplodeSignalRun(); - nRadialSpr = -1; + pRadialActor = nullptr; } } -void runlist_DamageEnemy(int nSprite, int nSprite2, short nDamage) +void runlist_DamageEnemy(DExhumedActor* pActor, DExhumedActor* pActor2, short nDamage) { - auto pSprite = &sprite[nSprite]; + auto pSprite = &pActor->s(); if (pSprite->statnum >= kMaxStatus) { return; @@ -1691,23 +1765,26 @@ void runlist_DamageEnemy(int nSprite, int nSprite2, short nDamage) short nPreCreaturesKilled = nCreaturesKilled; - runlist_SendMessageToRunRec(nRun, nSprite2, 0x80000, nDamage * 4); + RunListEvent ev{}; + ev.pOtherActor = pActor2; + ev.nDamage = nDamage * 4; + runlist_SendMessage(nRun, -1, &ExhumedAI::Damage, &ev); // is there now one less creature? (has one died) - if (nPreCreaturesKilled < nCreaturesKilled && nSprite2 > -1) + if (nPreCreaturesKilled < nCreaturesKilled && pActor2 != nullptr) { - if (sprite[nSprite2].statnum != 100) { + if (pActor2->s().statnum != 100) { return; } - short nPlayer = GetPlayerFromSprite(nSprite2); + short nPlayer = GetPlayerFromActor(pActor2); PlayerList[nPlayer].nTauntTimer--; if (PlayerList[nPlayer].nTauntTimer <= 0) { // Do a taunt - int nPlayerSprite = PlayerList[nPlayer].nSprite; - int nSector = sprite[nPlayerSprite].sectnum; + auto pPlayerActor = PlayerList[nPlayer].Actor(); + int nSector = pPlayerActor->s().sectnum; if (!(SectFlag[nSector] & kSectUnderwater)) { @@ -1717,8 +1794,7 @@ void runlist_DamageEnemy(int nSprite, int nSprite2, short nDamage) ebx = 0x6000; } - int nDopSprite = PlayerList[nPlayer].nDoppleSprite; - D3PlayFX(StaticSound[kSoundTauntStart + (RandomSize(3) % 5)], nDopSprite, ebx); + D3PlayFX(StaticSound[kSoundTauntStart + (RandomSize(3) % 5)], PlayerList[nPlayer].pDoppleSprite, ebx); } PlayerList[nPlayer].nTauntTimer = RandomSize(3) + 3; @@ -1726,65 +1802,4 @@ void runlist_DamageEnemy(int nSprite, int nSprite2, short nDamage) } } -// This is only temporary so that the event system can be refactored in smaller steps. -void runlist_DispatchEvent(ExhumedAI* ai, int nObject, int nMessage, int nDamage, int nRun) -{ - RunListEvent ev{}; - ev.nMessage = (EMessageType)(nMessage >> 16); - ev.nObjIndex = RunData[nRun].nObjIndex; - ev.pObjActor = RunData[nRun].pObjActor; - ev.nParam = nObject; - ev.nDamage = nDamage; - ev.nRun = nRun; - switch (ev.nMessage) - { - case EMessageType::ProcessChannel: - ai->ProcessChannel(&ev); - break; - - case EMessageType::Tick: - ai->Tick(&ev); - break; - - case EMessageType::Process: - ai->Process(&ev); - break; - - case EMessageType::Use: - ai->Use(&ev); - break; - - case EMessageType::TouchFloor: - ai->TouchFloor(&ev); - break; - - case EMessageType::LeaveSector: - ai->LeaveSector(&ev); - break; - - case EMessageType::EnterSector: - ai->EnterSector(&ev); - break; - - case EMessageType::Damage: - ev.pOtherActor = &exhumedActors[nObject]; - ai->Damage(&ev); - break; - - case EMessageType::Draw: - ev.pTSprite = &mytsprite[nObject]; - ai->Draw(&ev); - break; - - case EMessageType::RadialDamage: - ev.nRadialDamage = nRadialDamage; - ev.nDamageRadius = nDamageRadius; - ev.pOtherActor = nullptr; // &exhumedActors[nObject]; nObject is always 0 here, this was setting some random invalid target - ev.pRadialActor = &exhumedActors[nRadialSpr]; - ai->RadialDamage(&ev); - break; - } -} - - END_PS_NS diff --git a/source/games/exhumed/src/save.cpp b/source/games/exhumed/src/save.cpp index 1f229e6f7..91a8498cb 100644 --- a/source/games/exhumed/src/save.cpp +++ b/source/games/exhumed/src/save.cpp @@ -73,6 +73,7 @@ void GameInterface::SerializeGameState(FSerializer& arc) SerializeQueen(arc); SerializeRat(arc); + arc.EndObject(); } if (arc.isReading()) { diff --git a/source/games/exhumed/src/scorp.cpp b/source/games/exhumed/src/scorp.cpp index 49f4cef6b..939fcc0bf 100644 --- a/source/games/exhumed/src/scorp.cpp +++ b/source/games/exhumed/src/scorp.cpp @@ -38,7 +38,7 @@ static actionSeq ScorpSeq[] = { {53, 1} }; -void BuildScorp(DExhumedActor* pActor, int x, int y, int z, short nSector, short nAngle, int nChannel) +void BuildScorp(DExhumedActor* pActor, int x, int y, int z, int nSector, short nAngle, int nChannel) { spritetype* pSprite; @@ -54,7 +54,7 @@ void BuildScorp(DExhumedActor* pActor, int x, int y, int z, short nSector, short pSprite = &pActor->s(); x = pSprite->x; y = pSprite->y; - z = sector[pSprite->sectnum].floorz; + z = pSprite->sector()->floorz; nAngle = pSprite->ang; } @@ -67,7 +67,7 @@ void BuildScorp(DExhumedActor* pActor, int x, int y, int z, short nSector, short pSprite->xrepeat = 80; pSprite->yrepeat = 80; pSprite->picnum = 1; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->ang = nAngle; @@ -482,9 +482,4 @@ void AIScorp::Effect(RunListEvent* ev, DExhumedActor* pTarget, int mode) } -void FuncScorp(int nObject, int nMessage, int nDamage, int nRun) -{ - AIScorp ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/sequence.cpp b/source/games/exhumed/src/sequence.cpp index 6f42d9438..9d504aa0c 100644 --- a/source/games/exhumed/src/sequence.cpp +++ b/source/games/exhumed/src/sequence.cpp @@ -437,7 +437,7 @@ int seq_GetFrameSound(int val, int edx) return FrameSound[SeqBase[val] + edx]; } -void seq_MoveSequence(short nSprite, short nSeq, short bx) +void seq_MoveSequence(DExhumedActor* actor, short nSeq, short bx) { assert(nSeq >= 0); // TEMP @@ -446,8 +446,8 @@ void seq_MoveSequence(short nSprite, short nSeq, short bx) return; } - if (nSprite > -1) { - D3PlayFX(nSound, nSprite); + if (actor) { + D3PlayFX(nSound, actor); } else { PlayLocalSound(nSound, 0); @@ -608,7 +608,7 @@ int seq_PlotSequence(short nSprite, short edx, short nFrame, short ecx) } else { - short nSector = pTSprite->sectnum; + int nSector =pTSprite->sectnum; int nFloorZ = sector[nSector].floorz; if (nFloorZ <= PlayerList[nLocalPlayer].eyelevel + initz) { diff --git a/source/games/exhumed/src/sequence.h b/source/games/exhumed/src/sequence.h index 25aa80f05..5aa673b89 100644 --- a/source/games/exhumed/src/sequence.h +++ b/source/games/exhumed/src/sequence.h @@ -133,11 +133,7 @@ extern short FrameBase[]; void seq_LoadSequences(); int seq_GetFrameSound(int val, int edx); -void seq_MoveSequence(short nSprite, short nSeq, short bx); -inline void seq_MoveSequence(DExhumedActor* actor, short nSeq, short bx) -{ - seq_MoveSequence(actor->GetSpriteIndex(), nSeq, bx); -} +void seq_MoveSequence(DExhumedActor* actor, short nSeq, short bx); int seq_GetSeqPicnum2(short nSeq, short nFrame); int seq_GetSeqPicnum(short nSeq, short edx, short ebx); diff --git a/source/games/exhumed/src/set.cpp b/source/games/exhumed/src/set.cpp index 4641aa253..e0a4109d4 100644 --- a/source/games/exhumed/src/set.cpp +++ b/source/games/exhumed/src/set.cpp @@ -39,7 +39,7 @@ static actionSeq SetSeq[] = { {74, 1} }; -void BuildSet(DExhumedActor* pActor, int x, int y, int z, short nSector, short nAngle, int nChannel) +void BuildSet(DExhumedActor* pActor, int x, int y, int z, int nSector, short nAngle, int nChannel) { spritetype* pSprite; if (pActor == nullptr) @@ -53,7 +53,7 @@ void BuildSet(DExhumedActor* pActor, int x, int y, int z, short nSector, short n pSprite = &pActor->s(); x = pSprite->x; y = pSprite->y; - z = sector[pSprite->sectnum].floorz; + z = pSprite->sector()->floorz; nAngle = pSprite->ang; } @@ -68,7 +68,7 @@ void BuildSet(DExhumedActor* pActor, int x, int y, int z, short nSector, short n pSprite->zvel = 0; pSprite->xrepeat = 87; pSprite->yrepeat = 96; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->xoffset = 0; pSprite->yoffset = 0; pSprite->ang = nAngle; @@ -120,7 +120,7 @@ void BuildSoul(DExhumedActor* pSet) pSprite->x = pSetSprite->x; pSprite->y = pSetSprite->y; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; pSprite->z = (RandomSize(8) << 8) + 8192 + sector[nSector].ceilingz - GetActorHeight(pActor); //pSprite->hitag = nSet; @@ -173,13 +173,6 @@ void AISoul::Tick(RunListEvent* ev) } - -void FuncSoul(int nObject, int nMessage, int nDamage, int nRun) -{ - AISoul ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - void AISet::RadialDamage(RunListEvent* ev) { auto pActor = ev->pObjActor; @@ -290,7 +283,10 @@ void AISet::Tick(RunListEvent* ev) auto nMov = MoveCreature(pActor); - pushmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &pSprite->sectnum, pSprite->clipdist << 2, 5120, -5120, CLIPMASK0); + static_assert(sizeof(pSprite->sectnum) != 4); + int sectnum = pSprite->sectnum; + pushmove(&pSprite->pos, §num, pSprite->clipdist << 2, 5120, -5120, CLIPMASK0); + pSprite->sectnum = sectnum; if (pSprite->zvel > 4000) { @@ -643,9 +639,4 @@ void AISet::Tick(RunListEvent* ev) return; } -void FuncSet(int nObject, int nMessage, int nDamage, int nRun) -{ - AISet ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/snake.cpp b/source/games/exhumed/src/snake.cpp index 7e2cfce0c..b89a7ca2a 100644 --- a/source/games/exhumed/src/snake.cpp +++ b/source/games/exhumed/src/snake.cpp @@ -102,12 +102,12 @@ void ExplodeSnakeSprite(DExhumedActor* pActor, short nPlayer) } // take a copy of this, to revert after call to runlist_RadialDamageEnemy() - short nOwner = pSprite->owner; - pSprite->owner = PlayerList[nPlayer].nSprite; + auto nOwner = pActor->pTarget; + pActor->pTarget = PlayerList[nPlayer].pActor; runlist_RadialDamageEnemy(pActor, nDamage, BulletInfo[kWeaponStaff].nRadius); - pSprite->owner = nOwner; + pActor->pTarget = nOwner; BuildAnim(nullptr, 23, 0, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, 40, 4); @@ -178,9 +178,9 @@ void BuildSnake(short nPlayer, short zVal) if (hitactor && hitactor->s().statnum >= 90 && hitactor->s().statnum <= 199) { pTarget = hitactor; } - else if (sPlayerInput[nPlayer].nTarget >= 0) + else if (sPlayerInput[nPlayer].pTarget != nullptr) { - pTarget = &exhumedActors[sPlayerInput[nPlayer].nTarget]; + pTarget = sPlayerInput[nPlayer].pTarget; } short nSnake = GrabSnake(); @@ -274,7 +274,7 @@ DExhumedActor* FindSnakeEnemy(short nSnake) auto pSprite = &pActor->s(); short nAngle = pSprite->ang; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; int esi = 2048; @@ -380,7 +380,7 @@ void AISnake::Tick(RunListEvent* ev) SnakeList[nSnake].sE = (SnakeList[nSnake].sE + 64) & 0x7FF; int var_28 = (nAngle + 512) & kAngleMask; - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; int x = pSprite->x; int y = pSprite->y; @@ -423,10 +423,4 @@ void AISnake::Draw(RunListEvent* ev) ev->pTSprite->owner = -1; } - -void FuncSnake(int nObject, int nMessage, int nDamage, int nRun) -{ - AISnake ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/sound.cpp b/source/games/exhumed/src/sound.cpp index a6ddb859a..e8b951c9e 100644 --- a/source/games/exhumed/src/sound.cpp +++ b/source/games/exhumed/src/sound.cpp @@ -557,23 +557,23 @@ void GameInterface::UpdateSounds() int soundx, soundy, soundz; short soundsect; -void PlayFX2(unsigned short nSound, short nSprite, int sectf, EChanFlags chanflags, int sprflags) +void PlayFX2(unsigned short nSound, DExhumedActor* pActor, int sectf, EChanFlags chanflags, int sprflags) { if (!SoundEnabled()) return; if ((nSound&0x1ff) >= kMaxSounds || !soundEngine->isValidSoundId((nSound & 0x1ff)+1)) { - Printf("PlayFX2: Invalid sound nSound == %i, nSprite == %i\n", nSound, nSprite); + Printf("PlayFX2: Invalid sound nSound == %i\n", nSound); return; } bool fullvol = false, hiprio = false; - if (nSprite >= 0) + if (pActor) { fullvol = (sprflags & 0x2000) != 0; hiprio = (sprflags & 0x4000) != 0; - soundx = sprite[nSprite].x; - soundy = sprite[nSprite].y; - soundz = sprite[nSprite].z; + soundx = pActor->s().x; + soundy = pActor->s().y; + soundz = pActor->s().z; } int nVolume = 255; @@ -584,7 +584,7 @@ void PlayFX2(unsigned short nSound, short nSprite, int sectf, EChanFlags chanfla int prio = 0; if (forcePlay || midprio) prio = 1000; - else if (nSprite != -1 && hiprio) prio = 2000; + else if (pActor != nullptr && hiprio) prio = 2000; short v10 = (nSound&0xe00)>>9; nSound &= 0x1ff; @@ -602,16 +602,16 @@ void PlayFX2(unsigned short nSound, short nSprite, int sectf, EChanFlags chanfla { bool res = soundEngine->EnumerateChannels([=](FSoundChan* chan) { - if (chan->SourceType == SOURCE_Actor && nSprite != -1) + if (chan->SourceType == SOURCE_Actor && pActor != nullptr) { if (prio >= chan->UserData) { if (chan->SoundID == nSound + 1) { - if (!allowMultiple && &sprite[nSprite] == chan->Source) + if (!allowMultiple && &pActor->s() == chan->Source) return 1; } - else if (&sprite[nSprite] == chan->Source) + else if (&pActor->s() == chan->Source) { soundEngine->StopChannel(chan); return -1; @@ -619,7 +619,7 @@ void PlayFX2(unsigned short nSound, short nSprite, int sectf, EChanFlags chanfla } } - else if (chan->SourceType == SOURCE_Unattached && nSprite == -1) + else if (chan->SourceType == SOURCE_Unattached && pActor != nullptr) { if (chan->SoundID == nSound + 1) { @@ -633,9 +633,9 @@ void PlayFX2(unsigned short nSound, short nSprite, int sectf, EChanFlags chanfla if (res) return; } FSoundChan* chan = nullptr; - if (nSprite >= 0) + if (pActor != nullptr) { - chan = soundEngine->StartSound(SOURCE_Actor, &sprite[nSprite], nullptr, CHAN_BODY, chanflags| CHANF_OVERLAP, nSound+1, nVolume / 255.f,fullvol? 0.5f : ATTN_NORM, nullptr, (11025 + nPitch) / 11025.f); + chan = soundEngine->StartSound(SOURCE_Actor, &pActor->s(), nullptr, CHAN_BODY, chanflags| CHANF_OVERLAP, nSound+1, nVolume / 255.f,fullvol? 0.5f : ATTN_NORM, nullptr, (11025 + nPitch) / 11025.f); } else { @@ -648,7 +648,7 @@ void PlayFX2(unsigned short nSound, short nSprite, int sectf, EChanFlags chanfla } // Nuke: added nSprite >= 0 check - if (nSprite != nLocalSpr && nSprite >= 0 && (sprite[nSprite].cstat&257)) + if (pActor != PlayerList[nLocalPlayer].Actor() && pActor != nullptr && (pActor->s().cstat&257)) nCreepyTimer = kCreepyCount; } @@ -664,7 +664,7 @@ void PlayFXAtXYZ(unsigned short ax, int x, int y, int z, int nSector, EChanFlags soundy = y; soundz = z; soundsect = nSector; - PlayFX2(ax, -1, sectf, chanflags); + PlayFX2(ax, nullptr, sectf, chanflags); } //========================================================================== @@ -673,12 +673,12 @@ void PlayFXAtXYZ(unsigned short ax, int x, int y, int z, int nSector, EChanFlags // //========================================================================== -void CheckAmbience(short nSector) +void CheckAmbience(int nSector) { if (!SoundEnabled()) return; if (SectSound[nSector] != -1) { - short nSector2 = SectSoundSect[nSector]; + int nSector2 = SectSoundSect[nSector]; walltype* pWall = &wall[sector[nSector2].wallptr]; if (!soundEngine->IsSourcePlayingSomething(SOURCE_Ambient, &amb, 0)) { @@ -693,7 +693,7 @@ void CheckAmbience(short nSector) { if (nSector == nSector2) { - spritetype* pSprite = &sprite[PlayerList[0].nSprite]; + spritetype* pSprite = &PlayerList[0].Actor()->s(); amb = GetSoundPos(&pSprite->pos); } else @@ -724,7 +724,7 @@ void UpdateCreepySounds() { if ((currentLevel->gameflags & LEVEL_EX_COUNTDOWN) || nFreeze || !SoundEnabled()) return; - spritetype* pSprite = &sprite[PlayerList[nLocalPlayer].nSprite]; + spritetype* pSprite = &PlayerList[nLocalPlayer].Actor()->s(); nCreepyTimer--; if (nCreepyTimer <= 0) { @@ -771,10 +771,10 @@ void UpdateCreepySounds() // //========================================================================== -void StopSpriteSound(short nSprite) +void StopActorSound(DExhumedActor *pActor) { - if (nSprite >= 0 && nSprite < MAXSPRITES) - soundEngine->StopSound(SOURCE_Actor, &sprite[nSprite], -1); + if (pActor) + soundEngine->StopSound(SOURCE_Actor, &pActor->s(), -1); } void StopAllSounds(void) diff --git a/source/games/exhumed/src/sound.h b/source/games/exhumed/src/sound.h index e1121019d..757852aa6 100644 --- a/source/games/exhumed/src/sound.h +++ b/source/games/exhumed/src/sound.h @@ -129,29 +129,17 @@ void PlayLocalSound(short nSound, short val, bool unattached = false, EChanFlags int LoadSound(const char* sound); void BendAmbientSound(); -void CheckAmbience(short nSector); +void CheckAmbience(int nSector); -void PlayFX2(unsigned short nSound, short nSprite, int sectf = 0, EChanFlags chanflags = CHANF_NONE, int sprflags = 0); -inline void PlayFX2(unsigned short nSound, DExhumedActor* actor, int sectf = 0, EChanFlags chanflags = CHANF_NONE, int sprflags = 0) -{ - PlayFX2(nSound, actor->GetSpriteIndex(), sectf, chanflags, sprflags); -} +void PlayFX2(unsigned short nSound, DExhumedActor* nSprite, int sectf = 0, EChanFlags chanflags = CHANF_NONE, int sprflags = 0); void PlayFXAtXYZ(unsigned short nSound, int x, int y, int z, int nSector, EChanFlags chanflags = CHANF_NONE, int sectf = 0); -inline void D3PlayFX(unsigned short nSound, short nSprite, short flags = 0) -{ - PlayFX2(nSound, nSprite, 0, CHANF_NONE, flags); -} inline void D3PlayFX(unsigned short nSound, DExhumedActor* actor, short flags = 0) { - PlayFX2(nSound, actor->GetSpriteIndex(), 0, CHANF_NONE, flags); + PlayFX2(nSound, actor, 0, CHANF_NONE, flags); } -void StopSpriteSound(short nSprite); -inline void StopActorSound(DExhumedActor* actor) -{ - if (actor) StopSpriteSound(actor->GetSpriteIndex()); -} +void StopActorSound(DExhumedActor* actor); void StartSwirlies(); void UpdateSwirlies(); diff --git a/source/games/exhumed/src/spider.cpp b/source/games/exhumed/src/spider.cpp index 5c26bc773..26e4b4921 100644 --- a/source/games/exhumed/src/spider.cpp +++ b/source/games/exhumed/src/spider.cpp @@ -36,7 +36,7 @@ static actionSeq SpiderSeq[] = { }; -DExhumedActor* BuildSpider(DExhumedActor* spp, int x, int y, int z, short nSector, int nAngle) +DExhumedActor* BuildSpider(DExhumedActor* spp, int x, int y, int z, int nSector, int nAngle) { spritetype* sp; if (spp == nullptr) @@ -51,7 +51,7 @@ DExhumedActor* BuildSpider(DExhumedActor* spp, int x, int y, int z, short nSecto x = sp->x; y = sp->y; - z = sector[sp->sectnum].floorz; + z = sp->sector()->floorz; nAngle = sp->ang; } @@ -66,7 +66,7 @@ DExhumedActor* BuildSpider(DExhumedActor* spp, int x, int y, int z, short nSecto sp->zvel = 0; sp->xrepeat = 40; sp->yrepeat = 40; - sp->pal = sector[sp->sectnum].ceilingpal; + sp->pal = sp->sector()->ceilingpal; sp->xoffset = 0; sp->yoffset = 0; sp->ang = nAngle; @@ -106,7 +106,7 @@ void AISpider::Tick(RunListEvent* ev) { if (sp->cstat & 8) { - sp->z = sector[sp->sectnum].ceilingz + GetActorHeight(spp); + sp->z = sp->sector()->ceilingz + GetActorHeight(spp); } else { @@ -178,7 +178,7 @@ void AISpider::Tick(RunListEvent* ev) case 3: { case_3: - short nSector = sp->sectnum; + int nSector =sp->sectnum; if (sp->cstat & 8) { @@ -288,14 +288,13 @@ void AISpider::Tick(RunListEvent* ev) if (nMov.type == kHitNone && nMov.exbits == 0) return; - Collision HiHit(hihit); // fixme if (nMov.exbits & kHitAux1 && sp->zvel < 0 - && HiHit.type != kHitSprite - && !((sector[sp->sectnum].ceilingstat) & 1)) + && hiHit.type != kHitSprite + && !((sp->sector()->ceilingstat) & 1)) { sp->cstat |= 8; - sp->z = GetActorHeight(spp) + sector[sp->sectnum].ceilingz; + sp->z = GetActorHeight(spp) + sp->sector()->ceilingz; sp->zvel = 0; spp->nAction = 1; @@ -409,9 +408,4 @@ void AISpider::Damage(RunListEvent* ev) } } -void FuncSpider(int nObject, int nMessage, int nDamage, int nRun) -{ - AISpider ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/status.cpp b/source/games/exhumed/src/status.cpp index 8305c74a8..44bfe6858 100644 --- a/source/games/exhumed/src/status.cpp +++ b/source/games/exhumed/src/status.cpp @@ -102,7 +102,7 @@ DEFINE_ACTION_FUNCTION(_Exhumed, MoveStatusSequence) PARAM_PROLOGUE; PARAM_INT(s1); PARAM_INT(s2); - seq_MoveSequence(-1, nStatusSeqOffset + s1, s2); + seq_MoveSequence(nullptr, nStatusSeqOffset + s1, s2); ACTION_RETURN_INT(SeqSize[nStatusSeqOffset + s1]); } diff --git a/source/games/exhumed/src/switch.cpp b/source/games/exhumed/src/switch.cpp index 0a3f8ecaa..f76e6830b 100644 --- a/source/games/exhumed/src/switch.cpp +++ b/source/games/exhumed/src/switch.cpp @@ -42,9 +42,9 @@ struct Switch short nChannel; short nLink; short nRunPtr; - short nSector; + int nSector; short nRun2; - short nWall; + int nWall; short nRun3; uint16_t nKeyMask; }; @@ -150,12 +150,6 @@ void AISWReady::Process(RunListEvent* ev) } } -void FuncSwReady(int nObject, int nMessage, int, int nRun) -{ - AISWReady ai; - runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun); -} - std::pair BuildSwPause(int nChannel, int nLink, int ebx) { for (int i = kMaxSwitches - 1; i >= SwitchCount; i--) @@ -239,12 +233,6 @@ void AISWPause::Process(RunListEvent* ev) SwitchData[nSwitch].nWaitTimer = eax; } -void FuncSwPause(int nObject, int nMessage, int, int nRun) -{ - AISWPause ai; - runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun); -} - std::pair BuildSwStepOn(int nChannel, int nLink, int nSector) { if (SwitchCount <= 0 || nLink < 0 || nSector < 0) @@ -267,7 +255,7 @@ void AISWStepOn::ProcessChannel(RunListEvent* ev) short nLink = SwitchData[nSwitch].nLink; short nChannel = SwitchData[nSwitch].nChannel; - short nSector = SwitchData[nSwitch].nSector; + int nSector =SwitchData[nSwitch].nSector; assert(sRunChannels[nChannel].c < 8); @@ -292,7 +280,7 @@ void AISWStepOn::TouchFloor(RunListEvent* ev) short nLink = SwitchData[nSwitch].nLink; short nChannel = SwitchData[nSwitch].nChannel; - short nSector = SwitchData[nSwitch].nSector; + int nSector =SwitchData[nSwitch].nSector; assert(sRunChannels[nChannel].c < 8); @@ -300,7 +288,7 @@ void AISWStepOn::TouchFloor(RunListEvent* ev) if (var_14 != sRunChannels[nChannel].c) { - short nWall = sector[nSector].wallptr; + int nWall = sector[nSector].wallptr; PlayFXAtXYZ(StaticSound[nSwitchSound], wall[nWall].x, wall[nWall].y, sector[nSector].floorz, nSector); assert(sRunChannels[nChannel].c < 8); @@ -309,12 +297,6 @@ void AISWStepOn::TouchFloor(RunListEvent* ev) } } -void FuncSwStepOn(int nObject, int nMessage, int, int nRun) -{ - AISWStepOn ai; - runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun); -} - std::pair BuildSwNotOnPause(int nChannel, int nLink, int nSector, int ecx) { if (SwitchCount <= 0 || nLink < 0 || nSector < 0) @@ -385,7 +367,7 @@ void AISWNotOnPause::Process(RunListEvent* ev) { SwitchData[nSwitch].nRunPtr = runlist_AddRunRec(NewRun, &RunData[ev->nRun]); - short nSector = SwitchData[nSwitch].nSector; + int nSector =SwitchData[nSwitch].nSector; SwitchData[nSwitch].nWaitTimer = SwitchData[nSwitch].nWait; SwitchData[nSwitch].nRun2 = runlist_AddRunRec(sector[nSector].lotag - 1, &RunData[ev->nRun]); @@ -401,12 +383,6 @@ void AISWNotOnPause::TouchFloor(RunListEvent* ev) return; } -void FuncSwNotOnPause(int nObject, int nMessage, int, int nRun) -{ - AISWNotOnPause ai; - runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun); -} - std::pair BuildSwPressSector(int nChannel, int nLink, int nSector, int keyMask) { if (SwitchCount <= 0 || nLink < 0 || nSector < 0) @@ -443,7 +419,7 @@ void AISWPressSector::ProcessChannel(RunListEvent* ev) return; } - short nSector = SwitchData[nSwitch].nSector; + int nSector =SwitchData[nSwitch].nSector; SwitchData[nSwitch].nRun2 = runlist_AddRunRec(sector[nSector].lotag - 1, &RunData[ev->nRun]); } @@ -465,8 +441,8 @@ void AISWPressSector::Use(RunListEvent* ev) { if (SwitchData[nSwitch].nKeyMask) { - short nSprite = PlayerList[nPlayer].nSprite; - PlayFXAtXYZ(StaticSound[nSwitchSound], sprite[nSprite].x, sprite[nSprite].y, 0, sprite[nSprite].sectnum, CHANF_LISTENERZ); + auto pSprite = &PlayerList[nPlayer].Actor()->s(); + PlayFXAtXYZ(StaticSound[nSwitchSound], pSprite->x, pSprite->y, 0, pSprite->sectnum, CHANF_LISTENERZ); StatusMessage(300, "YOU NEED THE KEY FOR THIS DOOR"); } @@ -474,13 +450,7 @@ void AISWPressSector::Use(RunListEvent* ev) } -void FuncSwPressSector(int nObject, int nMessage, int, int nRun) -{ - AISWPressSector ai; - runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun); -} - -std::pair BuildSwPressWall(short nChannel, short nLink, short nWall) +std::pair BuildSwPressWall(short nChannel, short nLink, int nWall) { if (SwitchCount <= 0 || nLink < 0 || nWall < 0) { I_Error("Too many switches!\n"); @@ -512,7 +482,7 @@ void AISWPressWall::Process(RunListEvent* ev) if (LinkMap[nLink].v[sRunChannels[nChannel].c] >= 0) { - short nWall = SwitchData[nSwitch].nWall; + int nWall = SwitchData[nSwitch].nWall; SwitchData[nSwitch].nRun3 = runlist_AddRunRec(wall[nWall].lotag - 1, &RunData[ev->nRun]); } } @@ -535,15 +505,10 @@ void AISWPressWall::Use(RunListEvent* ev) SwitchData[nSwitch].nRun3 = -1; } - short nWall = SwitchData[nSwitch].nWall; - short nSector = SwitchData[nSwitch].nSector; // CHECKME - where is this set?? + int nWall = SwitchData[nSwitch].nWall; + int nSector =SwitchData[nSwitch].nSector; // CHECKME - where is this set?? PlayFXAtXYZ(StaticSound[nSwitchSound], wall[nWall].x, wall[nWall].y, 0, nSector, CHANF_LISTENERZ); } -void FuncSwPressWall(int nObject, int nMessage, int, int nRun) -{ - AISWPressWall ai; - runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun); -} END_PS_NS diff --git a/source/games/exhumed/src/view.cpp b/source/games/exhumed/src/view.cpp index 3a723c968..da94add74 100644 --- a/source/games/exhumed/src/view.cpp +++ b/source/games/exhumed/src/view.cpp @@ -87,16 +87,16 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y } } - short nPlayerSprite = PlayerList[nLocalPlayer].nSprite; + auto pPlayerActor = PlayerList[nLocalPlayer].Actor(); int var_38 = 20; int var_2C = 30000; - spritetype *pPlayerSprite = &sprite[nPlayerSprite]; + spritetype *pPlayerSprite = &pPlayerActor->s(); - besttarget = -1; + bestTarget = nullptr; - short nSector = pPlayerSprite->sectnum; + int nSector =pPlayerSprite->sectnum; int nAngle = (2048 - pPlayerSprite->ang) & kAngleMask; @@ -107,7 +107,8 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y for (nTSprite = spritesortcnt-1, pTSprite = &tsprite[nTSprite]; nTSprite >= 0; nTSprite--, pTSprite--) { int nSprite = pTSprite->owner; - spritetype *pSprite = &sprite[nSprite]; + auto pActor = &exhumedActors[nSprite]; + spritetype *pSprite = &pActor->s(); if (pTSprite->sectnum >= 0) { @@ -129,9 +130,11 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y if (pSprite->statnum > 0) { - runlist_SignalRun(pSprite->lotag - 1, nTSprite | 0x90000); + RunListEvent ev{}; + ev.pTSprite = pTSprite; + runlist_SignalRun(pSprite->lotag - 1, nTSprite, &ExhumedAI::Draw, &ev); - if ((pSprite->statnum < 150) && (pSprite->cstat & 0x101) && (nSprite != nPlayerSprite)) + if ((pSprite->statnum < 150) && (pSprite->cstat & 0x101) && (pActor != pPlayerActor)) { int xval = pSprite->x - x; int yval = pSprite->y - y; @@ -151,7 +154,7 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y edx = (abs(edx) * 32) / ebx; if (ebx < 1000 && ebx < var_2C && edx < 10) { - besttarget = nSprite; + bestTarget = pActor; var_38 = edx; var_2C = ebx; } @@ -162,21 +165,21 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y { var_38 = edx; var_2C = ebx; - besttarget = nSprite; + bestTarget = pActor; } } } } } - if (besttarget != -1) + if (bestTarget != nullptr) { - spritetype *pTarget = &sprite[besttarget]; + spritetype *pTarget = &bestTarget->s(); nCreepyTimer = kCreepyCount; - if (!cansee(x, y, z, nSector, pTarget->x, pTarget->y, pTarget->z - GetSpriteHeight(besttarget), pTarget->sectnum)) + if (!cansee(x, y, z, nSector, pTarget->x, pTarget->y, pTarget->z - GetActorHeight(bestTarget), pTarget->sectnum)) { - besttarget = -1; + bestTarget = nullptr; } } @@ -200,7 +203,7 @@ void DrawView(double smoothRatio, bool sceneonly) int playerX; int playerY; int playerZ; - short nSector; + int nSector; binangle nAngle, rotscrnang; fixedhoriz pan; @@ -211,10 +214,11 @@ void DrawView(double smoothRatio, bool sceneonly) DoInterpolations(smoothRatio / 65536.); pm_smoothratio = (int)smoothRatio; - int nPlayerSprite = PlayerList[nLocalPlayer].nSprite; - auto pPlayerSprite = &sprite[nPlayerSprite]; + auto pPlayerActor = PlayerList[nLocalPlayer].Actor(); + auto pPlayerSprite = &pPlayerActor->s(); int nPlayerOldCstat = pPlayerSprite->cstat; - int nDoppleOldCstat = sprite[PlayerList[nLocalPlayer].nDoppleSprite].cstat; + auto pDop = &PlayerList[nLocalPlayer].pDoppleSprite->s(); + int nDoppleOldCstat = pDop->cstat; if (nSnakeCam >= 0 && !sceneonly) { @@ -244,10 +248,9 @@ void DrawView(double smoothRatio, bool sceneonly) } else { - auto psp = &sprite[nPlayerSprite]; - playerX = psp->interpolatedx(smoothRatio); - playerY = psp->interpolatedy(smoothRatio); - playerZ = psp->interpolatedz(smoothRatio) + interpolatedvalue(PlayerList[nLocalPlayer].oeyelevel, PlayerList[nLocalPlayer].eyelevel, smoothRatio); + playerX = pPlayerSprite->interpolatedx(smoothRatio); + playerY = pPlayerSprite->interpolatedy(smoothRatio); + playerZ = pPlayerSprite->interpolatedz(smoothRatio) + interpolatedvalue(PlayerList[nLocalPlayer].oeyelevel, PlayerList[nLocalPlayer].eyelevel, smoothRatio); nSector = PlayerList[nLocalPlayer].nPlayerViewSect; updatesector(playerX, playerY, &nSector); @@ -268,12 +271,12 @@ void DrawView(double smoothRatio, bool sceneonly) if (!bCamera) { pPlayerSprite->cstat |= CSTAT_SPRITE_INVISIBLE; - sprite[PlayerList[nLocalPlayer].nDoppleSprite].cstat |= CSTAT_SPRITE_INVISIBLE; + pDop->cstat |= CSTAT_SPRITE_INVISIBLE; } else { pPlayerSprite->cstat |= CSTAT_SPRITE_TRANSLUCENT; - sprite[PlayerList[nLocalPlayer].nDoppleSprite].cstat |= CSTAT_SPRITE_INVISIBLE; + pDop->cstat |= CSTAT_SPRITE_INVISIBLE; } pan = q16horiz(clamp(pan.asq16(), gi->playerHorizMin(), gi->playerHorizMax())); } @@ -288,7 +291,7 @@ void DrawView(double smoothRatio, bool sceneonly) else { viewz = playerZ + nQuake[nLocalPlayer]; - int floorZ = sector[pPlayerSprite->sectnum].floorz; + int floorZ = pPlayerSprite->sector()->floorz; if (viewz > floorZ) viewz = floorZ; @@ -298,10 +301,10 @@ void DrawView(double smoothRatio, bool sceneonly) if (bCamera) { viewz -= 2560; - if (!calcChaseCamPos(&playerX, &playerY, &viewz, &sprite[nPlayerSprite], &nSector, nAngle, pan, smoothRatio)) + if (!calcChaseCamPos(&playerX, &playerY, &viewz, pPlayerSprite, &nSector, nAngle, pan, smoothRatio)) { viewz += 2560; - calcChaseCamPos(&playerX, &playerY, &viewz, &sprite[nPlayerSprite], &nSector, nAngle, pan, smoothRatio); + calcChaseCamPos(&playerX, &playerY, &viewz, pPlayerSprite, &nSector, nAngle, pan, smoothRatio); } } } @@ -334,9 +337,10 @@ void DrawView(double smoothRatio, bool sceneonly) if (nFreeze != 3) { - static uint8_t sectorFloorPal[MAXSECTORS]; - static uint8_t sectorCeilingPal[MAXSECTORS]; - static uint8_t wallPal[MAXWALLS]; + TArray paldata(numsectors * 2 + numwalls, true); + uint8_t* sectorFloorPal = &paldata[0]; + uint8_t* sectorCeilingPal = &paldata[numsectors]; + uint8_t* wallPal = &paldata[2*numsectors]; int const viewingRange = viewingrange; int const vr = xs_CRoundToInt(65536. * tan(r_fov * (pi::pi() / 360.))); @@ -363,7 +367,7 @@ void DrawView(double smoothRatio, bool sceneonly) if (!testnewrenderer) { renderSetRollAngle((float)rotscrnang.asbuildf()); - renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), nSector); + renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), nSector, false); analyzesprites(pm_tsprite, pm_spritesortcnt, nCamerax, nCameray, viewz, smoothRatio); renderDrawMasks(); } @@ -454,7 +458,7 @@ void DrawView(double smoothRatio, bool sceneonly) } pPlayerSprite->cstat = nPlayerOldCstat; - sprite[PlayerList[nLocalPlayer].nDoppleSprite].cstat = nDoppleOldCstat; + pDop->cstat = nDoppleOldCstat; RestoreInterpolations(); flash = 0; @@ -482,20 +486,23 @@ void Clip() void SerializeView(FSerializer& arc) { - arc("camerax", nCamerax) - ("cameray", nCameray) - ("cameraz", nCameraz) - ("touchfloor", bTouchFloor) - ("chunktotal", nChunkTotal) - ("cameraa", nCameraa) - ("camerapan", nCamerapan) - ("camera", bCamera) - ("viewz", viewz) - ("enemy", pEnemy) - ("enemypal", nEnemyPal) - .Array("vertpan", dVertPan, countof(dVertPan)) - .Array("quake", nQuake, countof(nQuake)) - .EndObject(); + if (arc.BeginObject("view")) + { + arc("camerax", nCamerax) + ("cameray", nCameray) + ("cameraz", nCameraz) + ("touchfloor", bTouchFloor) + ("chunktotal", nChunkTotal) + ("cameraa", nCameraa) + ("camerapan", nCamerapan) + ("camera", bCamera) + ("viewz", viewz) + ("enemy", pEnemy) + ("enemypal", nEnemyPal) + .Array("vertpan", dVertPan, countof(dVertPan)) + .Array("quake", nQuake, countof(nQuake)) + .EndObject(); + } } END_PS_NS diff --git a/source/games/exhumed/src/view.h b/source/games/exhumed/src/view.h index 255169453..934ad8db7 100644 --- a/source/games/exhumed/src/view.h +++ b/source/games/exhumed/src/view.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS extern short bSubTitles; -extern short besttarget; +extern DExhumedActor* bestTarget; extern bool bCamera; void DrawStatusBar(); diff --git a/source/games/exhumed/src/wasp.cpp b/source/games/exhumed/src/wasp.cpp index b4be53f4d..fd4ac5164 100644 --- a/source/games/exhumed/src/wasp.cpp +++ b/source/games/exhumed/src/wasp.cpp @@ -40,7 +40,7 @@ void SetWaspVel(spritetype* pSprite) pSprite->yvel = bsin(pSprite->ang); } -DExhumedActor* BuildWasp(DExhumedActor* pActor, int x, int y, int z, short nSector, short nAngle, bool bEggWasp) +DExhumedActor* BuildWasp(DExhumedActor* pActor, int x, int y, int z, int nSector, short nAngle, bool bEggWasp) { spritetype* pSprite; if (pActor == nullptr) @@ -61,7 +61,7 @@ DExhumedActor* BuildWasp(DExhumedActor* pActor, int x, int y, int z, short nSect pSprite->shade = -12; pSprite->cstat = 0x101; - pSprite->pal = sector[pSprite->sectnum].ceilingpal; + pSprite->pal = pSprite->sector()->ceilingpal; pSprite->clipdist = 70; if (bEggWasp) @@ -339,7 +339,7 @@ void AIWasp::Tick(RunListEvent* ev) } case 5: { - short nSector = pSprite->sectnum; + int nSector =pSprite->sectnum; pSprite->z += pSprite->zvel; @@ -364,10 +364,4 @@ void AIWasp::Tick(RunListEvent* ev) } } -void FuncWasp(int nObject, int nMessage, int nDamage, int nRun) -{ - AIWasp ai; - runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); -} - END_PS_NS diff --git a/source/games/sw/src/_polymost.cpp b/source/games/sw/src/_polymost.cpp index b838b1aeb..235847702 100644 --- a/source/games/sw/src/_polymost.cpp +++ b/source/games/sw/src/_polymost.cpp @@ -11,10 +11,10 @@ ViewSectorInScene(short cursectnum, short level) SPRITEp sp; short match; - StatIterator it(STAT_FAF); - while ((i = it.NextIndex()) >= 0) + SWStatIterator it(STAT_FAF); + while (auto actor = it.Next()) { - sp = &sprite[i]; + sp = &actor->s(); if (sp->hitag == level) { @@ -57,7 +57,7 @@ DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, shor if (tsectnum < 0) return; - renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, tsectnum); + renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, tsectnum, false); // reset Z's for (i = 0; i < save.zcount; i++) @@ -82,7 +82,7 @@ DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, shor if (tsectnum < 0) return; - renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, tsectnum); + renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, tsectnum, false); // reset Z's for (i = 0; i < save.zcount; i++) @@ -102,17 +102,16 @@ DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, shor void FAF_DrawRooms(int x, int y, int z, fixed_t q16ang, fixed_t q16horiz, short sectnum) { - int i; - StatIterator it(STAT_CEILING_FLOOR_PIC_OVERRIDE); - while ((i = it.NextIndex()) >= 0) + SWStatIterator it(STAT_CEILING_FLOOR_PIC_OVERRIDE); + while (auto actor = it.Next()) { - auto sp = &sprite[i]; + auto sp = &actor->s(); if (SP_TAG3(sp) == 0) { // back up ceilingpicnum and ceilingstat SP_TAG5(sp) = sector[sp->sectnum].ceilingpicnum; sector[sp->sectnum].ceilingpicnum = SP_TAG2(sp); - SP_TAG4(sp) = sector[sprite[i].sectnum].ceilingstat; + SP_TAG4(sp) = sector[sp->sectnum].ceilingstat; //SET(sp->sectnum].ceilingstat, ((int)SP_TAG7(sp))<<7); SET(sector[sp->sectnum].ceilingstat, SP_TAG6(sp)); RESET(sector[sp->sectnum].ceilingstat, CEILING_STAT_PLAX); @@ -128,12 +127,12 @@ void FAF_DrawRooms(int x, int y, int z, fixed_t q16ang, fixed_t q16horiz, short } } - renderDrawRoomsQ16(x,y,z,q16ang,q16horiz,sectnum); + renderDrawRoomsQ16(x,y,z,q16ang,q16horiz,sectnum, false); it.Reset(STAT_CEILING_FLOOR_PIC_OVERRIDE); - while ((i = it.NextIndex()) >= 0) + while (auto actor = it.Next()) { - auto sp = &sprite[i]; + auto sp = &actor->s(); // manually set gotpic if (gotsector[sp->sectnum]) { @@ -252,8 +251,6 @@ void JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, fixed_t tpq16ang, fixed sp = &sprite[mirror[cnt].camera]; - ASSERT(sp); - // Calculate the angle of the mirror wall w = mirror[cnt].mirrorwall; @@ -299,7 +296,7 @@ void JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, fixed_t tpq16ang, fixed if (mirror[cnt].campic != -1) tileDelete(mirror[cnt].campic); - renderDrawRoomsQ16(dx, dy, dz, tpq16ang, tpq16horiz, sp->sectnum + MAXSECTORS); + renderDrawRoomsQ16(dx, dy, dz, tpq16ang, tpq16horiz, sp->sectnum, true); analyzesprites(pm_tsprite, pm_spritesortcnt, dx, dy, dz, false); renderDrawMasks(); } @@ -316,7 +313,7 @@ void JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, fixed_t tpq16ang, fixed renderPrepareMirror(tx, ty, tz, tpq16ang, tpq16horiz, mirror[cnt].mirrorwall, /*mirror[cnt].mirrorsector,*/ &tposx, &tposy, &tang); - renderDrawRoomsQ16(tposx, tposy, tz, (tang), tpq16horiz, mirror[cnt].mirrorsector + MAXSECTORS); + renderDrawRoomsQ16(tposx, tposy, tz, (tang), tpq16horiz, mirror[cnt].mirrorsector, true); analyzesprites(pm_tsprite, pm_spritesortcnt, tposx, tposy, tz, tang >> 16); renderDrawMasks(); diff --git a/source/games/sw/src/actor.cpp b/source/games/sw/src/actor.cpp index 2c2eaf3e9..124b908c5 100644 --- a/source/games/sw/src/actor.cpp +++ b/source/games/sw/src/actor.cpp @@ -41,6 +41,8 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS +DSWActor swActors[MAXSPRITES]; + extern int jump_grav; int SpawnBlood(short SpriteNum, short Weapon, short hit_ang, int hit_x, int hit_y, int hit_z); @@ -53,14 +55,13 @@ extern STATE s_NinjaDieSlicedHack[]; extern STATEp sg_NinjaGrabThroat[]; -int DoActorStopFall(short SpriteNum); +int DoActorStopFall(DSWActor* actor); -int -DoScaleSprite(short SpriteNum) +int DoScaleSprite(DSWActor* actor) { - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); + auto u = actor->u(); + auto sp = &actor->s(); int scale_value; if (u->scale_speed) @@ -92,6 +93,7 @@ DoScaleSprite(short SpriteNum) int DoActorDie(short SpriteNum, short weapon) { + auto actor = &swActors[SpriteNum]; USERp u = User[SpriteNum].Data(); SPRITEp sp = &sprite[SpriteNum]; @@ -168,7 +170,7 @@ DoActorDie(short SpriteNum, short weapon) u->ActorActionFunc = nullptr; sp->xvel = 200 + RandomRange(200); u->jump_speed = -200 - RandomRange(250); - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); sprite[SpriteNum].ang = sprite[weapon].ang; } } @@ -180,7 +182,7 @@ DoActorDie(short SpriteNum, short weapon) ChangeState(SpriteNum, u->StateEnd); sp->xvel = 0; u->jump_speed = 0; - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); } u->RotNum = 0; @@ -212,13 +214,13 @@ DoActorDie(short SpriteNum, short weapon) { sp->xvel <<= 1; u->jump_speed = -100 - RandomRange(250); - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); } else { sp->xvel = 0; u->jump_speed = -10 - RandomRange(25); - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); } u->ActorActionFunc = nullptr; // Get angle to player @@ -242,7 +244,7 @@ DoActorDie(short SpriteNum, short weapon) sp->xvel = 100 + RandomRange(200); u->jump_speed = -100 - RandomRange(250); } - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); u->ActorActionFunc = nullptr; // Get angle to player sp->ang = NORM_ANGLE(getangle(u->tgt_sp->x - sp->x, u->tgt_sp->y - sp->y) + 1024); @@ -271,7 +273,7 @@ DoActorDie(short SpriteNum, short weapon) u->ActorActionFunc = nullptr; sp->xvel = 300 + RandomRange(400); u->jump_speed = -300 - RandomRange(350); - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); sprite[SpriteNum].ang = sprite[weapon].ang; break; } @@ -326,10 +328,11 @@ DoDebrisCurrent(SPRITEp sp) } int -DoActorSectorDamage(short SpriteNum) +DoActorSectorDamage(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SECT_USERp sectu = SectUser[sp->sectnum].Data(); SECTORp sectp = §or[sp->sectnum]; @@ -408,10 +411,11 @@ move_debris(short SpriteNum, int xchange, int ychange, int zchange) // current move with the current. int -DoActorDebris(short SpriteNum) +DoActorDebris(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SECTORp sectp = §or[sp->sectnum]; int nx, ny; @@ -472,10 +476,11 @@ DoActorDebris(short SpriteNum) int -DoFireFly(short SpriteNum) +DoFireFly(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx, ny; nx = 4 * ACTORMOVETICS * bcos(sp->ang) >> 14; @@ -627,7 +632,7 @@ DoActorBeginSlide(int SpriteNum, short ang, short vel, short dec) u->slide_vel = vel; u->slide_dec = dec; - //DoActorSlide(SpriteNum); + //DoActorSlide(actor); return 0; } @@ -636,9 +641,10 @@ DoActorBeginSlide(int SpriteNum, short ang, short vel, short dec) // Has its own set of variables int -DoActorSlide(short SpriteNum) +DoActorSlide(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; int nx, ny; nx = MulScale(u->slide_vel, bcos(u->slide_ang), 14); @@ -663,9 +669,10 @@ DoActorSlide(short SpriteNum) // !AIC - Actor jumping and falling int -DoActorBeginJump(short SpriteNum) +DoActorBeginJump(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SET(u->Flags, SPR_JUMPING); RESET(u->Flags, SPR_FALLING); @@ -687,15 +694,16 @@ DoActorBeginJump(short SpriteNum) //DO NOT CALL DoActorJump! DoActorStopFall can cause an infinite loop and //stack overflow if it is called. - //DoActorJump(SpriteNum); + //DoActorJump(actor); return 0; } int -DoActorJump(short SpriteNum) +DoActorJump(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int jump_adj; @@ -711,7 +719,7 @@ DoActorJump(short SpriteNum) MONO_PRINT(ds); // Start falling - DoActorBeginFall(SpriteNum); + DoActorBeginFall(actor); return 0; } @@ -731,7 +739,7 @@ DoActorJump(short SpriteNum) MONO_PRINT(ds); // Change sprites state to falling - DoActorBeginFall(SpriteNum); + DoActorBeginFall(actor); } return 0; @@ -739,10 +747,9 @@ DoActorJump(short SpriteNum) int -DoActorBeginFall(short SpriteNum) +DoActorBeginFall(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - + USER* u = actor->u(); SET(u->Flags, SPR_FALLING); RESET(u->Flags, SPR_JUMPING); @@ -753,28 +760,28 @@ DoActorBeginFall(short SpriteNum) { if (TEST(u->Flags, SPR_DEAD)) { - NewStateGroup(SpriteNum, u->ActorActionSet->DeathFall); + NewStateGroup(u, u->ActorActionSet->DeathFall); } else - NewStateGroup(SpriteNum, u->ActorActionSet->Fall); + NewStateGroup(u, u->ActorActionSet->Fall); if (u->StateFallOverride) { - NewStateGroup(SpriteNum, u->StateFallOverride); + NewStateGroup(u, u->StateFallOverride); } } - DoActorFall(SpriteNum); + DoActorFall(actor); return 0; } int -DoActorFall(short SpriteNum) +DoActorFall(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; + USER* u = actor->u(); + SPRITEp sp = u->s(); // adjust jump speed by gravity u->jump_speed += u->jump_grav * ACTORMOVETICS; @@ -785,16 +792,17 @@ DoActorFall(short SpriteNum) // Stick like glue when you hit the ground if (sp->z > u->loz) { - DoActorStopFall(SpriteNum); + DoActorStopFall(actor); } return 0; } int -DoActorStopFall(short SpriteNum) +DoActorStopFall(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; sp->z = u->loz; @@ -813,7 +821,7 @@ DoActorStopFall(short SpriteNum) //DSPRINTF(ds,"StopFall: sp_num %d, sp->picnum %d, lo_num %d, lo_sp->picnum %d",SpriteNum, sp->picnum, u->lo_sp - sprite, u->lo_sp->picnum); MONO_PRINT(ds); - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); return 0; } @@ -843,20 +851,20 @@ DoActorStopFall(short SpriteNum) } int -DoActorDeathMove(short SpriteNum) +DoActorDeathMove(DSWActor* actor) { - ANIMATOR DoFindGround; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - USERp u = User[SpriteNum].Data(); SPRITEp sp = User[SpriteNum]->SpriteP; int nx, ny; if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else - DoActorFall(SpriteNum); + DoActorFall(actor); } nx = MulScale(sp->xvel, bcos(sp->ang), 14); @@ -995,26 +1003,10 @@ DoFall(short SpriteNum) static saveable_code saveable_actor_code[] = { - SAVE_CODE(DoScaleSprite), - SAVE_CODE(DoActorDie), - SAVE_CODE(DoDebrisCurrent), - SAVE_CODE(DoActorSectorDamage), SAVE_CODE(DoActorDebris), SAVE_CODE(DoFireFly), SAVE_CODE(DoGenerateSewerDebris), - SAVE_CODE(KeepActorOnFloor), - SAVE_CODE(DoActorBeginSlide), - SAVE_CODE(DoActorSlide), - SAVE_CODE(DoActorBeginJump), - SAVE_CODE(DoActorJump), - SAVE_CODE(DoActorBeginFall), - SAVE_CODE(DoActorFall), - SAVE_CODE(DoActorStopFall), SAVE_CODE(DoActorDeathMove), - SAVE_CODE(DoBeginJump), - SAVE_CODE(DoJump), - SAVE_CODE(DoBeginFall), - SAVE_CODE(DoFall) }; saveable_module saveable_actor = diff --git a/source/games/sw/src/ai.cpp b/source/games/sw/src/ai.cpp index 82cc5a62c..fcd5121e9 100644 --- a/source/games/sw/src/ai.cpp +++ b/source/games/sw/src/ai.cpp @@ -115,6 +115,7 @@ void DebugMoveHit(short SpriteNum) bool ActorMoveHitReact(short SpriteNum) { + auto actor = &swActors[SpriteNum]; USERp u = User[SpriteNum].Data(); // Should only return true if there is a reaction to what was hit that @@ -138,7 +139,7 @@ bool ActorMoveHitReact(short SpriteNum) action = ChooseAction(u->Personality->TouchTarget); if (action) { - (*action)(SpriteNum); + (*action)(actor); return true; } } @@ -819,9 +820,10 @@ DoActorActionDecide(short SpriteNum) int -InitActorDecide(short SpriteNum) +InitActorDecide(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; // NOTE: It is possible to overflow the stack with too many calls to this // routine @@ -833,15 +835,16 @@ InitActorDecide(short SpriteNum) u->ActorActionFunc = DoActorDecide; - DoActorDecide(SpriteNum); + DoActorDecide(actor); return 0; } int -DoActorDecide(short SpriteNum) +DoActorDecide(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; ANIMATORp actor_action; @@ -875,7 +878,7 @@ DoActorDecide(short SpriteNum) if (actor_action != InitActorDecide) { // NOT staying put - (*actor_action)(SpriteNum); + (*actor_action)(actor); //CON_Message("DoActorDecide: NOT Staying put"); } else @@ -895,9 +898,10 @@ int sw_snd_scratch = 0; int -InitActorAlertNoise(short SpriteNum) +InitActorAlertNoise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 1; // MONO_PRINT(strcpy(ds,"Init Actor Threat Noise")); @@ -911,9 +915,10 @@ InitActorAlertNoise(short SpriteNum) int -InitActorAmbientNoise(short SpriteNum) +InitActorAmbientNoise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 2; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -927,9 +932,10 @@ InitActorAmbientNoise(short SpriteNum) } int -InitActorAttackNoise(short SpriteNum) +InitActorAttackNoise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 3; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -943,9 +949,10 @@ InitActorAttackNoise(short SpriteNum) } int -InitActorPainNoise(short SpriteNum) +InitActorPainNoise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 4; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -959,9 +966,10 @@ InitActorPainNoise(short SpriteNum) } int -InitActorDieNoise(short SpriteNum) +InitActorDieNoise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 5; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -975,9 +983,10 @@ InitActorDieNoise(short SpriteNum) } int -InitActorExtra1Noise(short SpriteNum) +InitActorExtra1Noise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 6; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -990,9 +999,10 @@ InitActorExtra1Noise(short SpriteNum) } int -InitActorExtra2Noise(short SpriteNum) +InitActorExtra2Noise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 7; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -1005,9 +1015,10 @@ InitActorExtra2Noise(short SpriteNum) } int -InitActorExtra3Noise(short SpriteNum) +InitActorExtra3Noise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 8; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -1020,9 +1031,10 @@ InitActorExtra3Noise(short SpriteNum) } int -InitActorExtra4Noise(short SpriteNum) +InitActorExtra4Noise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 9; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -1035,9 +1047,10 @@ InitActorExtra4Noise(short SpriteNum) } int -InitActorExtra5Noise(short SpriteNum) +InitActorExtra5Noise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 10; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -1050,9 +1063,10 @@ InitActorExtra5Noise(short SpriteNum) } int -InitActorExtra6Noise(short SpriteNum) +InitActorExtra6Noise(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sw_snd_scratch = 11; // MONO_PRINT(strcpy(ds,"Init Actor Move Noise")); @@ -1070,9 +1084,10 @@ InitActorExtra6Noise(short SpriteNum) */ int -InitActorMoveCloser(short SpriteNum) +InitActorMoveCloser(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; //MONO_PRINT("Init Actor Move Closer\n"); @@ -1081,15 +1096,16 @@ InitActorMoveCloser(short SpriteNum) if (u->Rot != u->ActorActionSet->Run) NewStateGroup(SpriteNum, u->ActorActionSet->Run); - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); return 0; } int -DoActorCantMoveCloser(short SpriteNum) +DoActorCantMoveCloser(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; //MONO_PRINT("Can't move closer\n"); @@ -1109,20 +1125,19 @@ DoActorCantMoveCloser(short SpriteNum) } else { - int InitActorReposition(short SpriteNum); - // Try to move closer //MONO_PRINT("Move Closer - Trying to move around\n"); - InitActorReposition(SpriteNum); + InitActorReposition(actor); } return 0; } int -DoActorMoveCloser(short SpriteNum) +DoActorMoveCloser(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int nx, ny; @@ -1137,7 +1152,7 @@ DoActorMoveCloser(short SpriteNum) if (ActorMoveHitReact(SpriteNum)) return 0; - DoActorCantMoveCloser(SpriteNum); + DoActorCantMoveCloser(actor); return 0; } @@ -1168,7 +1183,7 @@ DoActorMoveCloser(short SpriteNum) if (!CanSeePlayer(SpriteNum)) { // stay put and choose another option - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } else @@ -1181,7 +1196,7 @@ DoActorMoveCloser(short SpriteNum) // Should be a random value test if (u->Dist > 512 * 3) { - InitActorDecide(SpriteNum); + InitActorDecide(actor); } return 0; @@ -1364,9 +1379,10 @@ FindWanderTrack(USERp u) int -InitActorRunAway(short SpriteNum) +InitActorRunAway(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; //MONO_PRINT("Init Actor RunAway\n"); @@ -1386,7 +1402,7 @@ InitActorRunAway(short SpriteNum) else { SET(u->Flags, SPR_RUN_AWAY); - InitActorReposition(SpriteNum); + InitActorReposition(actor); ////DSPRINTF(ds, "Actor RunAway\n"); //MONO_PRINT(ds); } @@ -1395,16 +1411,17 @@ InitActorRunAway(short SpriteNum) } int -InitActorRunToward(short SpriteNum) +InitActorRunToward(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; //MONO_PRINT("InitActorRunToward\n"); u->ActorActionFunc = DoActorDecide; NewStateGroup(SpriteNum, u->ActorActionSet->Run); - InitActorReposition(SpriteNum); + InitActorReposition(actor); DoActorSetSpeed(SpriteNum, FAST_SPEED); return 0; @@ -1418,9 +1435,10 @@ InitActorRunToward(short SpriteNum) int -InitActorAttack(short SpriteNum) +InitActorAttack(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; // zombie is attacking a player @@ -1437,7 +1455,7 @@ InitActorAttack(short SpriteNum) if (TEST(sprite[u->tgt_sp-sprite].cstat, CSTAT_SPRITE_TRANSLUCENT)) { - InitActorRunAway(SpriteNum); + InitActorRunAway(actor); return 0; } @@ -1445,13 +1463,13 @@ InitActorAttack(short SpriteNum) User[u->tgt_sp-sprite]->Health <= 0) { DoActorPickClosePlayer(SpriteNum); - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } if (!CanHitPlayer(SpriteNum)) { - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } @@ -1462,7 +1480,7 @@ InitActorAttack(short SpriteNum) TEST(User[u->tgt_sp-sprite]->PlayerP->Flags, PF_DEAD)) { DoActorPickClosePlayer(SpriteNum); - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } @@ -1477,7 +1495,7 @@ InitActorAttack(short SpriteNum) // If it's your own kind, lay off! if (u->ID == User[u->tgt_sp - sprite]->ID && !User[u->tgt_sp - sprite]->PlayerP) { - InitActorRunAway(SpriteNum); + InitActorRunAway(actor); return 0; } @@ -1516,16 +1534,18 @@ InitActorAttack(short SpriteNum) } - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); return 0; } int -DoActorAttack(short SpriteNum) +DoActorAttack(DSWActor* actor) { - USERp u = User[SpriteNum].Data(),pu; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + USERp pu; SPRITEp sp = User[SpriteNum]->SpriteP; short rand_num; int dist,a,b,c; @@ -1560,9 +1580,10 @@ DoActorAttack(short SpriteNum) } int -InitActorEvade(short SpriteNum) +InitActorEvade(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; //MONO_PRINT("Init Actor Evade\n"); @@ -1588,9 +1609,10 @@ InitActorEvade(short SpriteNum) } int -InitActorWanderAround(short SpriteNum) +InitActorWanderAround(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; //DSPRINTF(ds, "InitActorWanderAround\n"); @@ -1613,9 +1635,10 @@ InitActorWanderAround(short SpriteNum) } int -InitActorFindPlayer(short SpriteNum) +InitActorFindPlayer(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int DoActorFindPlayer(short SpriteNum); @@ -1638,7 +1661,7 @@ InitActorFindPlayer(short SpriteNum) } else { - InitActorReposition(SpriteNum); + InitActorReposition(actor); } @@ -1646,9 +1669,10 @@ InitActorFindPlayer(short SpriteNum) } int -InitActorDuck(short SpriteNum) +InitActorDuck(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; short dist; @@ -1676,15 +1700,16 @@ InitActorDuck(short SpriteNum) } - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); return 0; } int -DoActorDuck(short SpriteNum) +DoActorDuck(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if ((u->WaitTics -= ACTORMOVETICS) < 0) { @@ -1698,9 +1723,10 @@ DoActorDuck(short SpriteNum) } int -DoActorMoveJump(short SpriteNum) +DoActorMoveJump(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int nx, ny; @@ -1713,7 +1739,7 @@ DoActorMoveJump(short SpriteNum) if (!TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) { - InitActorDecide(SpriteNum); + InitActorDecide(actor); } return 0; @@ -1924,14 +1950,11 @@ FindNewAngle(short SpriteNum, signed char dir, int DistToMove) */ -#define REPOSITION 2 - -#if REPOSITION == 2 int -InitActorReposition(short SpriteNum) +InitActorReposition(DSWActor* actor) { - int DoActorReposition(short SpriteNum); - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; short ang; int rnum; @@ -1987,7 +2010,7 @@ InitActorReposition(short SpriteNum) if (ang == -1) { u->Vis = 8; - InitActorPause(SpriteNum); + InitActorPause(actor); return 0; } @@ -2008,7 +2031,7 @@ InitActorReposition(short SpriteNum) if (ang == -1) { u->Vis = 8; - InitActorPause(SpriteNum); + InitActorPause(actor); return 0; } } @@ -2029,15 +2052,16 @@ InitActorReposition(short SpriteNum) if (!TEST(u->Flags, SPR_SWIMMING)) NewStateGroup(SpriteNum, u->ActorActionSet->Run); - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); return 0; } int -DoActorReposition(short SpriteNum) +DoActorReposition(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int nx, ny; @@ -2051,14 +2075,14 @@ DoActorReposition(short SpriteNum) return 0; u->Vis = 6; - InitActorPause(SpriteNum); + InitActorPause(actor); return 0; } // if close to target distance do a Decision again if (u->TargetDist < 50) { - InitActorDecide(SpriteNum); + InitActorDecide(actor); } return 0; @@ -2066,9 +2090,10 @@ DoActorReposition(short SpriteNum) int -InitActorPause(short SpriteNum) +InitActorPause(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; u->ActorActionFunc = DoActorPause; @@ -2076,15 +2101,16 @@ InitActorPause(short SpriteNum) //if (!TEST(u->Flags, SPR_SWIMMING)) //NewStateGroup(SpriteNum, u->ActorActionSet->Stand); - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); return 0; } int -DoActorPause(short SpriteNum) +DoActorPause(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; // Using Vis instead of WaitTics, var name sucks, but it's the same type // WaitTics is used by too much other actor code and causes problems here @@ -2096,106 +2122,13 @@ DoActorPause(short SpriteNum) return 0; } -#endif -// not used - simplified version that is purely random that is easier to follow -// just leaving it here to look at -#if REPOSITION == 1 -int -InitActorReposition(short SpriteNum) -{ - int DoActorReposition(short SpriteNum); - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; - - //MONO_PRINT("InitActorReposition\n"); - - u->WaitTics = 8; - sp->ang = RANDOM_P2(2048); - - u->ActorActionFunc = DoActorReposition; - NewStateGroup(SpriteNum, u->ActorActionSet->Run); - - (*u->ActorActionFunc)(SpriteNum); - - return 0; -} - -int -DoActorReposition(short SpriteNum) -{ - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; - int nx, ny; - - nx = MulScale(sp->xvel, bcos(sp->ang), 14); - ny = MulScale(sp->xvel, bsin(sp->ang), 14); - - if (!move_actor(SpriteNum, nx, ny, 0L)) - { - if (ActorMoveHitReact(SpriteNum)) - return 0; - - InitActorPause(SpriteNum); - return 0; - } - - return 0; -} - - -int -InitActorPause(short SpriteNum) -{ - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; - - //MONO_PRINT("InitActorPause\n"); - - u->ActorActionFunc = DoActorPause; - - //NewStateGroup(SpriteNum, u->ActorActionSet->Stand); - - (*u->ActorActionFunc)(SpriteNum); - - return 0; -} - -int -DoActorPause(short SpriteNum) -{ - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; - - if ((u->WaitTics -= ACTORMOVETICS) < 0) - { - u->ActorActionFunc = DoActorDecide; - RESET(u->Flags, SPR_TARGETED); - } - - return 0; -} -#endif #include "saveable.h" static saveable_code saveable_ai_code[] = { - SAVE_CODE(DebugMoveHit), - SAVE_CODE(ActorMoveHitReact), - SAVE_CODE(ActorFlaming), - SAVE_CODE(DoActorSetSpeed), - SAVE_CODE(ChooseAction), - SAVE_CODE(ChooseActionNumber), - SAVE_CODE(DoActorNoise), - SAVE_CODE(CanSeePlayer), - SAVE_CODE(CanHitPlayer), - SAVE_CODE(DoActorPickClosePlayer), - SAVE_CODE(GetPlayerSpriteNum), - SAVE_CODE(CloseRangeDist), - SAVE_CODE(DoActorOperate), - SAVE_CODE(DoActorActionDecide), SAVE_CODE(InitActorDecide), SAVE_CODE(DoActorDecide), SAVE_CODE(InitActorAlertNoise), @@ -2210,7 +2143,6 @@ static saveable_code saveable_ai_code[] = SAVE_CODE(InitActorExtra5Noise), SAVE_CODE(InitActorExtra6Noise), SAVE_CODE(InitActorMoveCloser), - SAVE_CODE(DoActorCantMoveCloser), SAVE_CODE(DoActorMoveCloser), SAVE_CODE(FindTrackToPlayer), SAVE_CODE(FindTrackAwayFromPlayer), @@ -2225,10 +2157,8 @@ static saveable_code saveable_ai_code[] = SAVE_CODE(InitActorDuck), SAVE_CODE(DoActorDuck), SAVE_CODE(DoActorMoveJump), - SAVE_CODE(FindNewAngle), SAVE_CODE(InitActorReposition), SAVE_CODE(DoActorReposition), - SAVE_CODE(InitActorPause), SAVE_CODE(DoActorPause) }; diff --git a/source/games/sw/src/ai.h b/source/games/sw/src/ai.h index 73cee9eb1..25548cd51 100644 --- a/source/games/sw/src/ai.h +++ b/source/games/sw/src/ai.h @@ -80,41 +80,41 @@ bool CanSeePlayer(short SpriteNum); int CanHitPlayer(short SpriteNum); int DoActorPickClosePlayer(short SpriteNum); int CloseRangeDist(SPRITEp sp1,SPRITEp sp2); -int InitActorDecide(short SpriteNum); -int DoActorDecide(short SpriteNum); -int InitActorAlertNoise(short SpriteNum); -int InitActorAmbientNoise(short SpriteNum); -int InitActorAttackNoise(short SpriteNum); -int InitActorPainNoise(short SpriteNum); -int InitActorDieNoise(short SpriteNum); -int InitActorExtra1Noise(short SpriteNum); -int InitActorExtra2Noise(short SpriteNum); -int InitActorExtra3Noise(short SpriteNum); -int InitActorExtra4Noise(short SpriteNum); -int InitActorExtra5Noise(short SpriteNum); -int InitActorExtra6Noise(short SpriteNum); -int InitActorMoveCloser(short SpriteNum); -int DoActorCantMoveCloser(short SpriteNum); -int DoActorMoveCloser(short SpriteNum); +int InitActorDecide(DSWActor* actor); +int DoActorDecide(DSWActor* actor); +int InitActorAlertNoise(DSWActor* actor); +int InitActorAmbientNoise(DSWActor* actor); +int InitActorAttackNoise(DSWActor* actor); +int InitActorPainNoise(DSWActor* actor); +int InitActorDieNoise(DSWActor* actor); +int InitActorExtra1Noise(DSWActor* actor); +int InitActorExtra2Noise(DSWActor* actor); +int InitActorExtra3Noise(DSWActor* actor); +int InitActorExtra4Noise(DSWActor* actor); +int InitActorExtra5Noise(DSWActor* actor); +int InitActorExtra6Noise(DSWActor* actor); +int InitActorMoveCloser(DSWActor* actor); +int DoActorCantMoveCloser(DSWActor* actor); +int DoActorMoveCloser(DSWActor* actor); short FindTrackToPlayer(USERp u); short FindTrackAwayFromPlayer(USERp u); short FindWanderTrack(USERp u); -int InitActorRunAway(short SpriteNum); -int InitActorRunToward(short SpriteNum); -int InitActorAttack(short SpriteNum); -int DoActorAttack(short SpriteNum); -int InitActorEvade(short SpriteNum); -int InitActorWanderAround(short SpriteNum); -int InitActorFindPlayer(short SpriteNum); -int InitActorDuck(short SpriteNum); -int DoActorDuck(short SpriteNum); -int DoActorMoveJump(short SpriteNum); +int InitActorRunAway(DSWActor* actor); +int InitActorRunToward(DSWActor* actor); +int InitActorAttack(DSWActor* actor); +int DoActorAttack(DSWActor* actor); +int InitActorEvade(DSWActor* actor); +int InitActorWanderAround(DSWActor* actor); +int InitActorFindPlayer(DSWActor* actor); +int InitActorDuck(DSWActor* actor); +int DoActorDuck(DSWActor* actor); +int DoActorMoveJump(DSWActor* actor); int move_scan(short SpriteNum,short ang,int dist,int *stopx,int *stopy,int *stopz,short *stopsect); int FindNewAngle(short SpriteNum,signed char dir,int DistToMove); -int InitActorReposition(short SpriteNum); -int DoActorReposition(short SpriteNum); -int InitActorPause(short SpriteNum); -int DoActorPause(short SpriteNum); +int InitActorReposition(DSWActor* actor); +int DoActorReposition(DSWActor* actor); +int InitActorPause(DSWActor* actor); +int DoActorPause(DSWActor* actor); /* ANIMATOR diff --git a/source/games/sw/src/break.cpp b/source/games/sw/src/break.cpp index a38ea510f..552a30c48 100644 --- a/source/games/sw/src/break.cpp +++ b/source/games/sw/src/break.cpp @@ -745,7 +745,7 @@ bool UserBreakWall(WALLp wp, short) return false; } -int WallBreakPosition(short hit_wall, short *sectnum, int *x, int *y, int *z, short *ang) +int WallBreakPosition(short hit_wall, int *sectnum, int *x, int *y, int *z, short *ang) { short w,nw; WALLp wp; @@ -823,7 +823,7 @@ bool HitBreakWall(WALLp wp, int hit_x, int hit_y, int hit_z, short ang, short ty //if (hit_x == INT32_MAX) { - short sectnum; + int sectnum; WallBreakPosition(short(wp - wall), §num, &hit_x, &hit_y, &hit_z, &ang); } @@ -1091,7 +1091,7 @@ static int SectorOfWall(short theline) void DoWallBreakMatch(short match) { - short i,sectnum; + int i,sectnum; int x,y,z; WALLp wp; short wall_ang; diff --git a/source/games/sw/src/break.h b/source/games/sw/src/break.h index 133b9f9bf..846f2f972 100644 --- a/source/games/sw/src/break.h +++ b/source/games/sw/src/break.h @@ -51,7 +51,7 @@ short FindBreakSpriteMatch(short match); bool HitBreakWall(WALLp wp, int, int, int, short ang, short type); int HitBreakSprite(short BreakSprite, short type); bool CheckBreakToughness(BREAK_INFOp break_info, short ID); -int WallBreakPosition(short hit_wall, short *sectnum, int *x, int *y, int *z, short *ang); +int WallBreakPosition(short hit_wall, int *sectnum, int *x, int *y, int *z, short *ang); void SortBreakInfo(void); END_SW_NS diff --git a/source/games/sw/src/bunny.cpp b/source/games/sw/src/bunny.cpp index 3dfb2a387..a729c60a7 100644 --- a/source/games/sw/src/bunny.cpp +++ b/source/games/sw/src/bunny.cpp @@ -537,7 +537,7 @@ STATEp sg_BunnyFall[] = ////////////////////// #define BUNNY_JUMP_ATTACK_RATE 35 -int DoBunnyBeginJumpAttack(short SpriteNum); +int DoBunnyBeginJumpAttack(DSWActor* actor); STATE s_BunnyJumpAttack[5][6] = { @@ -850,10 +850,11 @@ PickBunnyJumpSpeed(short SpriteNum, int pix_height) // int -DoBunnyBeginJumpAttack(short SpriteNum) +DoBunnyBeginJumpAttack(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SPRITEp psp = User[SpriteNum]->tgt_sp; short tang; @@ -885,10 +886,10 @@ DoBunnyBeginJumpAttack(short SpriteNum) } int -DoBunnyMoveJump(short SpriteNum) +DoBunnyMoveJump(DSWActor* actor) { - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + SPRITEp sp = u->s(); if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { @@ -898,32 +899,32 @@ DoBunnyMoveJump(short SpriteNum) nx = MulScale(sp->xvel, bcos(sp->ang), 14); ny = MulScale(sp->xvel, bsin(sp->ang), 14); - move_actor(SpriteNum, nx, ny, 0L); + move_actor(u->SpriteNum, nx, ny, 0L); if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else - DoActorFall(SpriteNum); + DoActorFall(actor); } - DoActorZrange(SpriteNum); + DoActorZrange(u->SpriteNum); if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { // if (DoBunnyQuickJump(SpriteNum)) // return (0); - InitActorDecide(SpriteNum); + InitActorDecide(actor); } return 0; } int -DoPickCloseBunny(short SpriteNum) +DoPickCloseBunny(USERp u) { - USERp u = User[SpriteNum].Data(), tu; - SPRITEp sp = &sprite[SpriteNum],tsp; + USERp tu; + SPRITEp sp = u->s(),tsp; int dist, near_dist = 1000, a,b,c; int i; //short BunnyCount=0, Bunny_Result = -1; @@ -960,15 +961,16 @@ DoPickCloseBunny(short SpriteNum) } int -DoBunnyQuickJump(short SpriteNum) +DoBunnyQuickJump(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (u->spal != PALETTE_PLAYER8) return false; if (!u->lo_sp && u->spal == PALETTE_PLAYER8 && MoveSkip4) - DoPickCloseBunny(SpriteNum); + DoPickCloseBunny(u); // Random Chance of like sexes fighting if (u->lo_sp) @@ -1096,17 +1098,17 @@ DoBunnyQuickJump(short SpriteNum) int -NullBunny(short SpriteNum) +NullBunny(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else - DoActorFall(SpriteNum); + DoActorFall(actor); } // stay on floor unless doing certain things @@ -1114,29 +1116,31 @@ NullBunny(short SpriteNum) KeepActorOnFloor(SpriteNum); if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoBunnyPain(short SpriteNum) +int DoBunnyPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullBunny(SpriteNum); + NullBunny(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } -int DoBunnyRipHeart(short SpriteNum) +int DoBunnyRipHeart(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SPRITEp tsp = u->tgt_sp; @@ -1148,12 +1152,13 @@ int DoBunnyRipHeart(short SpriteNum) return 0; } -int DoBunnyStandKill(short SpriteNum) +int DoBunnyStandKill(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - NullBunny(SpriteNum); + NullBunny(actor); // Growl like the bad ass bunny you are! if (RandomRange(1000) > 800) @@ -1180,6 +1185,7 @@ void BunnyHatch(short Weapon) for (i = 0; i < MAX_BUNNYS; i++) { New = COVERinsertsprite(wp->sectnum, STAT_DEFAULT); + auto actorNew = &swActors[New]; np = &sprite[New]; memset(np,0,sizeof(SPRITE)); np->sectnum = wp->sectnum; @@ -1236,7 +1242,7 @@ void BunnyHatch(short Weapon) // if I didn't do this here they get stuck in the air sometimes DoActorZrange(New); - DoActorJump(New); + DoActorJump(actorNew); } } @@ -1249,6 +1255,7 @@ int BunnyHatch2(short Weapon) USERp nu; New = COVERinsertsprite(wp->sectnum, STAT_DEFAULT); + auto actorNew = &swActors[New]; np = &sprite[New]; memset(np,0,sizeof(SPRITE)); np->sectnum = wp->sectnum; @@ -1306,16 +1313,17 @@ int BunnyHatch2(short Weapon) // if I didn't do this here they get stuck in the air sometimes DoActorZrange(New); - DoActorJump(New); + DoActorJump(actorNew); return New; } int -DoBunnyMove(short SpriteNum) +DoBunnyMove(DSWActor* actor) { - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + auto sp = u->s(); + int SpriteNum = u->SpriteNum; // Parental lock crap if (TEST(sp->cstat, CSTAT_SPRITE_INVISIBLE)) @@ -1327,36 +1335,36 @@ DoBunnyMove(short SpriteNum) if (u->scale_speed) { - DoScaleSprite(SpriteNum); + DoScaleSprite(actor); } if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else - DoActorFall(SpriteNum); + DoActorFall(actor); } // if on a player/enemy sprite jump quickly if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - DoBunnyQuickJump(SpriteNum); + DoBunnyQuickJump(actor); } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); if (RandomRange(1000) > 985 && sp->pal != PALETTE_PLAYER1 && u->track < 0) { @@ -1377,7 +1385,7 @@ DoBunnyMove(short SpriteNum) default: sp->ang = NORM_ANGLE(RandomRange(2048 << 6) >> 6); u->jump_speed = -350; - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); u->ActorActionFunc = DoActorMoveJump; break; } @@ -1387,42 +1395,45 @@ DoBunnyMove(short SpriteNum) } int -BunnySpew(short SpriteNum) +BunnySpew(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; //InitBloodSpray(SpriteNum,true,-1); InitBloodSpray(SpriteNum,true,-1); return 0; } int -DoBunnyEat(short SpriteNum) +DoBunnyEat(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else - DoActorFall(SpriteNum); + DoActorFall(actor); } // if on a player/enemy sprite jump quickly if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - DoBunnyQuickJump(SpriteNum); + DoBunnyQuickJump(actor); } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); switch (sector[sp->sectnum].floorpicnum) { @@ -1447,27 +1458,28 @@ DoBunnyEat(short SpriteNum) } int -DoBunnyScrew(short SpriteNum) +DoBunnyScrew(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else - DoActorFall(SpriteNum); + DoActorFall(actor); } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); if (RandomRange(1000) > 990) // Bunny sex sounds { @@ -1496,10 +1508,11 @@ DoBunnyScrew(short SpriteNum) } int -DoBunnyGrowUp(short SpriteNum) +DoBunnyGrowUp(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (sp->pal == PALETTE_PLAYER1) return 0; // Don't bother white bunnies @@ -1536,9 +1549,6 @@ DoBunnyGrowUp(short SpriteNum) static saveable_code saveable_bunny_code[] = { - SAVE_CODE(SetupBunny), - SAVE_CODE(GetBunnyJumpHeight), - SAVE_CODE(PickBunnyJumpSpeed), SAVE_CODE(DoBunnyBeginJumpAttack), SAVE_CODE(DoBunnyMoveJump), SAVE_CODE(DoPickCloseBunny), @@ -1547,8 +1557,6 @@ static saveable_code saveable_bunny_code[] = SAVE_CODE(DoBunnyPain), SAVE_CODE(DoBunnyRipHeart), SAVE_CODE(DoBunnyStandKill), - SAVE_CODE(BunnyHatch), - SAVE_CODE(BunnyHatch2), SAVE_CODE(DoBunnyMove), SAVE_CODE(BunnySpew), SAVE_CODE(DoBunnyEat), diff --git a/source/games/sw/src/coolg.cpp b/source/games/sw/src/coolg.cpp index 8afdc61bb..8b9c36d84 100644 --- a/source/games/sw/src/coolg.cpp +++ b/source/games/sw/src/coolg.cpp @@ -124,7 +124,7 @@ ATTRIBUTE CoolgAttrib = #define COOLG_RUN_RATE 40 -ANIMATOR DoCoolgMove,NullAnimator,DoStayOnFloor, DoActorDebris, NullCoolg, DoCoolgBirth; +ANIMATOR DoCoolgMove,DoStayOnFloor, DoActorDebris, NullCoolg, DoCoolgBirth; STATE s_CoolgRun[5][4] = { @@ -585,13 +585,12 @@ NewCoolg(short SpriteNum) int -DoCoolgBirth(short New) +DoCoolgBirth(DSWActor* actor) { - USERp u; + USER* u = actor->u(); + int New = u->SpriteNum; ANIMATOR DoActorDecide; - u = User[New].Data(); - u->Health = HEALTH_COOLIE_GHOST; u->Attrib = &CoolgAttrib; DoActorSetSpeed(New, NORM_SPEED); @@ -610,18 +609,19 @@ DoCoolgBirth(short New) return 0; } -int NullCoolg(short SpriteNum) +int NullCoolg(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; u->ShellNum -= ACTORMOVETICS; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); DoCoolgMatchPlayerZ(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -709,11 +709,11 @@ int DoCoolgMatchPlayerZ(short SpriteNum) return 0; } -int InitCoolgCircle(short SpriteNum) +int InitCoolgCircle(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - u->ActorActionFunc = DoCoolgCircle; @@ -737,15 +737,16 @@ int InitCoolgCircle(short SpriteNum) u->WaitTics = (RandomRange(3)+1) * 120; - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); return 0; } -int DoCoolgCircle(short SpriteNum) +int DoCoolgCircle(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx,ny,bound; @@ -756,7 +757,7 @@ int DoCoolgCircle(short SpriteNum) if (!move_actor(SpriteNum, nx, ny, 0L)) { - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } @@ -768,14 +769,14 @@ int DoCoolgCircle(short SpriteNum) { // bumped something u->sz = bound; - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } // time out if ((u->WaitTics -= ACTORMOVETICS) < 0) { - InitActorReposition(SpriteNum); + InitActorReposition(actor); u->WaitTics = 0; return 0; } @@ -785,10 +786,11 @@ int DoCoolgCircle(short SpriteNum) int -DoCoolgDeath(short SpriteNum) +DoCoolgDeath(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx, ny; @@ -809,7 +811,7 @@ DoCoolgDeath(short SpriteNum) } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // slide while falling nx = MulScale(sp->xvel, bcos(sp->ang), 14); @@ -830,10 +832,11 @@ DoCoolgDeath(short SpriteNum) return 0; } -int DoCoolgMove(short SpriteNum) +int DoCoolgMove(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if ((u->ShellNum -= ACTORMOVETICS) <= 0) { @@ -895,13 +898,13 @@ int DoCoolgMove(short SpriteNum) } if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else { - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); } if (RANDOM_P2(1024) < 32 && !TEST(sp->cstat, CSTAT_SPRITE_INVISIBLE)) @@ -909,21 +912,20 @@ int DoCoolgMove(short SpriteNum) DoCoolgMatchPlayerZ(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoCoolgPain(short SpriteNum) +int DoCoolgPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - NullCoolg(SpriteNum); + USER* u = actor->u(); + NullCoolg(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } @@ -933,12 +935,8 @@ int DoCoolgPain(short SpriteNum) static saveable_code saveable_coolg_code[] = { - SAVE_CODE(CoolgCommon), - SAVE_CODE(SetupCoolg), - SAVE_CODE(NewCoolg), SAVE_CODE(DoCoolgBirth), SAVE_CODE(NullCoolg), - SAVE_CODE(DoCoolgMatchPlayerZ), SAVE_CODE(InitCoolgCircle), SAVE_CODE(DoCoolgCircle), SAVE_CODE(DoCoolgDeath), diff --git a/source/games/sw/src/coolie.cpp b/source/games/sw/src/coolie.cpp index 224f3cb95..9c3dec0d7 100644 --- a/source/games/sw/src/coolie.cpp +++ b/source/games/sw/src/coolie.cpp @@ -558,9 +558,11 @@ SetupCoolie(short SpriteNum) int NewCoolg(short); -int SpawnCoolg(short SpriteNum) +int SpawnCoolg(DSWActor* actor) { - + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + // Don't do a ghost every time if (RandomRange(1000) > 700 || Skill < MinEnemySkill - 1) { @@ -574,55 +576,58 @@ int SpawnCoolg(short SpriteNum) return 0; } -int CooliePain(short SpriteNum) +int CooliePain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } -int NullCoolie(short SpriteNum) +int NullCoolie(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoCoolieMove(short SpriteNum) +int DoCoolieMove(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); KeepActorOnFloor(SpriteNum); - if (DoActorSectorDamage(SpriteNum)) + if (DoActorSectorDamage(actor)) { return 0; } @@ -638,8 +643,10 @@ int DoCoolieMove(short SpriteNum) return 0; } -int InitCoolieCharge(short SpriteNum) +int InitCoolieCharge(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; if (RANDOM_P2(1024) > 950) @@ -647,7 +654,7 @@ int InitCoolieCharge(short SpriteNum) DoActorSetSpeed(SpriteNum, FAST_SPEED); - InitActorMoveCloser(SpriteNum); + InitActorMoveCloser(actor); NewStateGroup(SpriteNum, sg_CoolieCharge); @@ -656,11 +663,10 @@ int InitCoolieCharge(short SpriteNum) int -DoCoolieWaitBirth(short SpriteNum) +DoCoolieWaitBirth(DSWActor* actor) { - USERp u; - - u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if ((u->Counter -= ACTORMOVETICS) <= 0) { @@ -675,8 +681,6 @@ DoCoolieWaitBirth(short SpriteNum) static saveable_code saveable_coolie_code[] = { - SAVE_CODE(EnemyDefaults), - SAVE_CODE(SetupCoolie), SAVE_CODE(SpawnCoolg), SAVE_CODE(CooliePain), SAVE_CODE(NullCoolie), diff --git a/source/games/sw/src/copysect.cpp b/source/games/sw/src/copysect.cpp index 822140ed5..9ea9e812f 100644 --- a/source/games/sw/src/copysect.cpp +++ b/source/games/sw/src/copysect.cpp @@ -67,10 +67,10 @@ void CopySectorWalls(short dest_sectnum, short src_sectnum) wall[dest_wall_num].lotag = wall[src_wall_num].lotag; wall[dest_wall_num].extra = wall[src_wall_num].extra; - uint16_t const dest_nextwall = wall[dest_wall_num].nextwall; - uint16_t const src_nextwall = wall[src_wall_num].nextwall; + uint32_t const dest_nextwall = wall[dest_wall_num].nextwall; + uint32_t const src_nextwall = wall[src_wall_num].nextwall; - if (dest_nextwall < MAXWALLS && src_nextwall < MAXWALLS) + if (validWallIndex(dest_nextwall) && validWallIndex(src_nextwall)) { wall[dest_nextwall].picnum = wall[src_nextwall].picnum; wall[dest_nextwall].xrepeat = wall[src_nextwall].xrepeat; diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index d333c4a6a..b60bc3619 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -274,7 +274,7 @@ DoShadows(spritetype* tsprite, int& spritesortcnt, tspriteptr_t tsp, int viewz, int loz; short xrepeat; short yrepeat; - short sectnum; + int sectnum; sectnum = tsp->sectnum; // make sure its the correct sector @@ -914,7 +914,7 @@ post_analyzesprites(spritetype* tsprite, int& spritesortcnt) #endif void -CircleCamera(int *nx, int *ny, int *nz, short *vsect, binangle *nang, fixed_t q16horiz) +CircleCamera(int *nx, int *ny, int *nz, int *vsect, binangle *nang, fixed_t q16horiz) { vec3_t n = { *nx, *ny, *nz }; SPRITEp sp; @@ -943,7 +943,7 @@ CircleCamera(int *nx, int *ny, int *nz, short *vsect, binangle *nang, fixed_t q1 RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN); // Make sure sector passed to hitscan is correct - //COVERupdatesector(*nx, *ny, vsect); + //updatesector(*nx, *ny, vsect); hitscan(&n, *vsect, vx, vy, vz, &hitinfo, CLIPMASK_MISSILE); @@ -1091,7 +1091,7 @@ void DrawCrosshair(PLAYERp pp) } } -void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, binangle *tang, fixedhoriz *thoriz) +void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, int *tsectnum, binangle *tang, fixedhoriz *thoriz) { int i; binangle ang; @@ -1268,7 +1268,7 @@ int CopySprite(spritetype const * tsp, short newsector) int ConnectCopySprite(spritetype const * tsp) { - short newsector; + int newsector; int testz; if (FAF_ConnectCeiling(tsp->sectnum)) @@ -1460,7 +1460,7 @@ drawscreen(PLAYERp pp, double smoothratio) int tx, ty, tz; binangle tang, trotscrnang; fixedhoriz thoriz; - short tsectnum; + int tsectnum; short i,j; int bob_amt = 0; int quake_z, quake_x, quake_y; @@ -1515,7 +1515,7 @@ drawscreen(PLAYERp pp, double smoothratio) } tsectnum = camerapp->cursectnum; - COVERupdatesector(tx, ty, &tsectnum); + updatesector(tx, ty, &tsectnum); if (tsectnum >= 0) { @@ -1590,7 +1590,7 @@ drawscreen(PLAYERp pp, double smoothratio) } // recoil only when not in camera - thoriz = q16horiz(clamp(thoriz.asq16() + pp->recoil_horizoff, gi->playerHorizMin(), gi->playerHorizMax())); + thoriz = q16horiz(clamp(thoriz.asq16() + interpolatedvalue(pp->recoil_ohorizoff, pp->recoil_horizoff, smoothratio), gi->playerHorizMin(), gi->playerHorizMax())); } if (automapMode != am_full)// && !ScreenSavePic) diff --git a/source/games/sw/src/eel.cpp b/source/games/sw/src/eel.cpp index 54ac6fb6e..5f6d73e03 100644 --- a/source/games/sw/src/eel.cpp +++ b/source/games/sw/src/eel.cpp @@ -118,7 +118,7 @@ ATTRIBUTE EelAttrib = #define EEL_RUN_RATE 20 -ANIMATOR DoEelMove,NullAnimator,DoStayOnFloor, DoActorDebris, NullEel; +ANIMATOR DoEelMove,DoStayOnFloor, DoActorDebris, NullEel; STATE s_EelRun[5][4] = { @@ -354,7 +354,7 @@ ACTOR_ACTION_SET EelActionSet = nullptr }; -int DoEelMatchPlayerZ(short SpriteNum); +int DoEelMatchPlayerZ(DSWActor* actor); void @@ -411,56 +411,27 @@ SetupEel(short SpriteNum) return 0; } -#if 0 -int -NewEel(short SpriteNum) + +int NullEel(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; - USERp nu; - SPRITEp np; - ANIMATOR DoActorDecide; - short New; - - - New = SpawnSprite(STAT_ENEMY, EEL_RUN_R0, &s_EelBirth, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 50); - - nu = User[New].Data(); - np = &sprite[New]; - - ChangeState(New, &s_EelBirth); - nu->StateEnd = s_EelDie; - nu->Rot = sg_EelRun; - np->pal = nu->spal = u->spal; - - nu->ActorActionSet = &EelActionSet; - - np->shade = sp->shade; - - EelCommon(New); - - return 0; -} -#endif - -int NullEel(short SpriteNum) -{ - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); - DoEelMatchPlayerZ(SpriteNum); + DoEelMatchPlayerZ(actor); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoEelMatchPlayerZ(short SpriteNum) +int DoEelMatchPlayerZ(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SPRITEp tsp = User[SpriteNum]->tgt_sp; int zdiff,zdist; int loz,hiz; @@ -558,10 +529,11 @@ int DoEelMatchPlayerZ(short SpriteNum) } int -DoEelDeath(short SpriteNum) +DoEelDeath(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx, ny; if (TEST(u->Flags, SPR_FALLING)) { @@ -575,7 +547,7 @@ DoEelDeath(short SpriteNum) } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // slide while falling nx = MulScale(sp->xvel, bcos(sp->ang), 14); @@ -599,9 +571,10 @@ DoEelDeath(short SpriteNum) return 0; } -int DoEelMove(short SpriteNum) +int DoEelMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; ASSERT(u->Rot != nullptr); @@ -609,16 +582,16 @@ int DoEelMove(short SpriteNum) NewStateGroup(SpriteNum, u->ActorActionSet->CloseAttack[0]); if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); - DoEelMatchPlayerZ(SpriteNum); + DoEelMatchPlayerZ(actor); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; @@ -629,9 +602,6 @@ int DoEelMove(short SpriteNum) static saveable_code saveable_eel_code[] = { - SAVE_CODE(EelCommon), - SAVE_CODE(SetupEel), - //SAVE_CODE(NewEel), SAVE_CODE(DoEelMatchPlayerZ), SAVE_CODE(DoEelDeath), SAVE_CODE(DoEelMove) diff --git a/source/games/sw/src/game.cpp b/source/games/sw/src/game.cpp index 708feefab..967074292 100644 --- a/source/games/sw/src/game.cpp +++ b/source/games/sw/src/game.cpp @@ -179,6 +179,7 @@ void GameInterface::LoadGameTextures() void GameInterface::app_init() { GameTicRate = TICS_PER_SEC / synctics; + InputScalePercentage = 0.070625; InitCheats(); automapping = 1; @@ -715,29 +716,6 @@ int StdRandomRange(int range) // //--------------------------------------------------------------------------- -#include "saveable.h" - -saveable_module saveable_build{}; - -void Saveable_Init_Dynamic() -{ - static saveable_data saveable_build_data[] = - { - {sector, MAXSECTORS*sizeof(sectortype)}, - {sprite, MAXSPRITES*sizeof(spritetype)}, - {wall, MAXWALLS*sizeof(walltype)}, - }; - - saveable_build.data = saveable_build_data; - saveable_build.numdata = NUM_SAVEABLE_ITEMS(saveable_build_data); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - ReservedSpace GameInterface::GetReservedScreenSpace(int viewsize) { return { 0, 48 }; diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h index 4d5d12539..784713c96 100644 --- a/source/games/sw/src/game.h +++ b/source/games/sw/src/game.h @@ -330,9 +330,9 @@ inline int SPRITEp_SIZE_BOS(const spritetype* sp) #define HIT_SECTOR BIT(14) #define HIT_PLAX_WALL BIT(16) -#define NORM_SPRITE(val) ((val) & (MAXSPRITES - 1)) -#define NORM_WALL(val) ((val) & (MAXWALLS - 1)) -#define NORM_SECTOR(val) ((val) & (MAXSECTORS - 1)) +#define NORM_SPRITE(val) ((val) & (kHitIndexMask)) +#define NORM_WALL(val) ((val) & (kHitIndexMask)) +#define NORM_SECTOR(val) ((val) & (kHitIndexMask)) // overwritesprite flags #define OVER_SPRITE_MIDDLE (BIT(0)) @@ -527,7 +527,8 @@ typedef struct PANEL_SPRITEstruct PANEL_SPRITE, *PANEL_SPRITEp; struct ANIMstruct; typedef struct ANIMstruct ANIM, *ANIMp; -typedef int ANIMATOR (int16_t SpriteNum); +class DSWActor; +typedef int ANIMATOR (DSWActor* actor); typedef ANIMATOR *ANIMATORp; typedef void pANIMATOR (PANEL_SPRITEp); @@ -566,7 +567,7 @@ struct STATEstruct typedef enum {WATER_FOOT, BLOOD_FOOT} FOOT_TYPE; extern FOOT_TYPE FootMode; -int QueueFloorBlood(short hit_sprite); // Weapon.c +ANIMATOR QueueFloorBlood; // Weapon.c int QueueFootPrint(short hit_sprite); // Weapon.c int QueueGeneric(short SpriteNum, short pic); // Weapon.c int QueueLoWangs(short SpriteNum); // Weapon.c @@ -735,7 +736,7 @@ typedef void (*PLAYER_ACTION_FUNCp)(PLAYERp); typedef struct { - short cursectnum,lastcursectnum,pang,filler; + int cursectnum,lastcursectnum,pang; int xvect,yvect,oxvect,oyvect,slide_xvect,slide_yvect; int posx,posy,posz; SECTOR_OBJECTp sop_control; @@ -788,7 +789,7 @@ struct PLAYERstruct short circle_camera_ang; short camera_check_time_delay; - short cursectnum,lastcursectnum; + int cursectnum,lastcursectnum; fixed_t turn180_target; // 180 degree turn // variables that do not fit into sprite structure @@ -798,7 +799,7 @@ struct PLAYERstruct short recoil_amt; short recoil_speed; short recoil_ndx; - fixed_t recoil_horizoff; + fixed_t recoil_ohorizoff, recoil_horizoff; int oldposx,oldposy,oldposz; int RevolveX, RevolveY; @@ -1129,6 +1130,7 @@ struct USER short SpriteNum; short Attach; // attach to sprite if needed - electro snake SPRITEp SpriteP; + SPRITEp s() { return SpriteP;} // if a player's sprite points to player structure PLAYERp PlayerP; @@ -1690,6 +1692,7 @@ struct SECTOR_OBJECTstruct drive_speed, drive_slide, crush_z, + op_main_sector, // main sector operational SO moves in - for speed purposes flags; short sector[MAX_SO_SECTOR], // hold the sector numbers of the sector object @@ -1725,7 +1728,6 @@ struct SECTOR_OBJECTstruct turn_speed, // shift value determines how fast SO turns to match new angle bob_sine_ndx, // index into sine table bob_speed, // shift value for speed - op_main_sector, // main sector operational SO moves in - for speed purposes save_vel, // save velocity save_spin_speed, // save spin speed match_event, // match number @@ -1854,6 +1856,7 @@ ANIMATOR NullAnimator; int Distance(int x1, int y1, int x2, int y2); int NewStateGroup(short SpriteNum, STATEp SpriteGroup[]); +int NewStateGroup(USERp user, STATEp SpriteGroup[]); void SectorMidPoint(short sectnum, int *xmid, int *ymid, int *zmid); USERp SpawnUser(short SpriteNum, short id, STATEp state); @@ -1952,7 +1955,7 @@ void FAFhitscan(int32_t x, int32_t y, int32_t z, int16_t sectnum, bool FAFcansee(int32_t xs, int32_t ys, int32_t zs, int16_t sects, int32_t xe, int32_t ye, int32_t ze, int16_t secte); -void FAFgetzrange(int32_t x, int32_t y, int32_t z, int16_t sectnum, +void FAFgetzrange(vec3_t pos, int16_t sectnum, int32_t* hiz, int32_t* ceilhit, int32_t* loz, int32_t* florhit, int32_t clipdist, int32_t clipmask); @@ -1961,8 +1964,6 @@ void FAFgetzrangepoint(int32_t x, int32_t y, int32_t z, int16_t sectnum, int32_t* hiz, int32_t* ceilhit, int32_t* loz, int32_t* florhit); -void COVERupdatesector(int32_t x, int32_t y, int16_t* newsector); - void short_setinterpolation(short *posptr); void short_stopinterpolation(short *posptr); @@ -2075,7 +2076,6 @@ int PickJumpMaxSpeed(short SpriteNum, short max_speed); // ripper.c int DoRipperRipHeart(short SpriteNum); // ripper.c int DoRipper2RipHeart(short SpriteNum); // ripper2.c int BunnyHatch2(short Weapon); // bunny.c -int DoSkullBeginDeath(int16_t SpriteNum); // skull.c void TerminateLevel(void); // game.c void DrawMenuLevelScreen(void); // game.c @@ -2223,5 +2223,8 @@ struct GameInterface : public ::GameInterface END_SW_NS + +#include "swactor.h" + #endif diff --git a/source/games/sw/src/girlninj.cpp b/source/games/sw/src/girlninj.cpp index 5056841ba..402d09460 100644 --- a/source/games/sw/src/girlninj.cpp +++ b/source/games/sw/src/girlninj.cpp @@ -40,7 +40,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -int DoHariKariBlood(short SpriteNum); //int InitActorMoveCloser(short SpriteNum); DECISION GirlNinjaBattle[] = @@ -751,29 +750,30 @@ SetupGirlNinja(short SpriteNum) int -DoGirlNinjaMove(short SpriteNum) +DoGirlNinjaMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; // jumping and falling if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING) && !TEST(u->Flags, SPR_CLIMBING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else if (TEST(u->Flags, SPR_FALLING)) - DoActorFall(SpriteNum); + DoActorFall(actor); } // sliding if (TEST(u->Flags, SPR_SLIDING) && !TEST(u->Flags, SPR_CLIMBING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // !AIC - do track or call current action function - such as DoActorMoveCloser() if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else { - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); } // stay on floor unless doing certain things @@ -783,15 +783,16 @@ DoGirlNinjaMove(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } int -GirlNinjaJumpActionFunc(short SpriteNum) +GirlNinjaJumpActionFunc(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int nx, ny; @@ -807,47 +808,50 @@ GirlNinjaJumpActionFunc(short SpriteNum) if (!TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) { - InitActorDecide(SpriteNum); + InitActorDecide(actor); } return 0; } int -NullGirlNinja(short SpriteNum) +NullGirlNinja(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (u->WaitTics > 0) u->WaitTics -= ACTORMOVETICS; if (TEST(u->Flags, SPR_SLIDING) && !TEST(u->Flags, SPR_CLIMBING) && !TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (!TEST(u->Flags, SPR_CLIMBING) && !TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoGirlNinjaPain(short SpriteNum) +int DoGirlNinjaPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullGirlNinja(SpriteNum); + NullGirlNinja(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } -int DoGirlNinjaSpecial(short SpriteNum) +int DoGirlNinjaSpecial(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (u->spal == PALETTE_PLAYER5) { @@ -864,7 +868,6 @@ int DoGirlNinjaSpecial(short SpriteNum) static saveable_code saveable_girlninj_code[] = { - SAVE_CODE(SetupGirlNinja), SAVE_CODE(DoGirlNinjaMove), SAVE_CODE(GirlNinjaJumpActionFunc), SAVE_CODE(NullGirlNinja), diff --git a/source/games/sw/src/goro.cpp b/source/games/sw/src/goro.cpp index 66017bef2..61a4f4d31 100644 --- a/source/games/sw/src/goro.cpp +++ b/source/games/sw/src/goro.cpp @@ -118,7 +118,7 @@ ATTRIBUTE GoroAttrib = #define GORO_RUN_RATE 18 -ANIMATOR DoGoroMove,NullGoro,DoActorDebris,NullAnimator,InitEnemyFireball; +ANIMATOR DoGoroMove,NullGoro,DoActorDebris,InitEnemyFireball; STATE s_GoroRun[5][4] = { @@ -513,53 +513,49 @@ SetupGoro(short SpriteNum) return 0; } -int NullGoro(short SpriteNum) +int NullGoro(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - ASSERT(SpriteNum >= 0); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoGoroPain(short SpriteNum) +int DoGoroPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - ASSERT(SpriteNum >= 0); - - NullGoro(SpriteNum); + USER* u = actor->u(); + + NullGoro(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } -int DoGoroMove(short SpriteNum) +int DoGoroMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - ASSERT(SpriteNum >= 0); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); ASSERT(User[SpriteNum].Data()); KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -568,7 +564,6 @@ int DoGoroMove(short SpriteNum) static saveable_code saveable_goro_code[] = { - SAVE_CODE(SetupGoro), SAVE_CODE(NullGoro), SAVE_CODE(DoGoroPain), SAVE_CODE(DoGoroMove), diff --git a/source/games/sw/src/hornet.cpp b/source/games/sw/src/hornet.cpp index 9d957a432..69bca3a19 100644 --- a/source/games/sw/src/hornet.cpp +++ b/source/games/sw/src/hornet.cpp @@ -332,16 +332,17 @@ SetupHornet(short SpriteNum) return 0; } -int NullHornet(short SpriteNum) +int NullHornet(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); DoHornetMatchPlayerZ(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -421,10 +422,11 @@ int DoHornetMatchPlayerZ(short SpriteNum) return 0; } -int InitHornetCircle(short SpriteNum) +int InitHornetCircle(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); u->ActorActionFunc = DoHornetCircle; @@ -448,15 +450,16 @@ int InitHornetCircle(short SpriteNum) u->WaitTics = (RandomRange(3)+1) * 60; - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); return 0; } -int DoHornetCircle(short SpriteNum) +int DoHornetCircle(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx,ny,bound; sp->ang = NORM_ANGLE(sp->ang + u->Counter2); @@ -476,7 +479,7 @@ int DoHornetCircle(short SpriteNum) if (!move_actor(SpriteNum, nx, ny, 0L)) { - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } } @@ -489,14 +492,14 @@ int DoHornetCircle(short SpriteNum) { // bumped something u->sz = bound; - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } // time out if ((u->WaitTics -= ACTORMOVETICS) < 0) { - InitActorReposition(SpriteNum); + InitActorReposition(actor); u->WaitTics = 0; return 0; } @@ -506,10 +509,11 @@ int DoHornetCircle(short SpriteNum) int -DoHornetDeath(short SpriteNum) +DoHornetDeath(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx, ny; if (TEST(u->Flags, SPR_FALLING)) @@ -528,7 +532,7 @@ DoHornetDeath(short SpriteNum) } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // slide while falling nx = MulScale(sp->xvel, bcos(sp->ang), 14); @@ -550,11 +554,13 @@ DoHornetDeath(short SpriteNum) } // Hornets can swarm around other hornets or whatever is tagged as swarm target -int DoCheckSwarm(short SpriteNum) +int DoCheckSwarm(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; int i; SPRITEp sp = &sprite[SpriteNum], tsp; - USERp u = User[SpriteNum].Data(), tu; + USERp tu; int dist, pdist, a,b,c; PLAYERp pp; @@ -596,28 +602,29 @@ int DoCheckSwarm(short SpriteNum) } -int DoHornetMove(short SpriteNum) +int DoHornetMove(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); // Check for swarming // lotag of 1 = Swarm around lotags of 2 // lotag of 0 is normal if (sp->hitag == TAG_SWARMSPOT && sp->lotag == 1) - DoCheckSwarm(SpriteNum); + DoCheckSwarm(actor); if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); DoHornetMatchPlayerZ(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -627,7 +634,6 @@ int DoHornetMove(short SpriteNum) static saveable_code saveable_hornet_code[] = { - SAVE_CODE(SetupHornet), SAVE_CODE(NullHornet), SAVE_CODE(DoHornetMatchPlayerZ), SAVE_CODE(InitHornetCircle), diff --git a/source/games/sw/src/inv.cpp b/source/games/sw/src/inv.cpp index 6bcfbc0dd..6d3552249 100644 --- a/source/games/sw/src/inv.cpp +++ b/source/games/sw/src/inv.cpp @@ -337,9 +337,6 @@ void StopInventoryCloak(PLAYERp pp, short InventoryNum) // ////////////////////////////////////////////////////////////////////// -static char sectorfloorpals[MAXSECTORS], sectorceilingpals[MAXSECTORS], wallpals[MAXWALLS]; - - void DoPlayerNightVisionPalette(PLAYERp pp) { diff --git a/source/games/sw/src/jsector.cpp b/source/games/sw/src/jsector.cpp index db3f69d6d..0d8215bd5 100644 --- a/source/games/sw/src/jsector.cpp +++ b/source/games/sw/src/jsector.cpp @@ -474,7 +474,7 @@ void drawroomstotile(int daposx, int daposy, int daposz, { if (!testnewrenderer) { - renderDrawRoomsQ16(daposx, daposy, daposz, ang.asq16(), horiz.asq16(), dacursectnum); + renderDrawRoomsQ16(daposx, daposy, daposz, ang.asq16(), horiz.asq16(), dacursectnum, false); analyzesprites(pm_tsprite, pm_spritesortcnt, daposx, daposy, daposz, ang.asbuild()); renderDrawMasks(); } @@ -595,7 +595,6 @@ void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz, double smoothratio) SPRITEp sp = nullptr; - int camhoriz; short w; int dx, dy, dz, tdx, tdy, tdz, midx, midy; @@ -691,14 +690,8 @@ void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz, double smoothratio) // tag5 } - // See if there is a horizon value. 0 defaults to - // 100! - if (SP_TAG7(sp) != 0) - { - camhoriz = clamp(SP_TAG7(sp), gi->playerHorizMin(), gi->playerHorizMax()); - } - else - camhoriz = 0; // Default + // Set the horizon value. + auto camhoriz = q16horiz(clamp(IntToFixed(SP_TAG7(sp) - 100), gi->playerHorizMin(), gi->playerHorizMax())); // If player is dead still then update at MoveSkip4 // rate. @@ -720,7 +713,7 @@ void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz, double smoothratio) } else { - drawroomstotile(sp->x, sp->y, sp->z, buildang(SP_TAG5(sp)), buildhoriz(camhoriz), sp->sectnum, mirror[cnt].campic, smoothratio); + drawroomstotile(sp->x, sp->y, sp->z, buildang(SP_TAG5(sp)), camhoriz, sp->sectnum, mirror[cnt].campic, smoothratio); } } } diff --git a/source/games/sw/src/jsector.h b/source/games/sw/src/jsector.h index 5a26cf222..ed2eef270 100644 --- a/source/games/sw/src/jsector.h +++ b/source/games/sw/src/jsector.h @@ -40,26 +40,17 @@ typedef enum typedef struct { - short mirrorwall; // Wall number containing the mirror - // tile - short mirrorsector; // nextsector used internally to draw - // mirror rooms - short camera; // Contains number of ST1 sprite used - // as a camera + short mirrorwall; // Wall number containing the mirror tile + short mirrorsector; // nextsector used internally to draw mirror rooms + short camera; // Contains number of ST1 sprite used as a camera short camsprite; // sprite pointing to campic - short campic; // Editart tile number to draw a - // screen to + short campic; // Editart tile number to draw a screen to short numspawnspots; // Number of spawnspots used - short spawnspots[MAXMIRRORMONSTERS]; // One spot for each possible skill - // level for a - // max of up to 4 coolie ghosts to spawn. + short spawnspots[MAXMIRRORMONSTERS]; // One spot for each possible skill level for a max of up to 4 coolie ghosts to spawn. bool ismagic; // Is this a magic mirror? - uint8_t mstate; // What state the mirror is currently - // in - int maxtics; // Tic count used to time mirror - // events - int tics; // How much viewing time has been - // used on mirror? + uint8_t mstate; // What state the mirror is currently in + int maxtics; // Tic count used to time mirror events + int tics; // How much viewing time has been used on mirror? } MIRRORTYPE, *MIRRORTYPEp; extern MIRRORTYPE mirror[MAXMIRRORS]; diff --git a/source/games/sw/src/jweapon.cpp b/source/games/sw/src/jweapon.cpp index 9062d27a4..f1b82f7d5 100644 --- a/source/games/sw/src/jweapon.cpp +++ b/source/games/sw/src/jweapon.cpp @@ -43,7 +43,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -ANIMATOR NullAnimator,DoSuicide; +ANIMATOR DoSuicide; ANIMATOR DoBloodSpray; int SpawnFlashBombOnActor(int16_t enemy); @@ -257,10 +257,11 @@ STATE s_BloodSprayDrip[] = ///////////////////////////////////////////////////////////////////////////////////////////// int -DoWallBloodDrip(short SpriteNum) +DoWallBloodDrip(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); //sp->z += (300+RandomRange(2300)) >> 1; @@ -366,10 +367,11 @@ SpawnFloorSplash(short SpriteNum) int -DoBloodSpray(int16_t Weapon) +DoBloodSpray(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int cz,fz; if (TEST(u->Flags, SPR_UNDERWATER)) @@ -593,10 +595,11 @@ DoBloodSpray(int16_t Weapon) int -DoPhosphorus(int16_t Weapon) +DoPhosphorus(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); if (TEST(u->Flags, SPR_UNDERWATER)) { @@ -817,10 +820,11 @@ DoPhosphorus(int16_t Weapon) } int -DoChemBomb(int16_t Weapon) +DoChemBomb(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); if (TEST(u->Flags, SPR_UNDERWATER)) { @@ -1063,9 +1067,10 @@ DoChemBomb(int16_t Weapon) } int -DoCaltropsStick(int16_t Weapon) +DoCaltropsStick(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; u->Counter = !u->Counter; @@ -1076,10 +1081,11 @@ DoCaltropsStick(int16_t Weapon) } int -DoCaltrops(int16_t Weapon) +DoCaltrops(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); if (TEST(u->Flags, SPR_UNDERWATER)) { @@ -1332,10 +1338,11 @@ SpawnRadiationCloud(short SpriteNum) } int -DoRadiationCloud(short SpriteNum) +DoRadiationCloud(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); sp->z -= sp->zvel; @@ -1642,13 +1649,16 @@ PlayerInitFlashBomb(PLAYERp pp) } int -InitFlashBomb(int16_t SpriteNum) +InitFlashBomb(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + SPRITEp sp = &sprite[SpriteNum]; int i; unsigned int stat; int dist, tx, ty, tmin; short damage; - SPRITEp sp = &sprite[SpriteNum], hp; + SPRITEp hp; USERp hu; PLAYERp pp = Player + screenpeek; @@ -2081,8 +2091,10 @@ InitBloodSpray(int16_t SpriteNum, bool dogib, short velocity) } int -BloodSprayFall(int16_t SpriteNum) +BloodSprayFall(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; sp->z += 1500; @@ -2171,10 +2183,11 @@ DoFlagRangeTest(short Weapon, short range) } int -DoCarryFlag(int16_t Weapon) +DoCarryFlag(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); #define FLAG_DETONATE_STATE 99 SPRITEp fp = &sprite[u->FlagOwner]; @@ -2326,10 +2339,12 @@ DoCarryFlag(int16_t Weapon) } int -DoCarryFlagNoDet(int16_t Weapon) +DoCarryFlagNoDet(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); + SPRITEp ap = &sprite[u->Attach]; USERp au = User[u->Attach].Data(); SPRITEp fp = &sprite[u->FlagOwner]; @@ -2416,10 +2431,11 @@ SetCarryFlag(int16_t Weapon) } int -DoFlag(int16_t Weapon) +DoFlag(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int16_t hit_sprite = -1; hit_sprite = DoFlagRangeTest(Weapon, 1000); diff --git a/source/games/sw/src/lava.cpp b/source/games/sw/src/lava.cpp index 7b68fa2df..d6651a87a 100644 --- a/source/games/sw/src/lava.cpp +++ b/source/games/sw/src/lava.cpp @@ -485,34 +485,36 @@ SetupLava(short SpriteNum) return 0; } -int NullLava(short SpriteNum) +int NullLava(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoLavaMove(short SpriteNum) +int DoLavaMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -521,7 +523,6 @@ int DoLavaMove(short SpriteNum) static saveable_code saveable_lava_code[] = { - SAVE_CODE(SetupLava), SAVE_CODE(NullLava), SAVE_CODE(DoLavaMove), }; diff --git a/source/games/sw/src/light.cpp b/source/games/sw/src/light.cpp index bb01058ae..c16ef837a 100644 --- a/source/games/sw/src/light.cpp +++ b/source/games/sw/src/light.cpp @@ -95,7 +95,7 @@ void SectorLightShade(SPRITEp sp, short intensity) if (TEST(sp->extra, SPRX_BOOL5)) { uint16_t const nextwall = wall[w].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) { base_shade = wall_shade[wallcount]; wall[nextwall].shade = base_shade + intensity; diff --git a/source/games/sw/src/mclip.cpp b/source/games/sw/src/mclip.cpp index 97f797028..d3217033d 100644 --- a/source/games/sw/src/mclip.cpp +++ b/source/games/sw/src/mclip.cpp @@ -41,7 +41,7 @@ BEGIN_SW_NS int MultiClipMove(PLAYERp pp, int z, int floor_dist) { int i; - int ox[MAX_CLIPBOX],oy[MAX_CLIPBOX]; + vec3_t opos[MAX_CLIPBOX], pos[MAX_CLIPBOX]; SECTOR_OBJECTp sop = pp->sop; short ang; short min_ndx = 0; @@ -51,10 +51,8 @@ int MultiClipMove(PLAYERp pp, int z, int floor_dist) int ret_start; int ret; int min_ret=0; - int x[MAX_CLIPBOX],y[MAX_CLIPBOX]; int xvect,yvect; - int xs,ys; for (i = 0; i < sop->clipbox_num; i++) { @@ -62,14 +60,11 @@ int MultiClipMove(PLAYERp pp, int z, int floor_dist) // allowing you to move through wall ang = NORM_ANGLE(pp->angle.ang.asbuild() + sop->clipbox_ang[i]); - xs = pp->posx; - ys = pp->posy; + vec3_t spos = { pp->posx, pp->posy, z }; xvect = sop->clipbox_vdist[i] * bcos(ang); yvect = sop->clipbox_vdist[i] * bsin(ang); - clipmoveboxtracenum = 1; - ret_start = clipmove_old(&xs, &ys, &z, &pp->cursectnum, xvect, yvect, (int)sop->clipbox_dist[i], Z(4), floor_dist, CLIPMASK_PLAYER); - clipmoveboxtracenum = 3; + ret_start = clipmove(&spos, &pp->cursectnum, xvect, yvect, (int)sop->clipbox_dist[i], Z(4), floor_dist, CLIPMASK_PLAYER, 1); if (ret_start) { @@ -77,15 +72,15 @@ int MultiClipMove(PLAYERp pp, int z, int floor_dist) min_dist = 0; min_ndx = i; // ox is where it should be - ox[i] = x[i] = pp->posx + MulScale(sop->clipbox_vdist[i], bcos(ang), 14); - oy[i] = y[i] = pp->posy + MulScale(sop->clipbox_vdist[i], bsin(ang), 14); + opos[i].x = pos[i].x = pp->posx + MulScale(sop->clipbox_vdist[i], bcos(ang), 14); + opos[i].y = pos[i].y = pp->posy + MulScale(sop->clipbox_vdist[i], bsin(ang), 14); - // xs is where it hit - x[i] = xs; - y[i] = ys; + // spos.x is where it hit + pos[i].x = spos.x; + pos[i].y = spos.y; // see the dist moved - dist = ksqrt(SQ(x[i] - ox[i]) + SQ(y[i] - oy[i])); + dist = ksqrt(SQ(pos[i].x - opos[i].x) + SQ(pos[i].y - opos[i].y)); // save it off if (dist < min_dist) @@ -98,14 +93,14 @@ int MultiClipMove(PLAYERp pp, int z, int floor_dist) else { // save off the start position - ox[i] = x[i] = xs; - oy[i] = y[i] = ys; + opos[i] = pos[i] = spos; + pos[i].z = z; // move the box - ret = clipmove_old(&x[i], &y[i], &z, &pp->cursectnum, pp->xvect, pp->yvect, (int)sop->clipbox_dist[i], Z(4), floor_dist, CLIPMASK_PLAYER); + ret = clipmove(&pos[i], &pp->cursectnum, pp->xvect, pp->yvect, (int)sop->clipbox_dist[i], Z(4), floor_dist, CLIPMASK_PLAYER); // save the dist moved - dist = ksqrt(SQ(x[i] - ox[i]) + SQ(y[i] - oy[i])); + dist = ksqrt(SQ(pos[i].x - opos[i].x) + SQ(pos[i].y - opos[i].y)); if (ret) { @@ -121,8 +116,8 @@ int MultiClipMove(PLAYERp pp, int z, int floor_dist) } // put posx and y off from offset - pp->posx += x[min_ndx] - ox[min_ndx]; - pp->posy += y[min_ndx] - oy[min_ndx]; + pp->posx += pos[min_ndx].x - opos[min_ndx].x; + pp->posy += pos[min_ndx].y - opos[min_ndx].y; return min_ret; } @@ -135,20 +130,19 @@ short MultiClipTurn(PLAYERp pp, short new_ang, int z, int floor_dist) int x,y; short ang; int xvect, yvect; - short cursectnum = pp->cursectnum; + int cursectnum = pp->cursectnum; for (i = 0; i < sop->clipbox_num; i++) { ang = NORM_ANGLE(new_ang + sop->clipbox_ang[i]); - x = pp->posx; - y = pp->posy; + vec3_t pos = { pp->posx, pp->posy, z }; xvect = sop->clipbox_vdist[i] * bcos(ang); yvect = sop->clipbox_vdist[i] * bsin(ang); // move the box - ret = clipmove_old(&x, &y, &z, &cursectnum, xvect, yvect, (int)sop->clipbox_dist[i], Z(4), floor_dist, CLIPMASK_PLAYER); + ret = clipmove(&pos, &cursectnum, xvect, yvect, (int)sop->clipbox_dist[i], Z(4), floor_dist, CLIPMASK_PLAYER); ASSERT(cursectnum >= 0); diff --git a/source/games/sw/src/misc.h b/source/games/sw/src/misc.h index 1c1bf0fce..b7c4cb8a9 100644 --- a/source/games/sw/src/misc.h +++ b/source/games/sw/src/misc.h @@ -19,10 +19,29 @@ void MapColors(short num,COLOR_MAP cm,short create); int32_t CONFIG_ReadSetup(void); bool WarpPlaneSectorInfo(short sectnum, SPRITEp* sp_ceiling, SPRITEp* sp_floor); -SPRITEp WarpPlane(int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum); -SPRITEp WarpToArea(SPRITEp sp_from, int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum); +SPRITEp WarpPlane(int32_t* x, int32_t* y, int32_t* z, int* sectnum); +SPRITEp WarpToArea(SPRITEp sp_from, int32_t* x, int32_t* y, int32_t* z, int* sectnum); bool WarpSectorInfo(short sectnum, SPRITEp* sp_warp); -SPRITEp Warp(int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum); +SPRITEp Warp(int32_t* x, int32_t* y, int32_t* z, int* sectnum); + +[[deprecated]] +SPRITEp Warp(int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum) +{ + int sect16 = *sectnum; + auto p= Warp(x, y, z, §16); + *sectnum = sect16; + return p; +} + +[[deprecated]] +SPRITEp WarpPlane(int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum) +{ + int sect16 = *sectnum; + auto p= WarpPlane(x, y, z, §16); + *sectnum = sect16; + return p; +} + void ProcessVisOn(void); void VisViewChange(PLAYERp pp, int* vis); @@ -66,9 +85,9 @@ int DoJump(short SpriteNum); int DoBeginFall(short SpriteNum); int DoFall(short SpriteNum); void KeepActorOnFloor(short SpriteNum); -int DoActorSlide(short SpriteNum); -int DoActorSectorDamage(short SpriteNum); -int DoScaleSprite(short SpriteNum); +int DoActorSlide(DSWActor* actor); +int DoActorSectorDamage(DSWActor* actor); +int DoScaleSprite(DSWActor* actor); void InitPlayerSprite(PLAYERp pp); void InitAllPlayerSprites(void); diff --git a/source/games/sw/src/miscactr.cpp b/source/games/sw/src/miscactr.cpp index 538b3efa6..8d694f070 100644 --- a/source/games/sw/src/miscactr.cpp +++ b/source/games/sw/src/miscactr.cpp @@ -149,9 +149,10 @@ SetupToiletGirl(short SpriteNum) return 0; } -int DoToiletGirl(short SpriteNum) +int DoToiletGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -201,15 +202,16 @@ int DoToiletGirl(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } -int NullToiletGirl(short SpriteNum) +int NullToiletGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -239,9 +241,10 @@ int NullToiletGirl(short SpriteNum) return 0; } -int ToiletGirlUzi(short SpriteNum) +int ToiletGirlUzi(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); @@ -256,11 +259,12 @@ int ToiletGirlUzi(short SpriteNum) return 0; } -int ToiletGirlPain(short SpriteNum) +int ToiletGirlPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullToiletGirl(SpriteNum); + NullToiletGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(SpriteNum,s_ToiletGirlStand); @@ -388,9 +392,10 @@ SetupWashGirl(short SpriteNum) return 0; } -int DoWashGirl(short SpriteNum) +int DoWashGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -446,15 +451,16 @@ int DoWashGirl(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } -int NullWashGirl(short SpriteNum) +int NullWashGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -484,9 +490,10 @@ int NullWashGirl(short SpriteNum) return 0; } -int WashGirlUzi(short SpriteNum) +int WashGirlUzi(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); @@ -501,11 +508,11 @@ int WashGirlUzi(short SpriteNum) return 0; } -int WashGirlPain(short SpriteNum) +int WashGirlPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - NullWashGirl(SpriteNum); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + NullWashGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(SpriteNum,s_WashGirlStand); @@ -597,16 +604,17 @@ SetupTrashCan(short SpriteNum) return 0; } -int DoTrashCan(short SpriteNum) +int DoTrashCan(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; //(*u->ActorActionFunc) (SpriteNum); // stay on floor unless doing certain things if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { @@ -618,12 +626,13 @@ int DoTrashCan(short SpriteNum) return 0; } -int TrashCanPain(short SpriteNum) +int TrashCanPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); @@ -705,10 +714,11 @@ SetupPachinkoLight(short SpriteNum) return 0; } -int PachinkoLightOperate(short SpriteNum) +int PachinkoLightOperate(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if ((u->WaitTics -= ACTORMOVETICS) <= 0) { @@ -804,10 +814,11 @@ SetupPachinko1(short SpriteNum) return 0; } -int PachinkoCheckWin(short SpriteNum) +int PachinkoCheckWin(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); u->WaitTics = 0; // Can operate it again now @@ -869,9 +880,10 @@ int PachinkoCheckWin(short SpriteNum) return 0; } -int Pachinko1Operate(short SpriteNum) +int Pachinko1Operate(DSWActor* actor) { - SPRITEp sp = &sprite[SpriteNum]; + USER* u = actor->u(); + SPRITEp sp = u->s(); short rnd; rnd = RandomRange(1000); @@ -1260,9 +1272,10 @@ SetupCarGirl(short SpriteNum) return 0; } -int DoCarGirl(short SpriteNum) +int DoCarGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -1303,15 +1316,16 @@ int DoCarGirl(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } -int NullCarGirl(short SpriteNum) +int NullCarGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -1348,9 +1362,10 @@ int NullCarGirl(short SpriteNum) return 0; } -int CarGirlUzi(short SpriteNum) +int CarGirlUzi(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); @@ -1365,11 +1380,11 @@ int CarGirlUzi(short SpriteNum) return 0; } -int CarGirlPain(short SpriteNum) +int CarGirlPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - NullCarGirl(SpriteNum); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + NullCarGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(SpriteNum,s_CarGirlStand); @@ -1479,9 +1494,10 @@ SetupMechanicGirl(short SpriteNum) return 0; } -int DoMechanicGirl(short SpriteNum) +int DoMechanicGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -1522,15 +1538,16 @@ int DoMechanicGirl(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } -int NullMechanicGirl(short SpriteNum) +int NullMechanicGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -1567,10 +1584,10 @@ int NullMechanicGirl(short SpriteNum) return 0; } -int MechanicGirlDrill(short SpriteNum) +int MechanicGirlDrill(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); @@ -1584,11 +1601,12 @@ int MechanicGirlDrill(short SpriteNum) return 0; } -int MechanicGirlPain(short SpriteNum) +int MechanicGirlPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullMechanicGirl(SpriteNum); + NullMechanicGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(SpriteNum,s_MechanicGirlStand); @@ -1699,9 +1717,10 @@ SetupSailorGirl(short SpriteNum) return 0; } -int DoSailorGirl(short SpriteNum) +int DoSailorGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -1746,15 +1765,16 @@ int DoSailorGirl(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } -int NullSailorGirl(short SpriteNum) +int NullSailorGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; static short alreadythrew = 0; @@ -1796,9 +1816,10 @@ int NullSailorGirl(short SpriteNum) return 0; } -int SailorGirlThrow(short SpriteNum) +int SailorGirlThrow(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); @@ -1813,11 +1834,11 @@ int SailorGirlThrow(short SpriteNum) return 0; } -int SailorGirlPain(short SpriteNum) +int SailorGirlPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - NullSailorGirl(SpriteNum); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + NullSailorGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(SpriteNum,s_SailorGirlStand); @@ -1911,9 +1932,10 @@ SetupPruneGirl(short SpriteNum) return 0; } -int DoPruneGirl(short SpriteNum) +int DoPruneGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -1970,15 +1992,16 @@ int DoPruneGirl(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } -int NullPruneGirl(short SpriteNum) +int NullPruneGirl(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; @@ -2014,9 +2037,10 @@ int NullPruneGirl(short SpriteNum) return 0; } -int PruneGirlUzi(short SpriteNum) +int PruneGirlUzi(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); @@ -2031,11 +2055,12 @@ int PruneGirlUzi(short SpriteNum) return 0; } -int PruneGirlPain(short SpriteNum) +int PruneGirlPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullPruneGirl(SpriteNum); + NullPruneGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(SpriteNum,s_PruneGirlStand); @@ -2048,51 +2073,39 @@ int PruneGirlPain(short SpriteNum) static saveable_code saveable_miscactr_code[] = { - SAVE_CODE(SetupToiletGirl), SAVE_CODE(DoToiletGirl), SAVE_CODE(NullToiletGirl), SAVE_CODE(ToiletGirlUzi), SAVE_CODE(ToiletGirlPain), - SAVE_CODE(SetupWashGirl), SAVE_CODE(DoWashGirl), SAVE_CODE(NullWashGirl), SAVE_CODE(WashGirlUzi), SAVE_CODE(WashGirlPain), - SAVE_CODE(SetupTrashCan), SAVE_CODE(DoTrashCan), SAVE_CODE(TrashCanPain), - SAVE_CODE(SetupPachinkoLight), SAVE_CODE(PachinkoLightOperate), - SAVE_CODE(SetupPachinko1), - SAVE_CODE(SetupPachinko2), - SAVE_CODE(SetupPachinko3), - SAVE_CODE(SetupPachinko4), SAVE_CODE(PachinkoCheckWin), SAVE_CODE(Pachinko1Operate), - SAVE_CODE(SetupCarGirl), SAVE_CODE(DoCarGirl), SAVE_CODE(NullCarGirl), SAVE_CODE(CarGirlUzi), SAVE_CODE(CarGirlPain), - SAVE_CODE(SetupMechanicGirl), SAVE_CODE(DoMechanicGirl), SAVE_CODE(NullMechanicGirl), SAVE_CODE(MechanicGirlDrill), SAVE_CODE(MechanicGirlPain), - SAVE_CODE(SetupSailorGirl), SAVE_CODE(DoSailorGirl), SAVE_CODE(NullSailorGirl), SAVE_CODE(SailorGirlThrow), SAVE_CODE(SailorGirlPain), - SAVE_CODE(SetupPruneGirl), SAVE_CODE(DoPruneGirl), SAVE_CODE(NullPruneGirl), SAVE_CODE(PruneGirlUzi), diff --git a/source/games/sw/src/morph.cpp b/source/games/sw/src/morph.cpp index 4a6ab5585..f24265855 100644 --- a/source/games/sw/src/morph.cpp +++ b/source/games/sw/src/morph.cpp @@ -568,15 +568,9 @@ SpikeFloor(SECTOR_OBJECTp sop) static saveable_code saveable_morph_code[] = { - SAVE_CODE(DoSectorObjectSetScale), - SAVE_CODE(DoSOevent), SAVE_CODE(ScaleSectorObject), - SAVE_CODE(ScaleRandomPoint), SAVE_CODE(MorphTornado), SAVE_CODE(MorphFloor), - SAVE_CODE(SOBJ_AlignFloorToPoint), - SAVE_CODE(SOBJ_AlignCeilingToPoint), - SAVE_CODE(SOBJ_AlignFloorCeilingToPoint), SAVE_CODE(SpikeFloor), }; diff --git a/source/games/sw/src/ninja.cpp b/source/games/sw/src/ninja.cpp index 74b2a4d41..4e6ce93ed 100644 --- a/source/games/sw/src/ninja.cpp +++ b/source/games/sw/src/ninja.cpp @@ -1405,7 +1405,6 @@ STATEp sg_NinjaUzi[] = #define NINJA_HARI_KARI_WAIT_RATE 200 #define NINJA_HARI_KARI_FALL_RATE 16 -ANIMATOR DoHariKariBlood; ANIMATOR DoNinjaSpecial; STATE s_NinjaHariKari[] = @@ -1810,13 +1809,6 @@ ACTOR_ACTION_SET PlayerNinjaActionSet = sg_PlayerNinjaSwim }; -int -DoHariKariBlood(short SpriteNum) -{ - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - return 0; -} /* @@ -1947,9 +1939,10 @@ SetupNinja(short SpriteNum) } int -DoNinjaHariKari(short SpriteNum) +DoNinjaHariKari(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; short cnt,i; @@ -1977,9 +1970,10 @@ DoNinjaHariKari(short SpriteNum) } int -DoNinjaGrabThroat(short SpriteNum) +DoNinjaGrabThroat(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; if ((u->WaitTics -= ACTORMOVETICS) <= 0) @@ -2003,7 +1997,7 @@ DoNinjaGrabThroat(short SpriteNum) ChangeState(SpriteNum, u->StateEnd); sp->xvel = 0; //u->jump_speed = -300; - //DoActorBeginJump(SpriteNum); + //DoActorBeginJump(actor); PlaySound(DIGI_NINJASCREAM, sp, v3df_follow); } @@ -2017,9 +2011,10 @@ DoNinjaGrabThroat(short SpriteNum) */ int -DoNinjaMove(short SpriteNum) +DoNinjaMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags2, SPR2_DYING)) { @@ -2034,21 +2029,21 @@ DoNinjaMove(short SpriteNum) if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING) && !TEST(u->Flags, SPR_CLIMBING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else if (TEST(u->Flags, SPR_FALLING)) - DoActorFall(SpriteNum); + DoActorFall(actor); } // sliding if (TEST(u->Flags, SPR_SLIDING) && !TEST(u->Flags, SPR_CLIMBING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // !AIC - do track or call current action function - such as DoActorMoveCloser() if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else { - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); } // stay on floor unless doing certain things @@ -2058,15 +2053,16 @@ DoNinjaMove(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } int -NinjaJumpActionFunc(short SpriteNum) +NinjaJumpActionFunc(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int nx, ny; @@ -2082,7 +2078,7 @@ NinjaJumpActionFunc(short SpriteNum) if (!TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) { - InitActorDecide(SpriteNum); + InitActorDecide(actor); } return 0; @@ -2096,29 +2092,31 @@ NinjaJumpActionFunc(short SpriteNum) */ int -NullNinja(short SpriteNum) +NullNinja(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (u->WaitTics > 0) u->WaitTics -= ACTORMOVETICS; if (TEST(u->Flags, SPR_SLIDING) && !TEST(u->Flags, SPR_CLIMBING) && !TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (!TEST(u->Flags, SPR_CLIMBING) && !TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoNinjaPain(short SpriteNum) +int DoNinjaPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullNinja(SpriteNum); + NullNinja(actor); if (TEST(u->Flags2, SPR2_DYING)) { @@ -2130,16 +2128,17 @@ int DoNinjaPain(short SpriteNum) } if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } -int DoNinjaSpecial(short SpriteNum) +int DoNinjaSpecial(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - + if (u->spal == PALETTE_PLAYER5) { RESET(sp->cstat,CSTAT_SPRITE_TRANSLUCENT); @@ -2150,20 +2149,23 @@ int DoNinjaSpecial(short SpriteNum) return 0; } -int CheckFire(short SpriteNum) +int CheckFire(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (!CanSeePlayer(SpriteNum)) - InitActorDuck(SpriteNum); + InitActorDuck(actor); return 0; } int -DoNinjaCeiling(short SpriteNum) +DoNinjaCeiling(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -2509,8 +2511,6 @@ SpawnPlayerUnderSprite(PLAYERp pp) static saveable_code saveable_ninja_code[] = { - SAVE_CODE(DoHariKariBlood), - SAVE_CODE(SetupNinja), SAVE_CODE(DoNinjaHariKari), SAVE_CODE(DoNinjaGrabThroat), SAVE_CODE(DoNinjaMove), diff --git a/source/games/sw/src/panel.cpp b/source/games/sw/src/panel.cpp index d2db008c5..45f8c7829 100644 --- a/source/games/sw/src/panel.cpp +++ b/source/games/sw/src/panel.cpp @@ -97,7 +97,6 @@ char UziRecoilYadj = 0; extern short screenpeek; -ANIMATOR NullAnimator; pANIMATOR pNullAnimator; int InitStar(PLAYERp); int ChangeWeapon(PLAYERp); @@ -105,7 +104,7 @@ int ChangeWeapon(PLAYERp); ANIMATOR InitFire; int -NullAnimator(short) +NullAnimator(DSWActor*) { return 0; } @@ -433,7 +432,6 @@ void PlayerUpdateArmor(PLAYERp pp, short value) int WeaponOperate(PLAYERp pp) { short weapon; - int DoPlayerSpriteReset(short SpriteNum); USERp u = User[pp->PlayerSprite].Data(); diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp index d1fb09cde..6aebb6688 100644 --- a/source/games/sw/src/player.cpp +++ b/source/games/sw/src/player.cpp @@ -197,7 +197,7 @@ extern short target_ang; #if 1 #define PLAYER_NINJA_RATE 14 -int DoFootPrints(short SpriteNum); +int DoFootPrints(DSWActor* actor); STATE s_PlayerNinjaRun[5][6] = { @@ -360,7 +360,7 @@ STATEp sg_PlayerNinjaStand[] = #define PLAYER_NINJA_STAR_RATE 12 extern STATEp sg_NinjaRun[]; -int DoPlayerSpriteReset(short SpriteNum); +int DoPlayerSpriteReset(DSWActor* actor); #if 0 STATE s_PlayerNinjaThrow[5][4] = @@ -1077,9 +1077,10 @@ DoPlayerSpriteThrow(PLAYERp pp) } int -DoPlayerSpriteReset(short SpriteNum) +DoPlayerSpriteReset(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; PLAYERp pp; if (!u->PlayerP) @@ -1309,7 +1310,7 @@ DoPlayerTeleportToSprite(PLAYERp pp, SPRITEp sp) pp->posz = pp->oposz = sp->z - PLAYER_HEIGHT; - COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + updatesector(pp->posx, pp->posy, &pp->cursectnum); //pp->lastcursectnum = pp->cursectnum; SET(pp->Flags2, PF2_TELEPORTED); } @@ -1320,7 +1321,7 @@ DoPlayerTeleportToOffset(PLAYERp pp) pp->oposx = pp->oldposx = pp->posx; pp->oposy = pp->oldposy = pp->posy; - COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + updatesector(pp->posx, pp->posy, &pp->cursectnum); //pp->lastcursectnum = pp->cursectnum; SET(pp->Flags2, PF2_TELEPORTED); } @@ -1719,7 +1720,7 @@ DoPlayerBeginRecoil(PLAYERp pp, short pix_amt) pp->recoil_amt = pix_amt; pp->recoil_speed = 80; pp->recoil_ndx = 0; - pp->recoil_horizoff = 0; + pp->recoil_ohorizoff = pp->recoil_horizoff = 0; } void @@ -1731,11 +1732,12 @@ DoPlayerRecoil(PLAYERp pp) if (bsin(pp->recoil_ndx) < 0) { RESET(pp->Flags, PF_RECOIL); - pp->recoil_horizoff = 0; + pp->recoil_ohorizoff = pp->recoil_horizoff = 0; return; } // move pp->q16horiz up and down + pp->recoil_ohorizoff = pp->recoil_horizoff; pp->recoil_horizoff = pp->recoil_amt * bsin(pp->recoil_ndx, 2); } @@ -1935,7 +1937,9 @@ DoPlayerZrange(PLAYERp pp) // for an entire box, NOT just a point. -Useful for clipping bakcstat = pp->SpriteP->cstat; RESET(pp->SpriteP->cstat, CSTAT_SPRITE_BLOCK); - FAFgetzrange(pp->posx, pp->posy, pp->posz + Z(8), pp->cursectnum, &pp->hiz, &ceilhit, &pp->loz, &florhit, ((int)pp->SpriteP->clipdist<<2) - GETZRANGE_CLIP_ADJ, CLIPMASK_PLAYER); + vec3_t pos = pp->pos; + pos.z += Z(8); + FAFgetzrange(pos, pp->cursectnum, &pp->hiz, &ceilhit, &pp->loz, &florhit, ((int)pp->SpriteP->clipdist<<2) - GETZRANGE_CLIP_ADJ, CLIPMASK_PLAYER); pp->SpriteP->cstat = bakcstat; // 16384+sector (sector first touched) or @@ -2138,7 +2142,7 @@ DoPlayerMove(PLAYERp pp) if (TEST(pp->Flags, PF_CLIP_CHEAT)) { - short sectnum=pp->cursectnum; + int sectnum = pp->cursectnum; if (interpolate_ride) { pp->oposx = pp->posx; @@ -2146,7 +2150,7 @@ DoPlayerMove(PLAYERp pp) } pp->posx += pp->xvect >> 14; pp->posy += pp->yvect >> 14; - COVERupdatesector(pp->posx, pp->posy, §num); + updatesector(pp->posx, pp->posy, §num); if (sectnum != -1) pp->cursectnum = sectnum; } @@ -2174,7 +2178,7 @@ DoPlayerMove(PLAYERp pp) save_cstat = pp->SpriteP->cstat; RESET(pp->SpriteP->cstat, CSTAT_SPRITE_BLOCK); - COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + updatesector(pp->posx, pp->posy, &pp->cursectnum); clipmove(&pp->pos, &pp->cursectnum, pp->xvect, pp->yvect, ((int)pp->SpriteP->clipdist<<2), pp->ceiling_dist, pp->floor_dist, CLIPMASK_PLAYER); pp->SpriteP->cstat = save_cstat; PlayerCheckValidMove(pp); @@ -2259,7 +2263,7 @@ DoPlayerMove(PLAYERp pp) void DoPlayerSectorUpdatePreMove(PLAYERp pp) { - short sectnum = pp->cursectnum; + int sectnum = pp->cursectnum; if (sectnum < 0) return; @@ -2270,7 +2274,7 @@ DoPlayerSectorUpdatePreMove(PLAYERp pp) if (sectnum < 0) { sectnum = pp->cursectnum; - COVERupdatesector(pp->posx, pp->posy, §num); + updatesector(pp->posx, pp->posy, §num); } ASSERT(sectnum >= 0); } @@ -2280,7 +2284,7 @@ DoPlayerSectorUpdatePreMove(PLAYERp pp) if (sectnum < 0) { sectnum = pp->cursectnum; - COVERupdatesector(pp->posx, pp->posy, §num); + updatesector(pp->posx, pp->posy, §num); } ASSERT(sectnum >= 0); } @@ -2423,7 +2427,9 @@ DoPlayerMoveBoat(PLAYERp pp) pp->cursectnum = pp->sop->op_main_sector; // for speed floor_dist = labs(z - pp->sop->floor_loz); - clipmove_old(&pp->posx, &pp->posy, &z, &pp->cursectnum, pp->xvect, pp->yvect, (int)pp->sop->clipdist, Z(4), floor_dist, CLIPMASK_PLAYER); + vec3_t clippos = { pp->posx, pp->posy, z }; + clipmove_old(&clippos, &pp->cursectnum, pp->xvect, pp->yvect, (int)pp->sop->clipdist, Z(4), floor_dist, CLIPMASK_PLAYER); + pp->pos.vec2 = clippos.vec2; OperateSectorObject(pp->sop, pp->angle.ang.asbuild(), pp->posx, pp->posy); pp->cursectnum = save_sectnum; // for speed @@ -2620,7 +2626,9 @@ DriveCrush(PLAYERp pp, int *x, int *y) StatIterator it2(STAT_ENEMY); while ((i = it2.NextIndex()) >= 0) { + auto actor = &swActors[i]; sp = &sprite[i]; + auto u = User[i].Data(); if (testpointinquad(sp->x, sp->y, x, y)) { @@ -2632,7 +2640,7 @@ DriveCrush(PLAYERp pp, int *x, int *y) if (vel < 9000) { DoActorBeginSlide(i, getangle(pp->xvect, pp->yvect), vel/8, 5); - if (DoActorSlide(i)) + if (DoActorSlide(actor)) continue; } @@ -2891,9 +2899,15 @@ DoPlayerMoveVehicle(PLAYERp pp) save_cstat = pp->SpriteP->cstat; RESET(pp->SpriteP->cstat, CSTAT_SPRITE_BLOCK); if (pp->sop->clipdist) - u->ret = clipmove_old(&pp->posx, &pp->posy, &z, &pp->cursectnum, pp->xvect, pp->yvect, (int)pp->sop->clipdist, Z(4), floor_dist, CLIPMASK_PLAYER); + { + vec3_t clippos = { pp->posx, pp->posy, z }; + u->ret = clipmove(&clippos, &pp->cursectnum, pp->xvect, pp->yvect, (int)pp->sop->clipdist, Z(4), floor_dist, CLIPMASK_PLAYER); + pp->pos.vec2 = clippos.vec2; + } else + { u->ret = MultiClipMove(pp, z, floor_dist); + } pp->SpriteP->cstat = save_cstat; //SetupDriveCrush(pp, x, y); @@ -3175,7 +3189,7 @@ void StackedWaterSplash(PLAYERp pp) { if (FAF_ConnectArea(pp->cursectnum)) { - short sectnum = pp->cursectnum; + int sectnum = pp->cursectnum; updatesectorz(pp->posx, pp->posy, SPRITEp_BOS(pp->SpriteP), §num); @@ -4083,7 +4097,7 @@ PlayerCanDiveNoWarp(PLAYERp pp) { if (FAF_ConnectArea(pp->cursectnum)) { - short sectnum = pp->cursectnum; + int sectnum = pp->cursectnum; updatesectorz(pp->posx, pp->posy, SPRITEp_BOS(pp->SpriteP), §num); @@ -4716,7 +4730,7 @@ DoPlayerDive(PLAYERp pp) { if (pp->posz < sector[pp->cursectnum].ceilingz + Z(10)) { - short sectnum = pp->cursectnum; + int sectnum = pp->cursectnum; // check for sector above to see if it is an underwater sector also updatesectorz(pp->posx, pp->posy, sector[pp->cursectnum].ceilingz - Z(8), §num); @@ -5167,12 +5181,12 @@ void FindMainSector(SECTOR_OBJECTp sop) // set it to something valid sop->op_main_sector = 0; - //COVERupdatesector(sx, sy, &sop->op_main_sector); + //updatesector(sx, sy, &sop->op_main_sector); //updatesectorz(sx, sy, sop->zmid - Z(8), &sop->op_main_sector); updatesectorz(sx, sy, sop->zmid, &sop->op_main_sector); - //COVERupdatesector(sx, sy, &sop->op_main_sector); + //updatesector(sx, sy, &sop->op_main_sector); ////DSPRINTF(ds,"main sector %d, zmid %d",sop->op_main_sector, sop->zmid); //MONO_PRINT(ds); @@ -5256,7 +5270,7 @@ DoPlayerBeginOperate(PLAYERp pp) pp->angle.oang = pp->angle.ang = buildang(sop->ang); pp->posx = sop->xmid; pp->posy = sop->ymid; - COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + updatesector(pp->posx, pp->posy, &pp->cursectnum); getzsofslope(pp->cursectnum, pp->posx, pp->posy, &cz, &fz); pp->posz = fz - PLAYER_HEIGHT; @@ -5343,7 +5357,7 @@ DoPlayerBeginRemoteOperate(PLAYERp pp, SECTOR_OBJECTp sop) pp->angle.oang = pp->angle.ang = buildang(sop->ang); pp->posx = sop->xmid; pp->posy = sop->ymid; - COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + updatesector(pp->posx, pp->posy, &pp->cursectnum); getzsofslope(pp->cursectnum, pp->posx, pp->posy, &cz, &fz); pp->posz = fz - PLAYER_HEIGHT; @@ -6024,12 +6038,12 @@ DoPlayerBeginDie(PLAYERp pp) void DoPlayerDeathHoriz(PLAYERp pp, short target, short speed) { - if ((pp->horizon.horiz.asq16() - IntToFixed(target)) > FRACUNIT) + if ((pp->horizon.horiz.asbuild() - target) > 1) { pp->horizon.addadjustment(-speed); } - if ((IntToFixed(target) - pp->horizon.horiz.asq16()) > FRACUNIT) + if ((target - pp->horizon.horiz.asbuild()) > 1) { pp->horizon.addadjustment(speed); } @@ -6128,7 +6142,7 @@ void DoPlayerDeathFollowKiller(PLAYERp pp) if (FAFcansee(kp->x, kp->y, SPRITEp_TOS(kp), kp->sectnum, pp->posx, pp->posy, pp->posz, pp->cursectnum)) { - pp->angle.addadjustment(getincanglebam(pp->angle.ang, bvectangbam(kp->x - pp->posx, kp->y - pp->posy)).signedbuild() >> 4); + pp->angle.addadjustment(getincanglebam(pp->angle.ang, bvectangbam(kp->x - pp->posx, kp->y - pp->posy)) >> 4); } } } @@ -6297,7 +6311,7 @@ void DoPlayerDeathMoveHead(PLAYERp pp) SPRITEp sp = pp->SpriteP; USERp u = User[pp->PlayerSprite].Data(); int dax,day; - short sectnum; + int sectnum; dax = MOVEx(u->slide_vel, u->slide_ang); day = MOVEy(u->slide_vel, u->slide_ang); @@ -6354,7 +6368,7 @@ void DoPlayerDeathMoveHead(PLAYERp pp) // try to stay in valid area - death sometimes throws you out of the map sectnum = pp->cursectnum; - COVERupdatesector(pp->posx, pp->posy, §num); + updatesector(pp->posx, pp->posy, §num); if (sectnum < 0) { pp->cursectnum = pp->lv_sectnum; @@ -6570,7 +6584,7 @@ void DoPlayerDeathExplode(PLAYERp pp) else { // special line for amoeba - //COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + //updatesector(pp->posx, pp->posy, &pp->cursectnum); DoPlayerDeathCheckKick(pp); DoPlayerDeathHurl(pp); @@ -6770,6 +6784,7 @@ PlayerStateControl(int16_t SpriteNum) return; // Convienience var + auto actor = &swActors[SpriteNum]; u = User[SpriteNum].Data(); if (u == nullptr) @@ -6792,7 +6807,7 @@ PlayerStateControl(int16_t SpriteNum) while (TEST(u->State->Tics, SF_QUICK_CALL)) { // Call it once and go to the next state - (*u->State->Animator)(SpriteNum); + (*u->State->Animator)(actor); // if still on the same QUICK_CALL should you // go to the next state. @@ -6816,7 +6831,7 @@ PlayerStateControl(int16_t SpriteNum) // Call the correct animator if (TEST(u->State->Tics, SF_PLAYER_FUNC)) if (u->State->Animator) - (*u->State->Animator)(SpriteNum); + (*u->State->Animator)(actor); return; } @@ -7473,9 +7488,10 @@ InitMultiPlayerInfo(void) // If player stepped in something gooey, track it all over the place. int -DoFootPrints(short SpriteNum) +DoFootPrints(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (u->PlayerP) { @@ -7516,8 +7532,6 @@ void CheckFootPrints(PLAYERp pp) static saveable_code saveable_player_code[] = { SAVE_CODE(DoPlayerSlide), - //SAVE_CODE(DoPlayerBeginSwim), - //SAVE_CODE(DoPlayerSwim), SAVE_CODE(DoPlayerWade), SAVE_CODE(DoPlayerBeginWade), SAVE_CODE(DoPlayerBeginCrawl), @@ -7534,11 +7548,8 @@ static saveable_code saveable_player_code[] = SAVE_CODE(DoPlayerBeginClimb), SAVE_CODE(DoPlayerClimb), SAVE_CODE(DoPlayerBeginDie), - //SAVE_CODE(DoPlayerDie), - //SAVE_CODE(DoPlayerBeginOperateBoat), SAVE_CODE(DoPlayerBeginOperateVehicle), SAVE_CODE(DoPlayerBeginOperate), - //SAVE_CODE(DoPlayerOperateBoat), SAVE_CODE(DoPlayerOperateVehicle), SAVE_CODE(DoPlayerOperateTurret), SAVE_CODE(DoPlayerBeginDive), @@ -7639,6 +7650,7 @@ DEFINE_FIELD_X(SWPlayer, PLAYERstruct, recoil_amt) DEFINE_FIELD_X(SWPlayer, PLAYERstruct, recoil_speed) DEFINE_FIELD_X(SWPlayer, PLAYERstruct, recoil_ndx) DEFINE_FIELD_X(SWPlayer, PLAYERstruct, recoil_horizoff) +DEFINE_FIELD_X(SWPlayer, PLAYERstruct, recoil_ohorizoff) DEFINE_FIELD_X(SWPlayer, PLAYERstruct, oldposx) DEFINE_FIELD_X(SWPlayer, PLAYERstruct, oldposy) DEFINE_FIELD_X(SWPlayer, PLAYERstruct, oldposz) diff --git a/source/games/sw/src/quake.cpp b/source/games/sw/src/quake.cpp index a6561147a..c7e631d6e 100644 --- a/source/games/sw/src/quake.cpp +++ b/source/games/sw/src/quake.cpp @@ -342,33 +342,4 @@ SetSumoFartQuake(int16_t SpriteNum) } -#include "saveable.h" - -static saveable_code saveable_quake_code[] = -{ - SAVE_CODE(CopyQuakeSpotToOn), - SAVE_CODE(DoQuakeMatch), - SAVE_CODE(ProcessQuakeOn), - SAVE_CODE(ProcessQuakeSpot), - SAVE_CODE(QuakeViewChange), - SAVE_CODE(SpawnQuake), - SAVE_CODE(SetQuake), - SAVE_CODE(SetExpQuake), - SAVE_CODE(SetGunQuake), - SAVE_CODE(SetPlayerQuake), - SAVE_CODE(SetNuclearQuake), - SAVE_CODE(SetSumoQuake), - SAVE_CODE(SetSumoFartQuake), -}; - -saveable_module saveable_quake = -{ - // code - saveable_quake_code, - SIZ(saveable_quake_code), - - // data - nullptr,0 -}; - END_SW_NS diff --git a/source/games/sw/src/ripper.cpp b/source/games/sw/src/ripper.cpp index e2f7f79a3..684eacb4a 100644 --- a/source/games/sw/src/ripper.cpp +++ b/source/games/sw/src/ripper.cpp @@ -39,7 +39,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS ANIMATOR InitRipperHang; -ANIMATOR DoActorMoveJump; ANIMATOR DoRipperMoveJump; ANIMATOR DoRipperHangJF; ANIMATOR DoRipperQuickJump; @@ -553,7 +552,7 @@ STATEp sg_RipperFall[] = ////////////////////// #define RIPPER_JUMP_ATTACK_RATE 35 -int DoRipperBeginJumpAttack(short SpriteNum); +int DoRipperBeginJumpAttack(DSWActor* actor); STATE s_RipperJumpAttack[5][6] = { @@ -937,10 +936,11 @@ PickJumpMaxSpeed(short SpriteNum, short max_speed) // int -InitRipperHang(short SpriteNum) +InitRipperHang(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int dist; hitdata_t hitinfo = { { 0, 0, 0 }, -2, 0, -2 }; @@ -976,7 +976,7 @@ InitRipperHang(short SpriteNum) if (!Found) { - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } @@ -999,9 +999,10 @@ InitRipperHang(short SpriteNum) } int -DoRipperHang(short SpriteNum) +DoRipperHang(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if ((u->WaitTics -= ACTORMOVETICS) > 0) return 0; @@ -1013,10 +1014,11 @@ DoRipperHang(short SpriteNum) } int -DoRipperMoveHang(short SpriteNum) +DoRipperMoveHang(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx, ny; // Move while jumping @@ -1053,9 +1055,10 @@ DoRipperMoveHang(short SpriteNum) int -DoRipperHangJF(short SpriteNum) +DoRipperHangJF(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { @@ -1067,13 +1070,13 @@ DoRipperHangJF(short SpriteNum) if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - if (DoRipperQuickJump(SpriteNum)) + if (DoRipperQuickJump(actor)) return 0; - InitActorDecide(SpriteNum); + InitActorDecide(actor); } - DoRipperMoveHang(SpriteNum); + DoRipperMoveHang(actor); return 0; @@ -1084,10 +1087,11 @@ DoRipperHangJF(short SpriteNum) // int -DoRipperBeginJumpAttack(short SpriteNum) +DoRipperBeginJumpAttack(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SPRITEp psp = User[SpriteNum]->tgt_sp; short tang; @@ -1119,9 +1123,10 @@ DoRipperBeginJumpAttack(short SpriteNum) } int -DoRipperMoveJump(short SpriteNum) +DoRipperMoveJump(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { @@ -1133,13 +1138,13 @@ DoRipperMoveJump(short SpriteNum) if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - if (DoRipperQuickJump(SpriteNum)) + if (DoRipperQuickJump(actor)) return 0; - InitActorDecide(SpriteNum); + InitActorDecide(actor); } - DoRipperMoveHang(SpriteNum); + DoRipperMoveHang(actor); return 0; } @@ -1148,10 +1153,10 @@ DoRipperMoveJump(short SpriteNum) // int -DoRipperQuickJump(short SpriteNum) +DoRipperQuickJump(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; // Tests to see if ripper is on top of a player/enemy and then immediatly // does another jump @@ -1173,27 +1178,29 @@ DoRipperQuickJump(short SpriteNum) int -NullRipper(short SpriteNum) +NullRipper(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoRipperPain(short SpriteNum) +int DoRipperPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullRipper(SpriteNum); + NullRipper(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } @@ -1216,14 +1223,14 @@ int DoRipperRipHeart(short SpriteNum) return 0; } -// CTW MODIFICATION -//int DoRipperStandHeart(SpriteNum) -int DoRipperStandHeart(short SpriteNum) -// CTW MODIFICATION END -{ - USERp u = User[SpriteNum].Data(); - NullRipper(SpriteNum); +//int DoRipperStandHeart(SpriteNum) +int DoRipperStandHeart(DSWActor* actor) +{ + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + + NullRipper(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) NewStateGroup(SpriteNum, sg_RipperRun); @@ -1282,13 +1289,14 @@ void RipperHatch(short Weapon) } int -DoRipperMove(short SpriteNum) +DoRipperMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (u->scale_speed) { - DoScaleSprite(SpriteNum); + DoScaleSprite(actor); } if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) @@ -1302,21 +1310,21 @@ DoRipperMove(short SpriteNum) // if on a player/enemy sprite jump quickly if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - if (DoRipperQuickJump(SpriteNum)) + if (DoRipperQuickJump(actor)) return 0; KeepActorOnFloor(SpriteNum); } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -1325,10 +1333,6 @@ DoRipperMove(short SpriteNum) static saveable_code saveable_ripper_code[] = { - SAVE_CODE(SetupRipper), - SAVE_CODE(GetJumpHeight), - SAVE_CODE(PickJumpSpeed), - SAVE_CODE(PickJumpMaxSpeed), SAVE_CODE(InitRipperHang), SAVE_CODE(DoRipperHang), @@ -1343,7 +1347,6 @@ static saveable_code saveable_ripper_code[] = SAVE_CODE(DoRipperPain), SAVE_CODE(DoRipperRipHeart), SAVE_CODE(DoRipperStandHeart), - SAVE_CODE(RipperHatch), SAVE_CODE(DoRipperMove), }; diff --git a/source/games/sw/src/ripper2.cpp b/source/games/sw/src/ripper2.cpp index 8b7062d5b..25740829d 100644 --- a/source/games/sw/src/ripper2.cpp +++ b/source/games/sw/src/ripper2.cpp @@ -37,10 +37,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -int DoCheckSwarm(short SpriteNum); - ANIMATOR InitRipper2Hang; -ANIMATOR DoActorMoveJump; ANIMATOR DoRipper2MoveJump; ANIMATOR DoRipper2HangJF; ANIMATOR DoRipper2QuickJump; @@ -610,7 +607,7 @@ STATEp sg_Ripper2Fall[] = ////////////////////// #define RIPPER2_JUMP_ATTACK_RATE 35 -int DoRipper2BeginJumpAttack(short SpriteNum); +int DoRipper2BeginJumpAttack(DSWActor* actor); STATE s_Ripper2JumpAttack[5][6] = { @@ -937,10 +934,11 @@ SetupRipper2(short SpriteNum) // int -InitRipper2Hang(short SpriteNum) +InitRipper2Hang(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int dist; hitdata_t hitinfo = { { 0, 0, 0 }, -2, 0, -2 }; @@ -975,7 +973,7 @@ InitRipper2Hang(short SpriteNum) if (!Found) { - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } @@ -998,9 +996,10 @@ InitRipper2Hang(short SpriteNum) } int -DoRipper2Hang(short SpriteNum) +DoRipper2Hang(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if ((u->WaitTics -= ACTORMOVETICS) > 0) return 0; @@ -1013,10 +1012,11 @@ DoRipper2Hang(short SpriteNum) } int -DoRipper2MoveHang(short SpriteNum) +DoRipper2MoveHang(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int nx, ny; // Move while jumping @@ -1060,9 +1060,10 @@ DoRipper2MoveHang(short SpriteNum) int -DoRipper2HangJF(short SpriteNum) +DoRipper2HangJF(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { @@ -1074,13 +1075,13 @@ DoRipper2HangJF(short SpriteNum) if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - if (DoRipper2QuickJump(SpriteNum)) + if (DoRipper2QuickJump(actor)) return 0; - InitActorDecide(SpriteNum); + InitActorDecide(actor); } - DoRipper2MoveHang(SpriteNum); + DoRipper2MoveHang(actor); return 0; @@ -1091,10 +1092,11 @@ DoRipper2HangJF(short SpriteNum) // int -DoRipper2BeginJumpAttack(short SpriteNum) +DoRipper2BeginJumpAttack(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SPRITEp psp = User[SpriteNum]->tgt_sp; short tang; @@ -1133,9 +1135,10 @@ DoRipper2BeginJumpAttack(short SpriteNum) } int -DoRipper2MoveJump(short SpriteNum) +DoRipper2MoveJump(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { @@ -1147,13 +1150,13 @@ DoRipper2MoveJump(short SpriteNum) if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - if (DoRipper2QuickJump(SpriteNum)) + if (DoRipper2QuickJump(actor)) return 0; - InitActorDecide(SpriteNum); + InitActorDecide(actor); } - DoRipper2MoveHang(SpriteNum); + DoRipper2MoveHang(actor); return 0; } @@ -1162,9 +1165,10 @@ DoRipper2MoveJump(short SpriteNum) // int -DoRipper2QuickJump(short SpriteNum) +DoRipper2QuickJump(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; // Tests to see if ripper2 is on top of a player/enemy and then immediatly // does another jump @@ -1187,27 +1191,28 @@ DoRipper2QuickJump(short SpriteNum) int -NullRipper2(short SpriteNum) +NullRipper2(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoRipper2Pain(short SpriteNum) +int DoRipper2Pain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - - NullRipper2(SpriteNum); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + NullRipper2(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } @@ -1227,12 +1232,13 @@ int DoRipper2RipHeart(short SpriteNum) return 0; } -int DoRipper2StandHeart(short SpriteNum) +int DoRipper2StandHeart(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - NullRipper2(SpriteNum); + NullRipper2(actor); if (!SoundValidAndActive(sp, CHAN_RipHeart)) PlaySound(DIGI_RIPPER2HEARTOUT, sp, v3df_none, CHAN_RipHeart); @@ -1297,17 +1303,18 @@ void Ripper2Hatch(short Weapon) } int -DoRipper2Move(short SpriteNum) +DoRipper2Move(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (sp->hitag == TAG_SWARMSPOT && sp->lotag == 1) - DoCheckSwarm(SpriteNum); + DoCheckSwarm(actor); if (u->scale_speed) { - DoScaleSprite(SpriteNum); + DoScaleSprite(actor); } if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) @@ -1321,39 +1328,43 @@ DoRipper2Move(short SpriteNum) // if on a player/enemy sprite jump quickly if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { - if (DoRipper2QuickJump(SpriteNum)) + if (DoRipper2QuickJump(actor)) return 0; KeepActorOnFloor(SpriteNum); } if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int InitRipper2Charge(short SpriteNum) +int InitRipper2Charge(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; DoActorSetSpeed(SpriteNum, FAST_SPEED); - InitActorMoveCloser(SpriteNum); + InitActorMoveCloser(actor); NewStateGroup(SpriteNum, sg_Ripper2RunFast); return 0; } -int ChestRipper2(short SpriteNum) +int ChestRipper2(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; PlaySound(DIGI_RIPPER2CHEST, sp, v3df_follow); @@ -1366,8 +1377,6 @@ int ChestRipper2(short SpriteNum) static saveable_code saveable_ripper2_code[] = { - SAVE_CODE(SetupRipper2), - SAVE_CODE(InitRipper2Hang), SAVE_CODE(DoRipper2Hang), SAVE_CODE(DoRipper2MoveHang), diff --git a/source/games/sw/src/rooms.cpp b/source/games/sw/src/rooms.cpp index 3618c6da5..17ac9118a 100644 --- a/source/games/sw/src/rooms.cpp +++ b/source/games/sw/src/rooms.cpp @@ -54,12 +54,6 @@ SAVE save; bool FAF_DebugView = false; -void COVERupdatesector(int32_t x, int32_t y, int16_t* newsector) -{ - // ASSERT(*newsector>=0 && *newsector floorportals; TArray ceilingportals; - FixedBitArray floordone, ceilingdone; + BitArray floordone(numsectors), ceilingdone(numsectors); for (int i = 0; i < numsectors; i++) { diff --git a/source/games/sw/src/rotator.cpp b/source/games/sw/src/rotator.cpp index 3802628e4..407d56701 100644 --- a/source/games/sw/src/rotator.cpp +++ b/source/games/sw/src/rotator.cpp @@ -277,7 +277,7 @@ void DoRotatorSetInterp(short SpriteNum) StartInterpolation(w, Interp_Wall_Y); uint16_t const nextwall = wall[w].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) { StartInterpolation(wall[nextwall].point2, Interp_Wall_X); StartInterpolation(wall[nextwall].point2, Interp_Wall_Y); @@ -300,7 +300,7 @@ void DoRotatorStopInterp(short SpriteNum) StopInterpolation(w, Interp_Wall_Y); uint16_t const nextwall = wall[w].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) { StopInterpolation(wall[nextwall].point2, Interp_Wall_X); StopInterpolation(wall[nextwall].point2, Interp_Wall_Y); @@ -433,10 +433,10 @@ int DoRotatorMove(short SpriteNum) return 0; } -int DoRotator(short SpriteNum) +int DoRotator(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - SPRITEp sp = u->SpriteP; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; // could move this inside sprite control DoRotatorMove(SpriteNum); @@ -448,16 +448,6 @@ int DoRotator(short SpriteNum) static saveable_code saveable_rotator_code[] = { - SAVE_CODE(ReverseRotator), - SAVE_CODE(RotatorSwitch), - SAVE_CODE(SetRotatorActive), - SAVE_CODE(SetRotatorInactive), - SAVE_CODE(DoRotatorOperate), - SAVE_CODE(DoRotatorMatch), - SAVE_CODE(TestRotatorMatchActive), - SAVE_CODE(DoRotatorSetInterp), - SAVE_CODE(DoRotatorStopInterp), - SAVE_CODE(DoRotatorMove), SAVE_CODE(DoRotator) }; diff --git a/source/games/sw/src/save.cpp b/source/games/sw/src/save.cpp index b18997f66..7ff3308de 100644 --- a/source/games/sw/src/save.cpp +++ b/source/games/sw/src/save.cpp @@ -96,19 +96,8 @@ extern STATE s_NotRestored[]; FSerializer& Serialize(FSerializer& arc, const char* keyname, savedcodesym& w, savedcodesym* def) { - static savedcodesym nul; - if (!def) - { - def = &nul; - if (arc.isReading()) w = {}; - } - - if (arc.BeginObject(keyname)) - { - arc("module", w.module, def->module) - ("index", w.index, def->index) - .EndObject(); - } + if (arc.isWriting() && w.name.IsEmpty()) return arc; + arc(keyname, w.name); return arc; } @@ -120,18 +109,11 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, savedcodesym& w, s FSerializer& Serialize(FSerializer& arc, const char* keyname, saveddatasym& w, saveddatasym* def) { - static saveddatasym nul; - if (!def) + if (arc.isWriting() && w.name.IsEmpty()) return arc; + if (arc.BeginObject(keyname)) { - def = &nul; - if (arc.isReading()) w = {}; - } - - if (arc.BeginObject(keyname)) - { - arc("module", w.module, def->module) - ("index", w.index, def->index) - ("offset", w.offset, def->offset) + arc("name", w.name) + ("offset", w.offset) .EndObject(); } return arc; @@ -413,7 +395,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, REMOTE_CONTROL& w, arc("cursectnum", w.cursectnum) ("lastcursectnum", w.lastcursectnum) ("pang", w.pang) - ("filler", w.filler) ("xvect", w.xvect) ("yvect", w.yvect) ("slide_xvect", w.slide_xvect) @@ -510,6 +491,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PLAYERstruct& w, P ("recoil_speed", w.recoil_speed) ("recoil_ndx", w.recoil_ndx) ("recoil_horizoff", w.recoil_horizoff) + ("recoil_ohorizoff", w.recoil_ohorizoff) ("oldposx", w.oldposx) ("oldposy", w.oldposy) ("oldposz", w.oldposz) @@ -819,24 +801,24 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, SECT_USER& w, SECT void SerializeSectUser(FSerializer& arc) { - FixedBitArray hitlist; + BitArray hitlist(numsectors); if (arc.isWriting()) { - for (int i = 0; i < MAXSECTORS; i++) + for (int i = 0; i < numsectors; i++) { hitlist.Set(i, !!SectUser[i].Data()); } } else { - for (int i = 0; i < MAXSECTORS; i++) + for (int i = 0; i < numsectors; i++) { SectUser[i].Clear(); } } - arc("sectusermap", hitlist); - arc.SparseArray("sectuser", SectUser, MAXSECTORS, hitlist); + arc.SerializeMemory("sectusermap", hitlist.Storage().Data(), hitlist.Storage().Size()); + arc.SparseArray("sectuser", SectUser, numsectors, hitlist); } //--------------------------------------------------------------------------- diff --git a/source/games/sw/src/saveable.cpp b/source/games/sw/src/saveable.cpp index be891730e..f2284a054 100644 --- a/source/games/sw/src/saveable.cpp +++ b/source/games/sw/src/saveable.cpp @@ -36,8 +36,6 @@ void Saveable_Init(void) { if (saveablemodules.Size() > 0) return; - Saveable_Init_Dynamic(); - #define MODULE(x) { \ extern saveable_module saveable_ ## x; \ saveablemodules.Push(&saveable_ ## x); \ @@ -45,7 +43,7 @@ void Saveable_Init(void) MODULE(actor) MODULE(ai) - MODULE(build) + MODULE(ai) // was 'build' but that is not used anywhere anymore. MODULE(bunny) MODULE(coolg) MODULE(coolie) @@ -60,7 +58,6 @@ void Saveable_Init(void) MODULE(ninja) MODULE(panel) MODULE(player) - MODULE(quake) MODULE(ripper) MODULE(ripper2) MODULE(rotator) @@ -87,8 +84,7 @@ int Saveable_FindCodeSym(void *ptr, savedcodesym *sym) if (!ptr) { - sym->module = 0; // module 0 is the "null module" for null pointers - sym->index = 0; + sym->name = ""; return 0; } @@ -96,11 +92,9 @@ int Saveable_FindCodeSym(void *ptr, savedcodesym *sym) { for (i=0; inumcode; i++) { - if (ptr != saveablemodules[m]->code[i]) continue; - - sym->module = 1+m; - sym->index = i; + if (ptr != saveablemodules[m]->code[i].base) continue; + sym->name = saveablemodules[m]->code[i].name; return 0; } } @@ -115,8 +109,7 @@ int Saveable_FindDataSym(void *ptr, saveddatasym *sym) if (!ptr) { - sym->module = 0; - sym->index = 0; + sym->name = ""; sym->offset = 0; return 0; } @@ -129,8 +122,7 @@ int Saveable_FindDataSym(void *ptr, saveddatasym *sym) if (ptr >= (void *)((intptr_t)saveablemodules[m]->data[i].base + saveablemodules[m]->data[i].size)) continue; - sym->module = 1+m; - sym->index = i; + sym->name = saveablemodules[m]->data[i].name; sym->offset = unsigned((intptr_t)ptr - (intptr_t)saveablemodules[m]->data[i].base); return 0; @@ -143,54 +135,48 @@ int Saveable_FindDataSym(void *ptr, saveddatasym *sym) int Saveable_RestoreCodeSym(savedcodesym *sym, void **ptr) { - if (sym->module == 0) + if (sym->name.IsEmpty()) { *ptr = nullptr; return 0; } - if (sym->module > saveablemodules.Size()) + for (auto module : saveablemodules) { - debug_break(); - return -1; + for (unsigned i = 0; i < module->numcode; i++) + { + if (sym->name.Compare(module->code[i].name) == 0) + { + *ptr = module->code[i].base; + return 0; + } + } } - if (sym->index >= saveablemodules[sym->module-1]->numcode) - { - debug_break(); - return -1; - } - - *ptr = saveablemodules[sym->module-1]->code[sym->index]; - - return 0; + I_Error("Unknown code reference '%s' in savegame\n", sym->name.GetChars()); + return -1; } int Saveable_RestoreDataSym(saveddatasym *sym, void **ptr) { - if (sym->module == 0) + if (sym->name.IsEmpty()) { *ptr = nullptr; return 0; } - if (sym->module > saveablemodules.Size()) + for (auto module : saveablemodules) { - debug_break(); - return -1; + for (unsigned i = 0; i < module->numdata; i++) + { + if (sym->name.Compare(module->data[i].name) == 0) + { + *ptr = ((uint8_t*)module->data[i].base) + sym->offset; + return 0; + } + } } - if (sym->index >= saveablemodules[sym->module-1]->numdata) - { - debug_break(); - return -1; - } - if (sym->offset >= saveablemodules[sym->module-1]->data[sym->index].size) - { - debug_break(); - return -1; - } - - *ptr = (void *)((intptr_t)saveablemodules[sym->module-1]->data[sym->index].base + sym->offset); - - return 0; + I_Error("Unknown data reference '%s' in savegame\n", sym->name.GetChars()); + return -1; } + END_SW_NS diff --git a/source/games/sw/src/saveable.h b/source/games/sw/src/saveable.h index 98c47880b..18f5b9643 100644 --- a/source/games/sw/src/saveable.h +++ b/source/games/sw/src/saveable.h @@ -26,13 +26,18 @@ #include "compat.h" -typedef void *saveable_code; +struct saveable_code +{ + void* base; + const char* name; +}; -typedef struct +struct saveable_data { void *base; + const char* name; unsigned int size; -} saveable_data; +}; typedef struct { @@ -49,26 +54,23 @@ constexpr std::enable_if_t::value, size_t> SAVE_SIZEOF(T con return sizeof(obj); } -#define SAVE_CODE(s) (void*)(s) -#define SAVE_DATA(s) { (void*)&(s), (int)SAVE_SIZEOF(s) } +#define SAVE_CODE(s) { (void*)(s), #s } +#define SAVE_DATA(s) { (void*)&(s), #s, (int)SAVE_SIZEOF(s) } #define NUM_SAVEABLE_ITEMS(x) countof(x) typedef struct { - unsigned int module; - unsigned int index; + FString name; } savedcodesym; typedef struct { - unsigned int module; - unsigned int index; + FString name; unsigned int offset; } saveddatasym; void Saveable_Init(void); -void Saveable_Init_Dynamic(void); int Saveable_FindCodeSym(void *ptr, savedcodesym *sym); int Saveable_FindDataSym(void *ptr, saveddatasym *sym); diff --git a/source/games/sw/src/sector.cpp b/source/games/sw/src/sector.cpp index e97be92eb..6d3f29fef 100644 --- a/source/games/sw/src/sector.cpp +++ b/source/games/sw/src/sector.cpp @@ -51,7 +51,7 @@ BEGIN_SW_NS #define LAVAMAXDROPS 32 #define DEFAULT_DOOR_SPEED 800 -int InitFireballTrap(short SpriteNum); +int InitFireballTrap(DSWActor* actor); ANIMATOR DoGrating; void DoPlayerBeginForceJump(PLAYERp); @@ -106,7 +106,7 @@ void SetSectorWallBits(short sectnum, int bit_mask, bool set_sectwall, bool set_ if (set_nextwall) { uint16_t const nextwall = wall[wall_num].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) SET(wall[nextwall].extra, bit_mask); } @@ -151,7 +151,7 @@ static void WallSetupLoop(WALLp wp, int16_t lotag, int16_t extra) { SET(wp->extra, extra); uint16_t const nextwall = wp->nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) SET(wall[nextwall].extra, extra); } @@ -162,7 +162,7 @@ static void WallSetupLoop(WALLp wp, int16_t lotag, int16_t extra) { SET(wall[wall_num].extra, extra); uint16_t const nextwall = wall[wall_num].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) SET(wall[nextwall].extra, extra); } } @@ -180,7 +180,7 @@ WallSetup(void) extern int x_min_bound, y_min_bound, x_max_bound, y_max_bound; - for (wp = wall, i = 0; wp < &wall[numwalls]; i++, wp++) + for (wp = wall, i = 0; i < numwalls; i++, wp++) { if (wp->picnum == FAF_PLACE_MIRROR_PIC) wp->picnum = FAF_MIRROR_PIC; @@ -209,18 +209,28 @@ WallSetup(void) case TAG_WALL_LOOP_OUTER_SECONDARY: { // make sure it's a red wall - ASSERT((uint16_t)wp->nextwall < MAXWALLS); - - WallSetupLoop(wp, TAG_WALL_LOOP_OUTER_SECONDARY, WALLFX_LOOP_OUTER|WALLFX_LOOP_OUTER_SECONDARY); + if (validWallIndex(wp->nextwall)) + { + WallSetupLoop(wp, TAG_WALL_LOOP_OUTER_SECONDARY, WALLFX_LOOP_OUTER | WALLFX_LOOP_OUTER_SECONDARY); + } + else + { + Printf(PRINT_HIGH, "one-sided wall %d in loop setup\n", i); + } break; } case TAG_WALL_LOOP_OUTER: { // make sure it's a red wall - ASSERT((uint16_t)wp->nextwall < MAXWALLS); - - WallSetupLoop(wp, TAG_WALL_LOOP_OUTER, WALLFX_LOOP_OUTER); + if (validWallIndex(wp->nextwall)) + { + WallSetupLoop(wp, TAG_WALL_LOOP_OUTER, WALLFX_LOOP_OUTER); + } + else + { + Printf(PRINT_HIGH, "one-sided wall %d in loop setup\n", i); + } wp->lotag = 0; break; } @@ -1112,9 +1122,10 @@ DoExplodeSector(short match) } -int DoSpawnSpot(short SpriteNum) +int DoSpawnSpot(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if ((u->WaitTics -= synctics) < 0) { @@ -2029,6 +2040,7 @@ int DoTrapMatch(short match) StatIterator it(STAT_TRAP); while ((i = it.NextIndex()) >= 0) { + auto actor = &swActors[i]; sp = &sprite[i]; u = User[i].Data(); @@ -2043,7 +2055,7 @@ int DoTrapMatch(short match) if (u->WaitTics <= 0) { u->WaitTics = 1 * 120; - InitFireballTrap(i); + InitFireballTrap(actor); } } @@ -2055,7 +2067,7 @@ int DoTrapMatch(short match) if (u->WaitTics <= 0) { u->WaitTics = 1 * 120; - InitBoltTrap(i); + InitBoltTrap(actor); } } @@ -2225,56 +2237,7 @@ OperateContinuousTrigger(PLAYERp pp) { case TAG_TRIGGER_MISSILE_TRAP: { -#if 1 DoTrapMatch(sector[pp->cursectnum].hitag); -#else - int i; - SPRITEp sp; - USERp u; - - StatIterator it(STAT_TRAP); - while ((i = it.NextIndex()) >= 0) - { - sp = &sprite[i]; - u = User[i].Data(); - - // if correct type and matches - if (sp->hitag == FIREBALL_TRAP && sp->lotag == sector[pp->cursectnum].hitag) - { - u->WaitTics -= synctics; - - if (u->WaitTics <= 0) - { - u->WaitTics = 1 * 120; - InitFireballTrap(i); - } - } - - // if correct type and matches - if (sp->hitag == BOLT_TRAP && sp->lotag == sector[pp->cursectnum].hitag) - { - u->WaitTics -= synctics; - - if (u->WaitTics <= 0) - { - u->WaitTics = 1 * 120; - InitBoltTrap(i); - } - } - - // if correct type and matches - if (sp->hitag == SPEAR_TRAP && sp->lotag == sector[pp->cursectnum].hitag) - { - u->WaitTics -= synctics; - - if (u->WaitTics <= 0) - { - u->WaitTics = 1 * 120; - InitSpearTrap(i); - } - } - } -#endif break; } @@ -3371,49 +3334,7 @@ int inside(int x, int y, short sectnum) static saveable_code saveable_sector_code[] = { - SAVE_CODE(WallSetupDontMove), - SAVE_CODE(WallSetup), - SAVE_CODE(SectorLiquidSet), - SAVE_CODE(SectorSetup), - SAVE_CODE(DoSpringBoard), - SAVE_CODE(DoSpringBoardDown), - SAVE_CODE(DoSpawnActorTrigger), - SAVE_CODE(OperateSector), - SAVE_CODE(OperateWall), - SAVE_CODE(AnimateSwitch), - SAVE_CODE(SectorExp), - SAVE_CODE(DoExplodeSector), SAVE_CODE(DoSpawnSpot), - SAVE_CODE(DoSpawnSpotsForKill), - SAVE_CODE(DoSpawnSpotsForDamage), - SAVE_CODE(DoSoundSpotMatch), - SAVE_CODE(DoSoundSpotStopSound), - SAVE_CODE(DoStopSoundSpotMatch), - SAVE_CODE(DoSectorObjectKillMatch), - SAVE_CODE(DoDeleteSpriteMatch), - SAVE_CODE(DoChangorMatch), - SAVE_CODE(DoMatchEverything), - SAVE_CODE(DoTrapReset), - SAVE_CODE(DoTrapMatch), - SAVE_CODE(OperateTripTrigger), - SAVE_CODE(OperateContinuousTrigger), - SAVE_CODE(PlayerTakeSectorDamage), - SAVE_CODE(NearThings), - SAVE_CODE(NearTagList), - SAVE_CODE(BuildNearTagList), - SAVE_CODE(DoPlayerGrabStar), - SAVE_CODE(PlayerOperateEnv), - SAVE_CODE(DoSineWaveFloor), - SAVE_CODE(DoSineWaveWall), - SAVE_CODE(DoAnim), - SAVE_CODE(AnimClear), - SAVE_CODE(AnimGetGoal), - SAVE_CODE(AnimDelete), - SAVE_CODE(AnimSet), - SAVE_CODE(AnimSetCallback), - SAVE_CODE(AnimSetVelAdj), - SAVE_CODE(DoPanning), - SAVE_CODE(DoSector), }; saveable_module saveable_sector = diff --git a/source/games/sw/src/serp.cpp b/source/games/sw/src/serp.cpp index e6920c2e1..017fbe382 100644 --- a/source/games/sw/src/serp.cpp +++ b/source/games/sw/src/serp.cpp @@ -753,31 +753,33 @@ SetupSerp(short SpriteNum) return 0; } -int NullSerp(short SpriteNum) +int NullSerp(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); KeepActorOnFloor(SpriteNum); - //DoActorSectorDamage(SpriteNum); + //DoActorSectorDamage(actor); return 0; } -int DoSerpMove(short SpriteNum) +int DoSerpMove(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); // serp ring if (sp->pal != 16) @@ -804,12 +806,14 @@ int DoSerpMove(short SpriteNum) KeepActorOnFloor(SpriteNum); - //DoActorSectorDamage(SpriteNum); + //DoActorSectorDamage(actor); return 0; } -int DoDeathSpecial(short SpriteNum) +int DoDeathSpecial(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; DoMatchEverything(nullptr, sp->lotag, ON); @@ -829,7 +833,6 @@ int DoDeathSpecial(short SpriteNum) static saveable_code saveable_serp_code[] = { - SAVE_CODE(SetupSerp), SAVE_CODE(NullSerp), SAVE_CODE(DoSerpMove), SAVE_CODE(DoDeathSpecial), diff --git a/source/games/sw/src/skel.cpp b/source/games/sw/src/skel.cpp index 85ac5d723..283df6d72 100644 --- a/source/games/sw/src/skel.cpp +++ b/source/games/sw/src/skel.cpp @@ -533,8 +533,10 @@ SetupSkel(short SpriteNum) return 0; } -int DoSkelInitTeleport(short SpriteNum) +int DoSkelInitTeleport(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN); @@ -544,8 +546,10 @@ int DoSkelInitTeleport(short SpriteNum) return 0; } -int DoSkelTeleport(short SpriteNum) +int DoSkelTeleport(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; int x,y; @@ -568,7 +572,7 @@ int DoSkelTeleport(short SpriteNum) sp->y -= 512 + RANDOM_P2(1024); setspritez(SpriteNum, &sp->pos); - //COVERupdatesector(sp->x, sp->y, &sp->sectnum); + //updatesector(sp->x, sp->y, &sp->sectnum); if (sp->sectnum != -1) break; @@ -577,8 +581,10 @@ int DoSkelTeleport(short SpriteNum) return 0; } -int DoSkelTermTeleport(short SpriteNum) +int DoSkelTermTeleport(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; SET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN); @@ -586,46 +592,48 @@ int DoSkelTermTeleport(short SpriteNum) return 0; } -int NullSkel(short SpriteNum) +int NullSkel(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoSkelPain(short SpriteNum) +int DoSkelPain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullSkel(SpriteNum); + NullSkel(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } -int DoSkelMove(short SpriteNum) +int DoSkelMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } @@ -635,7 +643,6 @@ int DoSkelMove(short SpriteNum) static saveable_code saveable_skel_code[] = { - SAVE_CODE(SetupSkel), SAVE_CODE(DoSkelInitTeleport), SAVE_CODE(DoSkelTeleport), SAVE_CODE(DoSkelTermTeleport), diff --git a/source/games/sw/src/skull.cpp b/source/games/sw/src/skull.cpp index 36bb66847..98965fe15 100644 --- a/source/games/sw/src/skull.cpp +++ b/source/games/sw/src/skull.cpp @@ -34,9 +34,9 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -int InitSpriteGrenade(short SpriteNum); +int InitSpriteGrenade(DSWActor* actor); int InitSpriteChemBomb(short SpriteNum); -int InitFlashBomb(short SpriteNum); +int InitFlashBomb(DSWActor* actor); int InitCaltrops(short SpriteNum); int InitPhosphorus(int16_t SpriteNum); bool SpriteOverlapZ(int16_t, int16_t, int); @@ -49,7 +49,7 @@ bool SpriteOverlapZ(int16_t, int16_t, int); extern DAMAGE_DATA DamageData[]; -ANIMATOR DoSkullMove,NullAnimator,DoActorDebris; +ANIMATOR DoSkullMove,DoActorDebris; #define SKULL_RATE 10 ANIMATOR DoSkullWait; @@ -179,7 +179,6 @@ STATEp sg_SkullJump[] = #define SKULL_EXPLODE_RATE 11 ANIMATOR DoSuicide; -ANIMATOR DoDamageTest; ANIMATOR DoSkullSpawnShrap; STATE s_SkullExplode[] = @@ -262,10 +261,11 @@ SetupSkull(short SpriteNum) } int -DoSkullMove(int16_t SpriteNum) +DoSkullMove(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int32_t dax, day, daz; dax = MOVEx(sp->xvel, sp->ang); @@ -279,10 +279,11 @@ DoSkullMove(int16_t SpriteNum) } int -DoSkullBeginDeath(int16_t SpriteNum) +DoSkullBeginDeath(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int16_t i,num_ord=0; //extern short *DamageRadiusSkull; @@ -320,7 +321,7 @@ DoSkullBeginDeath(int16_t SpriteNum) case 3: UpdateSinglePlayKills(SpriteNum); - InitFlashBomb(SpriteNum); + InitFlashBomb(actor); break; case 4: @@ -331,7 +332,7 @@ DoSkullBeginDeath(int16_t SpriteNum) for (i=0; iang = NORM_ANGLE(sp->ang+(i*(2048/num_ord))); - InitSpriteGrenade(SpriteNum); + InitSpriteGrenade(actor); } break; default: @@ -366,14 +367,15 @@ DoSkullBeginDeath(int16_t SpriteNum) } -int DoSkullJump(short SpriteNum) +int DoSkullJump(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (sp->xvel) - DoSkullMove(SpriteNum); + DoSkullMove(actor); else sp->ang = NORM_ANGLE(sp->ang + (64 * ACTORMOVETICS)); @@ -397,7 +399,7 @@ int DoSkullJump(short SpriteNum) SpriteOverlapZ(SpriteNum, short(u->tgt_sp - sprite), Z(32))) { UpdateSinglePlayKills(SpriteNum); - DoSkullBeginDeath(SpriteNum); + DoSkullBeginDeath(actor); return 0; } @@ -405,7 +407,7 @@ int DoSkullJump(short SpriteNum) { sp->z = u->loz - Z(36); UpdateSinglePlayKills(SpriteNum); - DoSkullBeginDeath(SpriteNum); + DoSkullBeginDeath(actor); return 0; } } @@ -415,7 +417,7 @@ int DoSkullJump(short SpriteNum) if (u->jump_speed > 200) { UpdateSinglePlayKills(SpriteNum); - DoSkullBeginDeath(SpriteNum); + DoSkullBeginDeath(actor); } } @@ -423,16 +425,17 @@ int DoSkullJump(short SpriteNum) else { UpdateSinglePlayKills(SpriteNum); - DoSkullBeginDeath(SpriteNum); + DoSkullBeginDeath(actor); } return 0; } -int DoSkullBob(short SpriteNum) +int DoSkullBob(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); // actor does a sine wave about u->sz - this is the z mid point #define SKULL_BOB_AMT (Z(16)) @@ -444,8 +447,10 @@ int DoSkullBob(short SpriteNum) return 0; } -int DoSkullSpawnShrap(short SpriteNum) +int DoSkullSpawnShrap(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; int SpawnShrap(short, short); SpawnShrap(SpriteNum, -1); @@ -454,10 +459,11 @@ int DoSkullSpawnShrap(short SpriteNum) return 0; } -int DoSkullWait(short SpriteNum) +int DoSkullWait(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int a,b,c,dist; DISTANCE(sp->x, sp->y, u->tgt_sp->x, u->tgt_sp->y, dist, a, b, c); @@ -490,7 +496,7 @@ int DoSkullWait(short SpriteNum) { sp->ang = NORM_ANGLE(sp->ang + (48 * ACTORMOVETICS)); - DoSkullBob(SpriteNum); + DoSkullBob(actor); if (dist < 8000) { @@ -514,7 +520,7 @@ int DoSkullWait(short SpriteNum) ////////////////////// -ANIMATOR DoBettyMove,NullAnimator,DoActorDebris; +ANIMATOR DoBettyMove,DoActorDebris; #define BETTY_RATE 10 ANIMATOR DoBettyWait; @@ -613,7 +619,6 @@ STATEp sg_BettyJump[] = #define BETTY_EXPLODE_RATE 11 #define BETTY_EXPLODE BETTY_R0 ANIMATOR DoSuicide; -ANIMATOR DoDamageTest; ANIMATOR DoBettySpawnShrap; STATE s_BettyExplode[] = @@ -680,10 +685,11 @@ SetupBetty(short SpriteNum) } int -DoBettyMove(int16_t SpriteNum) +DoBettyMove(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int32_t dax, day, daz; dax = MOVEx(sp->xvel, sp->ang); @@ -697,10 +703,11 @@ DoBettyMove(int16_t SpriteNum) } int -DoBettyBeginDeath(int16_t SpriteNum) +DoBettyBeginDeath(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int16_t i,num_ord=0; //extern short *DamageRadiusBetty; @@ -733,7 +740,7 @@ DoBettyBeginDeath(int16_t SpriteNum) break; case 3: - InitFlashBomb(SpriteNum); + InitFlashBomb(actor); break; case 4: @@ -744,7 +751,7 @@ DoBettyBeginDeath(int16_t SpriteNum) for (i=0; iang = NORM_ANGLE(sp->ang + (i*(2048/num_ord))); - InitSpriteGrenade(SpriteNum); + InitSpriteGrenade(actor); } break; default: @@ -779,14 +786,15 @@ DoBettyBeginDeath(int16_t SpriteNum) } -int DoBettyJump(short SpriteNum) +int DoBettyJump(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (sp->xvel) - DoBettyMove(SpriteNum); + DoBettyMove(actor); else sp->ang = NORM_ANGLE(sp->ang + (64 * ACTORMOVETICS)); @@ -809,7 +817,7 @@ int DoBettyJump(short SpriteNum) SpriteOverlapZ(SpriteNum, short(u->tgt_sp - sprite), Z(32))) { UpdateSinglePlayKills(SpriteNum); - DoBettyBeginDeath(SpriteNum); + DoBettyBeginDeath(actor); return 0; } @@ -817,7 +825,7 @@ int DoBettyJump(short SpriteNum) { sp->z = u->loz - Z(36); UpdateSinglePlayKills(SpriteNum); - DoBettyBeginDeath(SpriteNum); + DoBettyBeginDeath(actor); return 0; } } @@ -827,7 +835,7 @@ int DoBettyJump(short SpriteNum) if (u->jump_speed > 200) { UpdateSinglePlayKills(SpriteNum); - DoBettyBeginDeath(SpriteNum); + DoBettyBeginDeath(actor); } } @@ -835,15 +843,16 @@ int DoBettyJump(short SpriteNum) else { UpdateSinglePlayKills(SpriteNum); - DoBettyBeginDeath(SpriteNum); + DoBettyBeginDeath(actor); } return 0; } -int DoBettyBob(short SpriteNum) +int DoBettyBob(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); // actor does a sine wave about u->sz - this is the z mid point #define BETTY_BOB_AMT (Z(16)) @@ -855,18 +864,20 @@ int DoBettyBob(short SpriteNum) return 0; } -int DoBettySpawnShrap(short SpriteNum) +int DoBettySpawnShrap(DSWActor* actor) { + USER* u = actor->u(); int SpawnShrap(short, short); - SpawnShrap(SpriteNum, -1); + SpawnShrap(u->SpriteNum, -1); //PlaySpriteSound(SpriteNum,attr_extra1,v3df_none); return 0; } -int DoBettyWait(short SpriteNum) +int DoBettyWait(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); int a,b,c,dist; DISTANCE(sp->x, sp->y, u->tgt_sp->x, u->tgt_sp->y, dist, a, b, c); @@ -899,7 +910,7 @@ int DoBettyWait(short SpriteNum) { sp->ang = NORM_ANGLE(sp->ang + (48 * ACTORMOVETICS)); - DoBettyBob(SpriteNum); + DoBettyBob(actor); if (dist < 8000) { @@ -919,7 +930,6 @@ int DoBettyWait(short SpriteNum) static saveable_code saveable_skull_code[] = { - SAVE_CODE(SetupSkull), SAVE_CODE(DoSkullMove), SAVE_CODE(DoSkullBeginDeath), SAVE_CODE(DoSkullJump), @@ -927,7 +937,6 @@ static saveable_code saveable_skull_code[] = SAVE_CODE(DoSkullSpawnShrap), SAVE_CODE(DoSkullWait), - SAVE_CODE(SetupBetty), SAVE_CODE(DoBettyMove), SAVE_CODE(DoBettyBeginDeath), SAVE_CODE(DoBettyJump), diff --git a/source/games/sw/src/slidor.cpp b/source/games/sw/src/slidor.cpp index e1af5e972..56f5759fa 100644 --- a/source/games/sw/src/slidor.cpp +++ b/source/games/sw/src/slidor.cpp @@ -276,7 +276,7 @@ void DoSlidorInterp(short SpriteNum, INTERP_FUNC interp_func) pw = endwall; uint16_t const nextwall = wall[w].nextwall; - if (nextwall >= MAXWALLS) + if (!validWallIndex(nextwall)) { // white wall - move 4 points interp_func(w, Interp_Wall_X); @@ -304,7 +304,7 @@ void DoSlidorInterp(short SpriteNum, INTERP_FUNC interp_func) pw = endwall; uint16_t const nextwall = wall[w].nextwall; - if (nextwall >= MAXWALLS) + if (!validWallIndex(nextwall)) { // white wall - move 4 points interp_func(w, Interp_Wall_X); @@ -332,7 +332,7 @@ void DoSlidorInterp(short SpriteNum, INTERP_FUNC interp_func) pw = endwall; uint16_t const nextwall = wall[w].nextwall; - if (nextwall >= MAXWALLS) + if (!validWallIndex(nextwall)) { interp_func(w, Interp_Wall_Y); interp_func(pw, Interp_Wall_Y); @@ -358,7 +358,7 @@ void DoSlidorInterp(short SpriteNum, INTERP_FUNC interp_func) pw = endwall; uint16_t const nextwall = wall[w].nextwall; - if (nextwall >= MAXWALLS) + if (!validWallIndex(nextwall)) { interp_func(w, Interp_Wall_Y); interp_func(pw, Interp_Wall_Y); @@ -400,7 +400,7 @@ int DoSlidorMoveWalls(short SpriteNum, int amt) if (w < startwall) pw = endwall; - if ((uint16_t)wall[w].nextwall >= MAXWALLS) + if (!validWallIndex(wall[w].nextwall)) { // white wall - move 4 points wall[w].x -= amt; @@ -424,7 +424,7 @@ int DoSlidorMoveWalls(short SpriteNum, int amt) if (w < startwall) pw = endwall; - if ((uint16_t)wall[w].nextwall >= MAXWALLS) + if (!validWallIndex(wall[w].nextwall)) { // white wall - move 4 points wall[w].x += amt; @@ -448,7 +448,7 @@ int DoSlidorMoveWalls(short SpriteNum, int amt) if (w < startwall) pw = endwall; - if ((uint16_t)wall[w].nextwall >= MAXWALLS) + if (!validWallIndex(wall[w].nextwall)) { wall[w].y -= amt; wall[pw].y -= amt; @@ -470,7 +470,7 @@ int DoSlidorMoveWalls(short SpriteNum, int amt) if (w < startwall) pw = endwall; - if ((uint16_t)wall[w].nextwall >= MAXWALLS) + if (!validWallIndex(wall[w].nextwall)) { wall[w].y += amt; wall[pw].y += amt; @@ -679,10 +679,11 @@ int DoSlidorMove(short SpriteNum) return 0; } -int DoSlidor(short SpriteNum) +int DoSlidor(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); - SPRITEp sp = u->SpriteP; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + SPRITEp sp = &sprite[SpriteNum]; SECTORp sectp = §or[sp->sectnum]; DoSlidorMove(SpriteNum); @@ -695,17 +696,6 @@ int DoSlidor(short SpriteNum) static saveable_code saveable_slidor_code[] = { - SAVE_CODE(ReverseSlidor), - SAVE_CODE(SlidorSwitch), - SAVE_CODE(SetSlidorActive), - SAVE_CODE(SetSlidorInactive), - SAVE_CODE(DoSlidorOperate), - SAVE_CODE(DoSlidorMatch), - SAVE_CODE(TestSlidorMatchActive), - SAVE_CODE(DoSlidorInterp), - SAVE_CODE(DoSlidorMoveWalls), - SAVE_CODE(DoSlidorInstantClose), - SAVE_CODE(DoSlidorMove), SAVE_CODE(DoSlidor), }; diff --git a/source/games/sw/src/sounds.cpp b/source/games/sw/src/sounds.cpp index b2ca4f8f1..4797528f9 100644 --- a/source/games/sw/src/sounds.cpp +++ b/source/games/sw/src/sounds.cpp @@ -113,10 +113,11 @@ float S_ConvertPitch(int lpitch) enum { - MAXLEVLDIST = 19000, // The higher the number, the further away you can hear sound DECAY_CONST = 4000 }; +const int MAXLEVLDIST = 19000; // The higher the number, the further away you can hear sound + short SoundDist(int x, int y, int z, int basedist) { double tx, ty, tz; diff --git a/source/games/sw/src/spike.cpp b/source/games/sw/src/spike.cpp index 64ab84c34..50f24e3b5 100644 --- a/source/games/sw/src/spike.cpp +++ b/source/games/sw/src/spike.cpp @@ -324,9 +324,10 @@ void MoveSpritesWithSpike(short sectnum) } } -int DoSpike(short SpriteNum) +int DoSpike(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = u->SpriteP; int *lptr; @@ -442,9 +443,10 @@ int DoSpike(short SpriteNum) return 0; } -int DoSpikeAuto(short SpriteNum) +int DoSpikeAuto(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = u->SpriteP; int *lptr; @@ -491,16 +493,6 @@ int DoSpikeAuto(short SpriteNum) static saveable_code saveable_spike_code[] = { - SAVE_CODE(ReverseSpike), - SAVE_CODE(SpikeSwitch), - SAVE_CODE(SetSpikeActive), - SAVE_CODE(SetSpikeInactive), - SAVE_CODE(DoSpikeOperate), - SAVE_CODE(DoSpikeMatch), - SAVE_CODE(TestSpikeMatchActive), - SAVE_CODE(DoSpikeMove), - SAVE_CODE(SpikeAlign), - SAVE_CODE(MoveSpritesWithSpike), SAVE_CODE(DoSpike), SAVE_CODE(DoSpikeAuto), }; diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp index a15897e18..724240f77 100644 --- a/source/games/sw/src/sprite.cpp +++ b/source/games/sw/src/sprite.cpp @@ -48,38 +48,40 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "quotemgr.h" #include "v_text.h" #include "gamecontrol.h" +#include "gamefuncs.h" BEGIN_SW_NS -ANIMATOR SetupCoolie; -ANIMATOR SetupNinja; -ANIMATOR SetupGoro; -ANIMATOR SetupCoolg; -ANIMATOR SetupEel; -ANIMATOR SetupSumo; -ANIMATOR SetupZilla; -ANIMATOR SetupToiletGirl; -ANIMATOR SetupWashGirl; -ANIMATOR SetupCarGirl; -ANIMATOR SetupMechanicGirl; -ANIMATOR SetupSailorGirl; -ANIMATOR SetupPruneGirl; -ANIMATOR SetupTrashCan; -ANIMATOR SetupBunny; -ANIMATOR SetupRipper; -ANIMATOR SetupRipper2; -ANIMATOR SetupSerp; -ANIMATOR SetupLava; -ANIMATOR SetupSkel; -ANIMATOR SetupHornet; -ANIMATOR SetupSkull; -ANIMATOR SetupBetty; -ANIMATOR SetupPachinkoLight; -ANIMATOR SetupPachinko1; -ANIMATOR SetupPachinko2; -ANIMATOR SetupPachinko3; -ANIMATOR SetupPachinko4; -ANIMATOR SetupGirlNinja; + +int SetupCoolie(short); +int SetupNinja(short); +int SetupGoro(short); +int SetupCoolg(short); +int SetupEel(short); +int SetupSumo(short); +int SetupZilla(short); +int SetupToiletGirl(short); +int SetupWashGirl(short); +int SetupCarGirl(short); +int SetupMechanicGirl(short); +int SetupSailorGirl(short); +int SetupPruneGirl(short); +int SetupTrashCan(short); +int SetupBunny(short); +int SetupRipper(short); +int SetupRipper2(short); +int SetupSerp(short); +int SetupLava(short); +int SetupSkel(short); +int SetupHornet(short); +int SetupSkull(short); +int SetupBetty(short); +int SetupPachinkoLight(short); +int SetupPachinko1(short); +int SetupPachinko2(short); +int SetupPachinko3(short); +int SetupPachinko4(short); +int SetupGirlNinja(short); ANIMATOR DoVator, DoVatorAuto; ANIMATOR DoRotator; ANIMATOR DoSlidor; @@ -101,7 +103,7 @@ static int globhiz, globloz, globhihit, globlohit; short wait_active_check_offset; int PlaxCeilGlobZadjust, PlaxFloorGlobZadjust; void SetSectorWallBits(short sectnum, int bit_mask, bool set_sectwall, bool set_nextwall); -int DoActorDebris(short SpriteNum); +int DoActorDebris(DSWActor* actor); void ActorWarpUpdatePos(short SpriteNum,short sectnum); void ActorWarpType(SPRITEp sp, SPRITEp sp_warp); int MissileZrange(short SpriteNum); @@ -1602,8 +1604,8 @@ void PreMapCombineFloors(void) int SpriteNum; int base_offset; int dx,dy; - short sectlist[MAXSECTORS]; - short sectlistplc, sectlistend, dasect, startwall, endwall, nextsector; + int dasect, startwall, endwall, nextsector; + unsigned sectliststart, sectlistplc; short pnum; typedef struct @@ -1631,6 +1633,7 @@ void PreMapCombineFloors(void) } } + sectliststart = GlobalSectorList.Size(); for (i = base_offset = 0; i < MAX_FLOORS; i++) { // blank so continue @@ -1646,11 +1649,12 @@ void PreMapCombineFloors(void) dx = BoundList[base_offset].offset->x - BoundList[i].offset->x; dy = BoundList[base_offset].offset->y - BoundList[i].offset->y; - sectlist[0] = BoundList[i].offset->sectnum; - sectlistplc = 0; sectlistend = 1; - while (sectlistplc < sectlistend) + GlobalSectorList.Resize(sectliststart); + GlobalSectorList.Push(BoundList[i].offset->sectnum); + sectlistplc = sectliststart; + while (sectlistplc < GlobalSectorList.Size()) { - dasect = sectlist[sectlistplc++]; + dasect = GlobalSectorList[sectlistplc++]; SectIterator it(dasect); while ((j = it.NextIndex()) >= 0) @@ -1669,11 +1673,18 @@ void PreMapCombineFloors(void) nextsector = wall[j].nextsector; if (nextsector < 0) continue; - for (k=sectlistend-1; k>=0; k--) - if (sectlist[k] == nextsector) + // make sure its not on the list + for (k = GlobalSectorList.Size() - 1; k >= (int)sectliststart; k--) + { + if (GlobalSectorList[k] == nextsector) break; + } + + // if its not on the list add it to the end if (k < 0) - sectlist[sectlistend++] = nextsector; + { + GlobalSectorList.Push(nextsector); + } } } @@ -1682,9 +1693,9 @@ void PreMapCombineFloors(void) { PLAYERp pp = &Player[pnum]; dasect = pp->cursectnum; - for (j=0; jposx += dx; pp->posy += dy; @@ -1703,6 +1714,7 @@ void PreMapCombineFloors(void) { KillSprite(SpriteNum); } + GlobalSectorList.Resize(sectliststart); } #if 0 @@ -1710,7 +1722,7 @@ void PreMapCombineFloors(void) void TraverseSectors(short start_sect) { int i, j, k; - short sectlist[MAXSECTORS]; + short sectlist[M AXSECTORS]; short sectlistplc, sectlistend, sect, startwall, endwall, nextsector; sectlist[0] = start_sect; @@ -2632,7 +2644,7 @@ SpriteSetup(void) if (TEST_BOOL5(sp)) { uint16_t const nextwall = wall[w].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) { wall_shade[wallcount] = wall[wall[w].nextwall].shade; wallcount++; @@ -2688,7 +2700,7 @@ SpriteSetup(void) if (TEST_BOOL5(sp)) { uint16_t const nextwall = wall[w].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) { wall_shade[wallcount] = wall[wall[w].nextwall].shade; wallcount++; @@ -2968,7 +2980,7 @@ SpriteSetup(void) do { // DO NOT TAG WHITE WALLS! - if ((uint16_t)wall[wall_num].nextwall < MAXWALLS) + if (validWallIndex(wall[wall_num].nextwall)) { SET(wall[wall_num].cstat, CSTAT_WALL_WARP_HITSCAN); } @@ -3084,7 +3096,7 @@ SpriteSetup(void) { SET(wall[wall_num].cstat, CSTAT_WALL_BLOCK_ACTOR); uint16_t const nextwall = wall[wall_num].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) SET(wall[nextwall].cstat, CSTAT_WALL_BLOCK_ACTOR); wall_num = wall[wall_num].point2; } @@ -4671,6 +4683,11 @@ NewStateGroup(short SpriteNum, STATEp StateGroup[]) return 0; } +int NewStateGroup(USERp user, STATEp StateGroup[]) +{ + return NewStateGroup(user->SpriteNum, StateGroup); +} + bool SpriteOverlap(int16_t spritenum_a, int16_t spritenum_b) @@ -4879,7 +4896,9 @@ DoActorZrange(short SpriteNum) save_cstat = TEST(sp->cstat, CSTAT_SPRITE_BLOCK); RESET(sp->cstat, CSTAT_SPRITE_BLOCK); - FAFgetzrange(sp->x, sp->y, sp->z - DIV2(SPRITEp_SIZE_Z(sp)), sp->sectnum, &u->hiz, &ceilhit, &u->loz, &florhit, (((int) sp->clipdist) << 2) - GETZRANGE_CLIP_ADJ, CLIPMASK_ACTOR); + vec3_t pos = sp->pos; + pos.z -= DIV2(SPRITEp_SIZE_Z(sp)); + FAFgetzrange(pos, sp->sectnum, &u->hiz, &ceilhit, &u->loz, &florhit, (((int) sp->clipdist) << 2) - GETZRANGE_CLIP_ADJ, CLIPMASK_ACTOR); SET(sp->cstat, save_cstat); u->lo_sectp = u->hi_sectp = nullptr; @@ -5013,7 +5032,7 @@ DropAhead(short SpriteNum, short min_height) SPRITEp sp = &sprite[SpriteNum]; int dax, day; - short newsector; + int newsector; // dax = sp->x + MOVEx(128, sp->ang); // day = sp->y + MOVEy(128, sp->ang); @@ -5022,7 +5041,7 @@ DropAhead(short SpriteNum, short min_height) day = sp->y + MOVEy(256, sp->ang); newsector = sp->sectnum; - COVERupdatesector(dax, day, &newsector); + updatesector(dax, day, &newsector); // look straight down for a drop if (ActorDrop(SpriteNum, dax, day, sp->z, newsector, min_height)) @@ -5074,10 +5093,8 @@ move_actor(short SpriteNum, int xchange, int ychange, int zchange) hi_sectp = u->hi_sectp; sectnum = sp->sectnum; - clipmoveboxtracenum = 1; u->ret = move_sprite(SpriteNum, xchange, ychange, zchange, u->ceiling_dist, u->floor_dist, cliptype, ACTORMOVETICS); - clipmoveboxtracenum = 3; ASSERT(sp->sectnum >= 0); @@ -5141,16 +5158,20 @@ move_actor(short SpriteNum, int xchange, int ychange, int zchange) } int -DoStayOnFloor(short SpriteNum) +DoStayOnFloor(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; sprite[SpriteNum].z = sector[sprite[SpriteNum].sectnum].floorz; //sprite[SpriteNum].z = getflorzofslope(sprite[SpriteNum].sectnum, sprite[SpriteNum].x, sprite[SpriteNum].y); return 0; } int -DoGrating(short SpriteNum) +DoGrating(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; int dir; #define GRATE_FACTOR 3 @@ -5217,59 +5238,27 @@ DoSpriteFade(short SpriteNum) } #endif -int -SpearOnFloor(short SpriteNum) -{ - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; - - if (!TEST(u->Flags, SPR_SO_ATTACHED)) - { - // if on a sprite bridge, stay with the sprite otherwize stay with - // the floor - if (u->lo_sp) - sp->z = u->loz; - else - sp->z = sector[sp->sectnum].floorz + u->sz; - } - return 0; -} int -SpearOnCeiling(short SpriteNum) -{ - USERp u = User[SpriteNum].Data(); - SPRITEp sp = User[SpriteNum]->SpriteP; - - if (!TEST(u->Flags, SPR_SO_ATTACHED)) - { - // if on a sprite bridge, stay with the sprite otherwize stay with - // the floor - if (u->hi_sp) - sp->z = u->hiz; - else - sp->z = sector[sp->sectnum].ceilingz + u->sz; - } - return 0; -} - -int -DoKey(short SpriteNum) +DoKey(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; sp->ang = NORM_ANGLE(sp->ang + (14 * ACTORMOVETICS)); //DoSpriteFade(SpriteNum); - DoGet(SpriteNum); + DoGet(actor); return 0; } int -DoCoin(short SpriteNum) +DoCoin(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; int offset; u->WaitTics -= ACTORMOVETICS * 2; @@ -5541,9 +5530,11 @@ struct InventoryDecl_t InventoryDecls[InvDecl_TOTAL] = #define ITEMFLASHAMT -8 #define ITEMFLASHCLR 144 int -DoGet(short SpriteNum) +DoGet(DSWActor* actor) { - USERp u = User[SpriteNum].Data(), pu; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + USERp pu; SPRITEp sp = u->SpriteP; PLAYERp pp; short pnum, key_num; @@ -6515,92 +6506,6 @@ AdjustActiveRange(PLAYERp pp, short SpriteNum, int dist) } } -/* - - !AIC KEY - Main processing loop for sprites. Sprites are separated and - traversed by STAT lists. Note the STAT_MISC, STAT_ENEMY, STAT_VATOR below. - Most everything here calls StateControl(). - -*/ - - -#if DEBUG -#define INLINE_STATE 0 -#else -#define INLINE_STATE 1 -#endif - -#define STATE_CONTROL(SpriteNum, sp, u, StateTics) \ - if (!(u)->State) \ - { \ - ASSERT((u)->ActorActionFunc); \ - ((u)->ActorActionFunc)((SpriteNum)); \ - } \ - else \ - { \ - if ((sp)->statnum >= STAT_SKIP4_START && (sp)->statnum <= STAT_SKIP4_END) \ - (u)->Tics += ACTORMOVETICS * 2; \ - else \ - (u)->Tics += ACTORMOVETICS; \ - \ - while ((u)->Tics >= TEST((u)->State->Tics, SF_TICS_MASK)) \ - { \ - (StateTics) = TEST((u)->State->Tics, SF_TICS_MASK); \ - \ - if (TEST((u)->State->Tics, SF_TIC_ADJUST)) \ - { \ - ASSERT((u)->Attrib); \ - ASSERT((u)->speed < MAX_SPEED); \ - ASSERT((StateTics) > -(u)->Attrib->TicAdjust[(u)->speed]); \ - \ - (StateTics) += (u)->Attrib->TicAdjust[(u)->speed]; \ - } \ - \ - (u)->Tics -= (StateTics); \ - \ - (u)->State = (u)->State->NextState; \ - \ - while (TEST((u)->State->Tics, SF_QUICK_CALL)) \ - { \ - (*(u)->State->Animator)((SpriteNum)); \ - ASSERT(u); \ - \ - if (!(u)) \ - break; \ - \ - if (TEST((u)->State->Tics, SF_QUICK_CALL)) \ - (u)->State = (u)->State->NextState; \ - } \ - \ - if (!(u)) \ - break; \ - \ - if (!(u)->State->Pic) \ - { \ - NewStateGroup((SpriteNum), (STATEp *) (u)->State->NextState); \ - } \ - } \ - \ - if (u) \ - { \ - if (TEST((u)->State->Tics, SF_WALL_STATE)) \ - { \ - ASSERT((u)->WallP); \ - (u)->WallP->picnum = (u)->State->Pic; \ - } \ - else \ - { \ - if ((u)->RotNum > 1) \ - (sp)->picnum = (u)->Rot[0]->Pic; \ - else \ - (sp)->picnum = (u)->State->Pic; \ - } \ - \ - if ((u)->State->Animator && (u)->State->Animator != NullAnimator) \ - (*(u)->State->Animator)((SpriteNum)); \ - } \ - } - /* @@ -6613,6 +6518,7 @@ AdjustActiveRange(PLAYERp pp, short SpriteNum, int dist) int StateControl(int16_t SpriteNum) { + auto actor = &swActors[SpriteNum]; USERp u = User[SpriteNum].Data(); SPRITEp sp = &sprite[SpriteNum]; short StateTics; @@ -6620,7 +6526,7 @@ StateControl(int16_t SpriteNum) if (!u->State) { ASSERT(u->ActorActionFunc); - (u->ActorActionFunc)(SpriteNum); + (u->ActorActionFunc)(actor); return 0; } @@ -6653,7 +6559,7 @@ StateControl(int16_t SpriteNum) while (TEST(u->State->Tics, SF_QUICK_CALL)) { // Call it once and go to the next state - (*u->State->Animator)(SpriteNum); + (*u->State->Animator)(actor); ASSERT(u); //put this in to see if actor was getting killed with in his QUICK_CALL state @@ -6695,7 +6601,7 @@ StateControl(int16_t SpriteNum) // Call the correct animator if (u->State->Animator && u->State->Animator != NullAnimator) - (*u->State->Animator)(SpriteNum); + (*u->State->Animator)(actor); } return 0; @@ -6717,17 +6623,8 @@ SpriteControl(void) StatIterator it(STAT_MISC); while ((i = it.NextIndex()) >= 0) { -#if INLINE_STATE - ASSERT(User[i].Data()); - u = User[i].Data(); - sp = User[i]->SpriteP; - STATE_CONTROL(i, sp, u, StateTics) - // ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()] != nullptr : true); -#else - ASSERT(User[i]); StateControl(i); // ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()] != nullptr : true); -#endif } // Items and skip2 things @@ -6738,17 +6635,7 @@ SpriteControl(void) StatIterator it(stat); while ((i = it.NextIndex()) >= 0) { -#if INLINE_STATE - ASSERT(User[i].Data()); - u = User[i].Data(); - sp = User[i]->SpriteP; - STATE_CONTROL(i, sp, u, StateTics) - ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()].Data() != nullptr : true); -#else - ASSERT(User[i]); StateControl(i); - ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()] != nullptr : true); -#endif } } } @@ -6788,13 +6675,7 @@ SpriteControl(void) // Only update the ones close to ANY player if (CloseToPlayer) { -#if INLINE_STATE - u = User[i].Data(); - sp = User[i]->SpriteP; - STATE_CONTROL(i, sp, u, StateTics) -#else StateControl(i); -#endif ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()].Data() != nullptr : true); } else @@ -6813,17 +6694,7 @@ SpriteControl(void) StatIterator it(stat); while ((i = it.NextIndex()) >= 0) { -#if INLINE_STATE - ASSERT(User[i].Data()); - u = User[i].Data(); - sp = User[i]->SpriteP; - STATE_CONTROL(i, sp, u, StateTics) - ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()].Data() != nullptr : true); -#else - ASSERT(User[i]); - StateControl(i); - ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()].Data() != nullptr : true); -#endif + StateControl(i); } } } @@ -6831,9 +6702,10 @@ SpriteControl(void) it.Reset(STAT_NO_STATE); while ((i = it.NextIndex()) >= 0) { - if (User[i].Data() && User[i]->ActorActionFunc) - (*User[i]->ActorActionFunc)(i); - ASSERT(it.PeekIndex() >= 0 ? sprite[it.PeekIndex()].statnum != MAXSTATUS : true); + auto actor = &swActors[i]; + auto u = actor->u(); + if (u && u->ActorActionFunc) + (*u->ActorActionFunc)(actor); } if (MoveSkip8 == 0) @@ -6852,10 +6724,7 @@ SpriteControl(void) it.Reset(STAT_WALLBLOOD_QUEUE); while ((i = it.NextIndex()) >= 0) { - ASSERT(User[i].Data()); - u = User[i].Data(); - sp = User[i]->SpriteP; - STATE_CONTROL(i, sp, u, StateTics) + StateControl(i); ASSERT(it.PeekIndex() >= 0 ? User[it.PeekIndex()].Data() != nullptr : true); } @@ -6866,6 +6735,7 @@ SpriteControl(void) it.Reset(STAT_VATOR); while ((i = it.NextIndex()) >= 0) { + auto actor = &swActors[i]; u = User[i].Data(); if (u == 0) @@ -6881,12 +6751,13 @@ SpriteControl(void) if (!TEST(u->Flags, SPR_ACTIVE)) continue; - (*User[i]->ActorActionFunc)(i); + (*User[i]->ActorActionFunc)(actor); } it.Reset(STAT_SPIKE); while ((i = it.NextIndex()) >= 0) { + auto actor = &swActors[i]; u = User[i].Data(); if (u->Tics) @@ -6903,12 +6774,13 @@ SpriteControl(void) if (i == 69 && it.PeekIndex() == -1) continue; - (*User[i]->ActorActionFunc)(i); + (*User[i]->ActorActionFunc)(actor); } it.Reset(STAT_ROTATOR); while ((i = it.NextIndex()) >= 0) { + auto actor = &swActors[i]; u = User[i].Data(); if (u->Tics) @@ -6922,12 +6794,13 @@ SpriteControl(void) if (!TEST(u->Flags, SPR_ACTIVE)) continue; - (*User[i]->ActorActionFunc)(i); + (*User[i]->ActorActionFunc)(actor); } it.Reset(STAT_SLIDOR); while ((i = it.NextIndex()) >= 0) { + auto actor = &swActors[i]; u = User[i].Data(); if (u->Tics) @@ -6941,7 +6814,7 @@ SpriteControl(void) if (!TEST(u->Flags, SPR_ACTIVE)) continue; - (*User[i]->ActorActionFunc)(i); + (*User[i]->ActorActionFunc)(actor); } it.Reset(STAT_SUICIDE); @@ -6966,9 +6839,9 @@ SpriteControl(void) int move_sprite(int spritenum, int xchange, int ychange, int zchange, int ceildist, int flordist, uint32_t cliptype, int numtics) { - int daz; int retval=0, zh; - short dasectnum, tempshort; + int dasectnum; + short tempshort; SPRITEp spr; USERp u = User[spritenum].Data(); short lastsectnum; @@ -6977,14 +6850,12 @@ move_sprite(int spritenum, int xchange, int ychange, int zchange, int ceildist, ASSERT(u); + vec3_t clippos = spr->pos; + // Can't modify sprite sectors // directly becuase of linked lists dasectnum = lastsectnum = spr->sectnum; - // Must do this if not using the new - // centered centering (of course) - daz = spr->z; - if (TEST(spr->cstat, CSTAT_SPRITE_YCENTER)) { zh = 0; @@ -6993,17 +6864,16 @@ move_sprite(int spritenum, int xchange, int ychange, int zchange, int ceildist, { // move the center point up for moving zh = u->zclip; - daz -= zh; + clippos.z -= zh; } // ASSERT(inside(spr->x,spr->y,dasectnum)); - clipmoveboxtracenum = 1; - retval = clipmove_old(&spr->x, &spr->y, &daz, &dasectnum, + retval = clipmove(&clippos, &dasectnum, ((xchange * numtics) << 11), ((ychange * numtics) << 11), - (((int) spr->clipdist) << 2), ceildist, flordist, cliptype); - clipmoveboxtracenum = 3; + (((int) spr->clipdist) << 2), ceildist, flordist, cliptype, 1); + spr->pos.vec2 = clippos.vec2; //if (TEST(retval, HIT_MASK) == HIT_WALL) // { @@ -7033,7 +6903,9 @@ move_sprite(int spritenum, int xchange, int ychange, int zchange, int ceildist, // I subtracted 8 from the clipdist because actors kept going up on // ledges they were not supposed to go up on. Did the same for the // player. Seems to work ok! - FAFgetzrange(spr->x, spr->y, spr->z - zh - 1, spr->sectnum, + vec3_t pos = spr->pos; + pos.z -= zh + 1; + FAFgetzrange(pos, spr->sectnum, &globhiz, &globhihit, &globloz, &globlohit, (((int) spr->clipdist) << 2) - GETZRANGE_CLIP_ADJ, cliptype); @@ -7043,16 +6915,16 @@ move_sprite(int spritenum, int xchange, int ychange, int zchange, int ceildist, // Takes info from global variables DoActorGlobZ(spritenum); - daz = spr->z + ((zchange * numtics) >> 3); + clippos.z = spr->z + ((zchange * numtics) >> 3); // test for hitting ceiling or floor - if ((daz - zh <= globhiz) || (daz - zh > globloz)) + if ((clippos.z - zh <= globhiz) || (clippos.z - zh > globloz)) { if (retval == 0) { if (TEST(u->Flags, SPR_CLIMBING)) { - spr->z = daz; + spr->z = clippos.z; return 0; } @@ -7061,7 +6933,7 @@ move_sprite(int spritenum, int xchange, int ychange, int zchange, int ceildist, } else { - spr->z = daz; + spr->z = clippos.z; } // extra processing for Stacks and warping @@ -7096,12 +6968,11 @@ int pushmove_sprite(short SpriteNum) { SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum].Data(); - short sectnum, ret; - int daz; + int sectnum, ret; - daz = sp->z - u->zclip; + sp->z -= u->zclip; sectnum = sp->sectnum; - ret = pushmove_old(&sp->x, &sp->y, &daz, §num, + ret = pushmove(&sp->pos, §num, (((int)sp->clipdist)<<2)-GETZRANGE_CLIP_ADJ, u->ceiling_dist, u->floor_dist, CLIPMASK_ACTOR); if (sectnum != sp->sectnum && sectnum >= 0) @@ -7113,7 +6984,7 @@ int pushmove_sprite(short SpriteNum) MONO_PRINT(ds); } - sp->z = daz + u->zclip; + sp->z += u->zclip; return 0; } @@ -7214,9 +7085,8 @@ MissileZrange(short SpriteNum) int move_missile(int spritenum, int xchange, int ychange, int zchange, int ceildist, int flordist, uint32_t cliptype, int numtics) { - int daz; int retval, zh; - short dasectnum, tempshort; + int dasectnum, tempshort; SPRITEp sp; USERp u = User[spritenum].Data(); short lastsectnum; @@ -7225,13 +7095,11 @@ move_missile(int spritenum, int xchange, int ychange, int zchange, int ceildist, ASSERT(u); - // Can't modify sprite sectors - // directly becuase of linked lists - dasectnum = lastsectnum = sp->sectnum; + vec3_t clippos = sp->pos; // Can't modify sprite sectors // directly becuase of linked lists - daz = sp->z; + dasectnum = lastsectnum = sp->sectnum; if (TEST(sp->cstat, CSTAT_SPRITE_YCENTER)) { @@ -7240,16 +7108,15 @@ move_missile(int spritenum, int xchange, int ychange, int zchange, int ceildist, else { zh = u->zclip; - daz -= zh; + clippos.z -= zh; } // ASSERT(inside(sp->x,sp->y,dasectnum)); - clipmoveboxtracenum = 1; - retval = clipmove_old(&sp->x, &sp->y, &daz, &dasectnum, + retval = clipmove(&clippos, &dasectnum, ((xchange * numtics) << 11), ((ychange * numtics) << 11), - (((int) sp->clipdist) << 2), ceildist, flordist, cliptype); - clipmoveboxtracenum = 3; + (((int) sp->clipdist) << 2), ceildist, flordist, cliptype, 1); + sp->pos.vec2 = clippos.vec2; if (dasectnum < 0) { @@ -7281,20 +7148,20 @@ move_missile(int spritenum, int xchange, int ychange, int zchange, int ceildist, // missiles don't need the water to be down MissileWaterAdjust(spritenum); - daz = sp->z + ((zchange * numtics) >> 3); + clippos.z = sp->z + ((zchange * numtics) >> 3); // NOTE: this does not tell you when you hit a floor sprite // this case is currently treated like it hit a sector // test for hitting ceiling or floor - if (daz - zh <= u->hiz + ceildist) + if (clippos.z - zh <= u->hiz + ceildist) { // normal code sp->z = u->hiz + zh + ceildist; if (retval == 0) retval = dasectnum|HIT_SECTOR; } - else if (daz - zh > u->loz - flordist) + else if (clippos.z - zh > u->loz - flordist) { sp->z = u->loz + zh - flordist; if (retval == 0) @@ -7302,7 +7169,7 @@ move_missile(int spritenum, int xchange, int ychange, int zchange, int ceildist, } else { - sp->z = daz; + sp->z = clippos.z; } if (FAF_ConnectArea(sp->sectnum)) @@ -7355,7 +7222,7 @@ move_ground_missile(short spritenum, int xchange, int ychange, int ceildist, int { int daz; int retval=0; - short dasectnum; + int dasectnum; SPRITEp sp; USERp u = User[spritenum].Data(); short lastsectnum; @@ -7369,6 +7236,7 @@ move_ground_missile(short spritenum, int xchange, int ychange, int ceildist, int // directly becuase of linked lists dasectnum = lastsectnum = sp->sectnum; + vec3_t opos = sp->pos; daz = sp->z; // climbing a wall @@ -7391,8 +7259,6 @@ move_ground_missile(short spritenum, int xchange, int ychange, int ceildist, int u->z_tgt = 0; } - ox = sp->x; - oy = sp->y; sp->x += xchange/2; sp->y += ychange/2; @@ -7402,13 +7268,12 @@ move_ground_missile(short spritenum, int xchange, int ychange, int ceildist, int { // back up and try again dasectnum = lastsectnum = sp->sectnum; - sp->x = ox; - sp->y = oy; - clipmoveboxtracenum = 1; - retval = clipmove_old(&sp->x, &sp->y, &daz, &dasectnum, + opos = sp->pos; + opos.z = daz; + retval = clipmove(&opos, &dasectnum, ((xchange * numtics) << 11), ((ychange * numtics) << 11), - (((int) sp->clipdist) << 2), ceildist, flordist, cliptype); - clipmoveboxtracenum = 3; + (((int) sp->clipdist) << 2), ceildist, flordist, cliptype, 1); + sp->pos.vec2 = opos.vec2; } if (dasectnum < 0) @@ -7531,29 +7396,14 @@ move_ground_missile(short spritenum, int xchange, int ychange, int ceildist, int return retval; } - #include "saveable.h" static saveable_code saveable_sprite_code[] = { - SAVE_CODE(DoActorZrange), - SAVE_CODE(DoActorGlobZ), - SAVE_CODE(DoStayOnFloor), SAVE_CODE(DoGrating), - SAVE_CODE(SpearOnFloor), - SAVE_CODE(SpearOnCeiling), SAVE_CODE(DoKey), SAVE_CODE(DoCoin), - SAVE_CODE(KillGet), - SAVE_CODE(KillGetAmmo), - SAVE_CODE(KillGetWeapon), - SAVE_CODE(DoSpawnItemTeleporterEffect), SAVE_CODE(DoGet), - SAVE_CODE(SetEnemyActive), - SAVE_CODE(SetEnemyInactive), - SAVE_CODE(ProcessActiveVars), - SAVE_CODE(StateControl), - SAVE_CODE(SpriteControl), }; static saveable_data saveable_sprite_data[] = diff --git a/source/games/sw/src/sprite.h b/source/games/sw/src/sprite.h index ddb804936..5c58cb646 100644 --- a/source/games/sw/src/sprite.h +++ b/source/games/sw/src/sprite.h @@ -46,7 +46,6 @@ int DoBody(short SpriteNum); bool CanMoveHere(int16_t spritenum); bool SpriteOverlap(int16_t spritenum_a, int16_t spritenum_b); int DoActorDie(short SpriteNum, short weapon); -int DoGet(short SpriteNum); void SpriteControl(void); void SetEnemyInactive(short SpriteNum); void DoActorZrange(short SpriteNum); diff --git a/source/games/sw/src/sumo.cpp b/source/games/sw/src/sumo.cpp index 4516c8a42..da5e20cd4 100644 --- a/source/games/sw/src/sumo.cpp +++ b/source/games/sw/src/sumo.cpp @@ -676,36 +676,38 @@ SetupSumo(short SpriteNum) return 0; } -int NullSumo(short SpriteNum) +int NullSumo(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; //if (TEST(u->Flags,SPR_SLIDING)) - //DoActorSlide(SpriteNum); + //DoActorSlide(actor); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoSumoMove(short SpriteNum) +int DoSumoMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; //if (TEST(u->Flags,SPR_SLIDING)) - //DoActorSlide(SpriteNum); + //DoActorSlide(actor); if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); KeepActorOnFloor(SpriteNum); - if (DoActorSectorDamage(SpriteNum)) + if (DoActorSectorDamage(actor)) { return 0; } @@ -713,37 +715,22 @@ int DoSumoMove(short SpriteNum) return 0; } -#if 0 -int InitSumoCharge(short SpriteNum) + +int DoSumoRumble(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - - if (RANDOM_P2(1024) > 950) - PlaySound(DIGI_SUMOALERT, sp, v3df_follow); - - DoActorSetSpeed(SpriteNum, FAST_SPEED); - - InitActorMoveCloser(SpriteNum); - - NewStateGroup(SpriteNum, sg_SumoCharge); - - return 0; -} -#endif - -int DoSumoRumble(short SpriteNum) -{ - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); SetSumoQuake(SpriteNum); return 0; } -int InitSumoFart(short SpriteNum) +int InitSumoFart(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; extern int InitSumoNapalm(short SpriteNum); @@ -757,8 +744,10 @@ int InitSumoFart(short SpriteNum) return 0; } -int InitSumoStomp(short SpriteNum) +int InitSumoStomp(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; extern int InitSumoStompAttack(short SpriteNum); @@ -769,8 +758,10 @@ int InitSumoStomp(short SpriteNum) return 0; } -int InitSumoClap(short SpriteNum) +int InitSumoClap(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; extern int InitMiniSumoClap(short SpriteNum); extern int InitSumoSkull(short SpriteNum); @@ -782,10 +773,11 @@ int InitSumoClap(short SpriteNum) return 0; } -int DoSumoDeathMelt(short SpriteNum) +int DoSumoDeathMelt(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); PlaySound(DIGI_SUMOFART, sp, v3df_follow); @@ -980,10 +972,8 @@ BossHealthMeter(void) static saveable_code saveable_sumo_code[] = { - SAVE_CODE(SetupSumo), SAVE_CODE(NullSumo), SAVE_CODE(DoSumoMove), - //SAVE_CODE(InitSumoCharge), SAVE_CODE(DoSumoRumble), SAVE_CODE(InitSumoFart), SAVE_CODE(InitSumoStomp), diff --git a/source/games/sw/src/swactor.h b/source/games/sw/src/swactor.h new file mode 100644 index 000000000..f2ade5a42 --- /dev/null +++ b/source/games/sw/src/swactor.h @@ -0,0 +1,206 @@ +#pragma once + +// included by game.h + +BEGIN_SW_NS + + +class DSWActor +{ + int index; + DSWActor* base(); + +public: + + int cumulDamage; + + DSWActor() :index(int(this - base())) { /*assert(index >= 0 && index < kMaxSprites);*/ } + DSWActor& operator=(const DSWActor& other) = default; + + void Clear() + { + } + bool hasU() { return User[index].Data() != nullptr; } + /* + void addU() + { + if (s().extra == -1) dbInsertXSprite(s().index); + } + */ + spritetype& s() { return sprite[index]; } + USER* u() { return User[index].Data(); } + + void SetOwner(DSWActor* own) + { + s().owner = own ? own->s().index : -1; + } + + DSWActor* GetOwner() + { + if (s().owner == -1 || s().owner == MAXSPRITES - 1) return nullptr; + return base() + s().owner; + } + + int GetSpriteIndex() const + { + return index; + } +}; + +extern DSWActor swActors[MAXSPRITES]; + +inline DSWActor* DSWActor::base() { return swActors; } + +// Iterator wrappers that return an actor pointer, not an index. +class SWStatIterator : public StatIterator +{ +public: + SWStatIterator(int stat) : StatIterator(stat) + { + } + + DSWActor* Next() + { + int n = NextIndex(); + return n >= 0 ? &swActors[n] : nullptr; + } + + DSWActor* Peek() + { + int n = PeekIndex(); + return n >= 0 ? &swActors[n] : nullptr; + } +}; + +class SWSectIterator : public SectIterator +{ +public: + SWSectIterator(int stat) : SectIterator(stat) + { + } + + DSWActor* Next() + { + int n = NextIndex(); + return n >= 0 ? &swActors[n] : nullptr; + } + + DSWActor* Peek() + { + int n = PeekIndex(); + return n >= 0 ? &swActors[n] : nullptr; + } +}; + +// An iterator to iterate over all sprites. +class SWSpriteIterator +{ + SWStatIterator it; + int stat = 0; + +public: + SWSpriteIterator() : it(0) {} + + DSWActor* Next() + { + while (stat < MAXSTATUS) + { + auto ac = it.Next(); + if (ac) return ac; + stat++; + if (stat < MAXSTATUS) it.Reset(stat); + } + return nullptr; + } +}; + +// For iterating linearly over map spawned sprites. +class SWLinearSpriteIterator +{ + int index = 0; +public: + + void Reset() + { + index = 0; + } + + DSWActor* Next() + { + while (index < MAXSPRITES) + { + auto p = &swActors[index++]; + if (p->s().statnum != MAXSTATUS) return p; + } + return nullptr; + } +}; + + +// Wrapper around the insane collision info mess from Build. +struct Collision +{ + int type; + int index; + int legacyVal; // should be removed later, but needed for converting back for unadjusted code. + DSWActor* actor; + + Collision() = default; + Collision(int legacyval) { setFromEngine(legacyval); } + + int setNone() + { + type = kHitNone; + index = -1; + legacyVal = 0; + actor = nullptr; + return kHitNone; + } + + int setSector(int num) + { + type = kHitSector; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitSector; + } + int setWall(int num) + { + type = kHitWall; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitWall; + } + int setSprite(DSWActor* num) + { + type = kHitSprite; + index = -1; + legacyVal = type | int(num - swActors); + actor = num; + return kHitSprite; + } + + int setFromEngine(int value) + { + legacyVal = value; + type = value & kHitTypeMask; + if (type == 0) { index = -1; actor = nullptr; } + else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; } + else { index = -1; actor = &swActors[value & kHitIndexMask]; } + return type; + } +}; + + +inline FSerializer& Serialize(FSerializer& arc, const char* keyname, DSWActor*& w, DSWActor** def) +{ + int index = w? int(w - swActors) : -1; + Serialize(arc, keyname, index, nullptr); + if (arc.isReading()) w = index == -1? nullptr : &swActors[index]; + return arc; +} + + +END_SW_NS diff --git a/source/games/sw/src/track.cpp b/source/games/sw/src/track.cpp index dda8f3b96..4acba88e3 100644 --- a/source/games/sw/src/track.cpp +++ b/source/games/sw/src/track.cpp @@ -44,10 +44,8 @@ BEGIN_SW_NS void DoTrack(SECTOR_OBJECTp sop, short locktics, int *nx, int *ny); void DoAutoTurretObject(SECTOR_OBJECTp sop); void DoTornadoObject(SECTOR_OBJECTp sop); -int DoActorMoveJump(short SpriteNum); int PickJumpSpeed(short SpriteNum, int pix_height); SPRITEp FindNearSprite(SPRITEp, short); -ANIMATOR DoActorMoveJump; ANIMATOR NinjaJumpActionFunc; #define ACTOR_STD_JUMP (-384) @@ -126,7 +124,7 @@ ActorFindTrack(short SpriteNum, int8_t player_dir, int track_type, short *track_ SPRITEp sp = User[SpriteNum]->SpriteP; int dist, near_dist = 999999, zdiff; - short track_sect=0; + int track_sect=0; short i; short end_point[2] = {0,0}; @@ -255,7 +253,7 @@ ActorFindTrack(short SpriteNum, int8_t player_dir, int track_type, short *track_ if (near_dist < 15000) { // get the sector number of the point - COVERupdatesector(near_tp->x, near_tp->y, &track_sect); + updatesector(near_tp->x, near_tp->y, &track_sect); // if can see the point, return the track number if (FAFcansee(sp->x, sp->y, sp->z - Z(16), sp->sectnum, near_tp->x, near_tp->y, sector[track_sect].floorz - Z(32), track_sect)) @@ -868,7 +866,7 @@ SectorObjectSetupBounds(SECTOR_OBJECTp sop) // each wall has this set - for collision detection SET(wall[k].extra, WALLFX_SECTOR_OBJECT|WALLFX_DONT_STICK); uint16_t const nextwall = wall[k].nextwall; - if (nextwall < MAXWALLS) + if (validWallIndex(nextwall)) SET(wall[nextwall].extra, WALLFX_SECTOR_OBJECT|WALLFX_DONT_STICK); } } @@ -969,7 +967,7 @@ SectorObjectSetupBounds(SECTOR_OBJECTp sop) break; } - ASSERT(sn < SIZ(sop->sp_num) - 1); + ASSERT(sn < (int)SIZ(sop->sp_num) - 1); sop->sp_num[sn] = sp_num; so_setspriteinterpolation(sop, sp); @@ -1674,7 +1672,7 @@ MovePlayer(PLAYERp pp, SECTOR_OBJECTp sop, int nx, int ny) // THIS WAS CAUSING PROLEMS!!!! // Sectors are still being manipulated so you can end up in a void (-1) sector - //COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + //updatesector(pp->posx, pp->posy, &pp->cursectnum); // New angle is formed by taking last known angle and // adjusting by the delta angle @@ -1711,7 +1709,7 @@ MovePoints(SECTOR_OBJECTp sop, short delta_ang, int nx, int ny) sop->sp_child->x = sop->xmid; sop->sp_child->y = sop->ymid; - //COVERupdatesector(sop->xmid, sop->ymid, &sop->sectnum); + //updatesector(sop->xmid, sop->ymid, &sop->sectnum); // setting floorz if need be //if (!TEST(sop->flags, SOBJ_SPRITE_OBJ)) @@ -1897,7 +1895,7 @@ PlayerPart: // prevents you from falling into map HOLEs created by moving // Sectors and sprites around. //if (sop->xmid < MAXSO) - COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); + updatesector(pp->posx, pp->posy, &pp->cursectnum); // in case you are in a whirlpool // move perfectly with the ride in the z direction @@ -2110,7 +2108,7 @@ DetectSectorObjectByWall(WALLp wph) if (TEST(wp->extra, WALLFX_LOOP_OUTER)) { uint16_t const nextwall = wp->nextwall; - if (nextwall < MAXWALLS && wph == &wall[nextwall]) + if (validWallIndex(nextwall) && wph == &wall[nextwall]) return sop; } @@ -2888,7 +2886,7 @@ void DoTornadoObject(SECTOR_OBJECTp sop) { int xvect,yvect; - short cursect; + int cursect; // this made them move together more or less - cool! //static short ang = 1024; int floor_dist; @@ -3087,6 +3085,7 @@ bool ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) { SPRITEp sp; + auto actor = &swActors[SpriteNum]; USERp u = User[SpriteNum].Data(); sp = u->SpriteP; @@ -3193,7 +3192,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) else u->jump_speed = -tpoint->tag_high; - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); u->ActorActionFunc = DoActorMoveJump; } @@ -3240,7 +3239,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) u->jump_speed = PickJumpSpeed(SpriteNum, zdiff); } - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); u->ActorActionFunc = DoActorMoveJump; return false; @@ -3252,8 +3251,6 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) if (u->ActorActionSet->Jump) { - int DoActorMoveJump(short SpriteNum); - sp->ang = tpoint->ang; ActorLeaveTrack(SpriteNum); @@ -3267,7 +3264,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) u->jump_speed = -350; } - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); u->ActorActionFunc = DoActorMoveJump; return false; } @@ -3288,8 +3285,6 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) if (u->Rot != u->ActorActionSet->Duck) { - int DoActorDuck(short SpriteNum); - sp->ang = tpoint->ang; ActorLeaveTrack(SpriteNum); @@ -3299,7 +3294,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) else u->WaitTics = tpoint->tag_high * 128; - InitActorDuck(SpriteNum); + InitActorDuck(actor); u->ActorActionFunc = DoActorDuck; return false; } @@ -3385,7 +3380,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) else u->jump_speed = -tpoint->tag_high; - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); } break; @@ -3398,7 +3393,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) else u->jump_speed = -tpoint->tag_high; - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); } break; @@ -3460,7 +3455,7 @@ ActorTrackDecide(TRACK_POINTp tpoint, short SpriteNum) SET(u->Flags, SPR_DEAD); sp->xvel <<= 1; u->jump_speed = -495; - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); NewStateGroup(SpriteNum, u->ActorActionSet->DeathJump); } @@ -3632,6 +3627,7 @@ present time. int ActorFollowTrack(short SpriteNum, short locktics) { + auto actor = &swActors[SpriteNum]; USERp u = User[SpriteNum].Data(); SPRITEp sp = User[SpriteNum]->SpriteP; PLAYERp pp; @@ -3767,7 +3763,7 @@ ActorFollowTrack(short SpriteNum, short locktics) DoActorSetSpeed(SpriteNum, SLOW_SPEED); u->ActorActionFunc = NinjaJumpActionFunc; u->jump_speed = -650; - DoActorBeginJump(SpriteNum); + DoActorBeginJump(actor); return true; } @@ -3803,11 +3799,8 @@ ActorFollowTrack(short SpriteNum, short locktics) static saveable_code saveable_track_code[] = { - SAVE_CODE(DoTrack), SAVE_CODE(DoTornadoObject), SAVE_CODE(DoAutoTurretObject), - SAVE_CODE(DoActorHitTrackEndPoint), - SAVE_CODE(CallbackSOsink), }; saveable_module saveable_track = diff --git a/source/games/sw/src/vator.cpp b/source/games/sw/src/vator.cpp index 7854d1e41..75bf26cf4 100644 --- a/source/games/sw/src/vator.cpp +++ b/source/games/sw/src/vator.cpp @@ -453,9 +453,10 @@ int DoVatorMove(short SpriteNum, int *lptr) } -int DoVator(short SpriteNum) +int DoVator(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = u->SpriteP; SECTORp sectp = §or[sp->sectnum]; int *lptr; @@ -622,9 +623,10 @@ int DoVator(short SpriteNum) return 0; } -int DoVatorAuto(short SpriteNum) +int DoVatorAuto(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = u->SpriteP; SECTORp sectp = §or[sp->sectnum]; int *lptr; @@ -680,16 +682,6 @@ int DoVatorAuto(short SpriteNum) static saveable_code saveable_vator_code[] = { - SAVE_CODE(ReverseVator), - SAVE_CODE(VatorSwitch), - SAVE_CODE(SetVatorActive), - SAVE_CODE(SetVatorInactive), - SAVE_CODE(DoVatorOperate), - SAVE_CODE(DoVatorMatch), - SAVE_CODE(TestVatorMatchActive), - SAVE_CODE(InterpSectorSprites), - SAVE_CODE(MoveSpritesWithSector), - SAVE_CODE(DoVatorMove), SAVE_CODE(DoVator), SAVE_CODE(DoVatorAuto), }; diff --git a/source/games/sw/src/warp.cpp b/source/games/sw/src/warp.cpp index 2b4bd0bd9..112269a7a 100644 --- a/source/games/sw/src/warp.cpp +++ b/source/games/sw/src/warp.cpp @@ -81,7 +81,7 @@ WarpPlaneSectorInfo(short sectnum, SPRITEp *sp_ceiling, SPRITEp *sp_floor) } SPRITEp -WarpPlane(int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum) +WarpPlane(int32_t* x, int32_t* y, int32_t* z, int* sectnum) { SPRITEp sp_floor, sp_ceiling; @@ -111,7 +111,7 @@ WarpPlane(int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum) } SPRITEp -WarpToArea(SPRITEp sp_from, int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum) +WarpToArea(SPRITEp sp_from, int32_t* x, int32_t* y, int32_t* z, int* sectnum) { int xoff; int yoff; @@ -183,7 +183,7 @@ WarpToArea(SPRITEp sp_from, int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum // exp: WARP_CEILING or WARP_CEILING_PLANE if (sp->hitag == to_tag) { - if ((unsigned)sp->sectnum >= MAXSECTORS) + if (!validSectorIndex(sp->sectnum)) return nullptr; // determine new x,y,z position @@ -245,7 +245,7 @@ WarpSectorInfo(short sectnum, SPRITEp *sp_warp) } SPRITEp -Warp(int32_t* x, int32_t* y, int32_t* z, int16_t* sectnum) +Warp(int32_t* x, int32_t* y, int32_t* z, int* sectnum) { SPRITEp sp_warp; diff --git a/source/games/sw/src/weapon.cpp b/source/games/sw/src/weapon.cpp index 83e79b7ab..640a1cb14 100644 --- a/source/games/sw/src/weapon.cpp +++ b/source/games/sw/src/weapon.cpp @@ -52,7 +52,6 @@ void VehicleSetSmoke(SECTOR_OBJECTp sop, ANIMATORp animator); ANIMATOR DoBettyBeginDeath; ANIMATOR DoSkullBeginDeath; ANIMATOR DoRipperGrow; -ANIMATOR InitMineShrap; // // Damage Amounts defined in damage.h @@ -94,20 +93,19 @@ int WeaponIsAmmo = BIT(WPN_STAR) | BIT(WPN_SWORD) | BIT(WPN_MINE) | BIT(WPN_FIST short target_ang; -ANIMATOR NullAnimator; ANIMATOR DoStar; ANIMATOR DoCrossBolt; ANIMATOR DoSuicide, DoUziSmoke; ANIMATOR DoShrapJumpFall; ANIMATOR DoFastShrapJumpFall; -int SpawnSmokePuff(short SpriteNum); +int SpawnSmokePuff(DSWActor* actor); bool WarpToUnderwater(short *sectnum, int *x, int *y, int *z); bool WarpToSurface(short *sectnum, int *x, int *y, int *z); short ElectroFindClosestEnemy(short SpriteNum); int InitElectroJump(SPRITEp wp, SPRITEp sp); bool TestDontStickSector(short hit_sect); -int SpawnShrapX(short SpriteNum); +ANIMATOR SpawnShrapX; bool WeaponMoveHit(short SpriteNum); int HelpMissileLateral(int16_t Weapon, int dist); void SpawnMidSplash(short SpriteNum); @@ -380,7 +378,7 @@ STATE s_TankShell[] = {TRACER + 0, 200, DoTankShell, &s_TankShell[0]} }; -ANIMATOR DoVehicleSmoke, SpawnVehicleSmoke; +ANIMATOR DoVehicleSmoke; #define VEHICLE_SMOKE_RATE 18 STATE s_VehicleSmoke[] = { @@ -1715,7 +1713,6 @@ STATE s_TracerExp[] = }; #define EXP_RATE_W 7 -ANIMATOR SpawnShrapX; ANIMATOR DoSectorExp; STATE s_SectorExp[] = @@ -2748,17 +2745,19 @@ bool MissileHitMatch(short Weapon, short WeaponNum, short hit_sprite) } #endif -int SpawnShrapX(short SpriteNum) +int SpawnShrapX(DSWActor* actor) { + USER* u = actor->u(); //For shrap that has no Weapon to send over - SpawnShrap(SpriteNum, -1); + SpawnShrap(u->SpriteNum, -1); return 0; } -int DoLavaErupt(short SpriteNum) +int DoLavaErupt(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); short i,pnum; PLAYERp pp; SPRITEp tsp; @@ -2823,10 +2822,10 @@ int DoLavaErupt(short SpriteNum) switch (SP_TAG3(sp)) { case 0: - SpawnShrapX(SpriteNum); + SpawnShrapX(actor); break; case 1: - InitVulcanBoulder(SpriteNum); + InitVulcanBoulder(actor); break; } } @@ -2836,12 +2835,6 @@ int DoLavaErupt(short SpriteNum) } -void UserShrapSetup(SHRAPp shrap, STATEp state, int num_shrap) -{ - shrap->state = state; - shrap->num = num_shrap; -} - #if 0 STATEp UserStateSetup(short base_tile, short num_tiles) { @@ -3890,10 +3883,11 @@ DoShrapMove(int16_t SpriteNum) #if 1 int -DoVomit(short SpriteNum) +DoVomit(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); u->Counter = NORM_ANGLE(u->Counter + (30*MISSILEMOVETICS)); sp->xrepeat = u->sx + MulScale(12, bcos(u->Counter), 14); @@ -3938,57 +3932,14 @@ DoVomit(short SpriteNum) return 0; } -#else -int -DoVomit(short SpriteNum) -{ - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - - u->Counter = NORM_ANGLE(u->Counter + (30*MISSILEMOVETICS)); - sp->xrepeat = u->sx + MulScale(12, bcos(u->Counter), 14); - sp->yrepeat = u->sy + MulScale(12, bsin(u->Counter), 14); - - if (TEST(u->Flags, SPR_JUMPING)) - { - DoShrapVelocity(SpriteNum); - } - else if (TEST(u->Flags, SPR_FALLING)) - { - DoShrapVelocity(SpriteNum); - } - else - { - ChangeState(SpriteNum, s_VomitSplash); - DoFindGroundPoint(SpriteNum); - MissileWaterAdjust(SpriteNum); - sp->z = u->loz; - u->WaitTics = 60; - u->sx = sp->xrepeat; - u->sy = sp->yrepeat; - return 0; - } - - if (TEST(u->ret, HIT_MASK) == HIT_SPRITE) - { - short hit_sprite = NORM_SPRITE(u->ret); - if (TEST(sprite[hit_sprite].extra, SPRX_PLAYER_OR_ENEMY)) - { - DoDamage(hit_sprite, SpriteNum); - //KillSprite(SpriteNum); - return 0; - } - } - - return 0; -} #endif int -DoVomitSplash(short SpriteNum) +DoVomitSplash(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if ((u->WaitTics-=MISSILEMOVETICS) < 0) { @@ -4000,12 +3951,13 @@ DoVomitSplash(short SpriteNum) } int -DoFastShrapJumpFall(short SpriteNum) +DoFastShrapJumpFall(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - sp->x += u->xchange*2; + sp->x += u->xchange*2; sp->y += u->ychange*2; sp->z += u->zchange*2; @@ -4017,10 +3969,11 @@ DoFastShrapJumpFall(short SpriteNum) } int -DoTracerShrap(short SpriteNum) +DoTracerShrap(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); sp->x += u->xchange; sp->y += u->ychange; @@ -4036,9 +3989,10 @@ DoTracerShrap(short SpriteNum) //#define ShrapKillSprite(num) _Shrap_Kill_Sprite(num, __FILE__, __LINE__) //#define DoShrapVelocity(num) _Do_Shrap_Velocity(num, __FILE__, __LINE__) int -DoShrapJumpFall(short SpriteNum) +DoShrapJumpFall(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (TEST(u->Flags, SPR_JUMPING)) { @@ -4067,10 +4021,11 @@ DoShrapJumpFall(short SpriteNum) } int -DoShrapDamage(short SpriteNum) +DoShrapDamage(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (TEST(u->Flags, SPR_JUMPING)) { @@ -4719,8 +4674,10 @@ WeaponMoveHit(short SpriteNum) } int -DoUziSmoke(short SpriteNum) +DoUziSmoke(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; //if (sp->picnum != nullptr) @@ -4731,8 +4688,10 @@ DoUziSmoke(short SpriteNum) } int -DoShotgunSmoke(short SpriteNum) +DoShotgunSmoke(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; //if (sp->picnum != nullptr) @@ -4743,23 +4702,26 @@ DoShotgunSmoke(short SpriteNum) } int -DoMineSpark(short SpriteNum) +DoMineSpark(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; if (sp->picnum != 0) { - DoDamageTest(SpriteNum); + DoDamageTest(actor); } return 0; } int -DoFireballFlames(short SpriteNum) +DoFireballFlames(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum],ap; - USERp u = User[SpriteNum].Data(); bool jumping = false; // if no owner then stay where you are @@ -4853,10 +4815,11 @@ DoFireballFlames(short SpriteNum) } int -DoBreakFlames(short SpriteNum) +DoBreakFlames(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); bool jumping = false; if (TEST(u->Flags, SPR_JUMPING)) @@ -4944,9 +4907,10 @@ SetSuicide(short SpriteNum) } int -DoActorScale(short SpriteNum) +DoActorScale(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; u->scale_speed = 70; @@ -4963,9 +4927,10 @@ DoActorScale(short SpriteNum) } int -DoRipperGrow(short SpriteNum) +DoRipperGrow(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; u->scale_speed = 70; @@ -5027,6 +4992,7 @@ void UpdateSinglePlayKills(short SpriteNum) int ActorChooseDeath(short SpriteNum, short Weapon) { + auto actor = &swActors[SpriteNum]; SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum].Data(); SPRITEp wp = &sprite[Weapon]; @@ -5091,12 +5057,12 @@ ActorChooseDeath(short SpriteNum, short Weapon) { case BETTY_R0: { - DoBettyBeginDeath(SpriteNum); + DoBettyBeginDeath(actor); break; } case SKULL_R0: { - DoSkullBeginDeath(SpriteNum); + DoSkullBeginDeath(actor); break; } case TOILETGIRL_R0: @@ -5233,7 +5199,7 @@ ActorChooseDeath(short SpriteNum, short Weapon) { if (wu->ID == BOLT_THINMAN_R1 && wu->Radius == RAIL_RADIUS) { - SpawnShrapX(Weapon); // Do rail gun shrap + SpawnShrapX(wu); // Do rail gun shrap } DoActorDie(SpriteNum, Weapon); @@ -5496,6 +5462,7 @@ ActorPain(short SpriteNum) int ActorPainPlasma(short SpriteNum) { + auto actor = &swActors[SpriteNum]; USERp u = User[SpriteNum].Data(); if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_ELECTRO_TOLERANT)) @@ -5509,7 +5476,7 @@ ActorPainPlasma(short SpriteNum) else { u->Vis = PLASMA_FOUNTAIN_TIME; - InitActorPause(SpriteNum); + InitActorPause(actor); } } @@ -5892,6 +5859,7 @@ objects. int DoDamage(short SpriteNum, short Weapon) { + auto actor = &swActors[SpriteNum]; SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum].Data(); SPRITEp wp; @@ -5910,6 +5878,7 @@ DoDamage(short SpriteNum, short Weapon) if (TEST(u->Flags, SPR_SUICIDE)) return 0; + auto weapActor = &swActors[Weapon]; wp = &sprite[Weapon]; wu = User[Weapon].Data(); @@ -6243,7 +6212,6 @@ DoDamage(short SpriteNum, short Weapon) } else if (u->PlayerP) { - extern int DoBunnyRipHeart(short SpriteNum); // Is the player blocking? if (u->PlayerP->WpnKungFuMove == 3) damage /= 3; @@ -6253,7 +6221,7 @@ DoDamage(short SpriteNum, short Weapon) PlayerUpdateHealth(u->PlayerP, damage); if (PlayerCheckDeath(u->PlayerP, Weapon)) { - DoBunnyRipHeart(Weapon); + DoBunnyRipHeart(weapActor); } } } @@ -7319,7 +7287,7 @@ DoDamage(short SpriteNum, short Weapon) } else if (u->ID == RIPPER_RUN_R0) { - DoRipperGrow(SpriteNum); + DoRipperGrow(actor); break; } @@ -7518,10 +7486,11 @@ const char *DeathString(short SpriteNum) #endif int -DoDamageTest(short Weapon) +DoDamageTest(DSWActor* actor) { - SPRITEp wp = &sprite[Weapon]; - USERp wu = User[Weapon].Data(); + auto wu = actor->u(); + int Weapon = wu->SpriteNum; + SPRITEp wp = &actor->s(); USERp u; SPRITEp sp; @@ -7683,30 +7652,29 @@ short StatBreakList[] = void TraverseBreakableWalls(short start_sect, int x, int y, int z, short ang, int radius) { - int WallBreakPosition(short hit_wall, short *sectnum, int *x, int *y, int *z, short *ang); int j, k; - short sectlist[MAXSECTORS]; // !JIM! Frank, 512 was not big enough for $dozer, was asserting out! - short sectlistplc, sectlistend, sect, startwall, endwall, nextsector; + int sect, startwall, endwall, nextsector; + unsigned sectlistplc, sectliststart; int xmid,ymid; int dist; short break_count; - short sectnum,wall_ang; + int sectnum; + short wall_ang; int hit_x,hit_y,hit_z; + - sectlist[0] = start_sect; - sectlistplc = 0; sectlistend = 1; + sectliststart = sectlistplc = GlobalSectorList.Size(); + GlobalSectorList.Push(start_sect); // limit radius if (radius > 2000) radius = 2000; break_count = 0; - while (sectlistplc < sectlistend) + while (sectlistplc < GlobalSectorList.Size()) { - sect = sectlist[sectlistplc++]; - - ASSERT((uint16_t)sectlistplc < SIZ(sectlist)); + sect = GlobalSectorList[sectlistplc++]; startwall = sector[sect].wallptr; endwall = startwall + sector[sect].wallnum; @@ -7717,8 +7685,8 @@ void TraverseBreakableWalls(short start_sect, int x, int y, int z, short ang, in if (wall[j].lotag == TAG_WALL_BREAK) { // find midpoint - xmid = DIV2(wall[j].x + wall[j+1].x); - ymid = DIV2(wall[j].y + wall[j+1].y); + xmid = (wall[j].x + wall[j+1].x) >> 1; + ymid = (wall[j].y + wall[j+1].y) >> 1; // don't need to go further if wall is too far out @@ -7735,7 +7703,10 @@ void TraverseBreakableWalls(short start_sect, int x, int y, int z, short ang, in break_count++; if (break_count > 4) + { + GlobalSectorList.Resize(sectliststart); return; + } } } } @@ -7746,28 +7717,29 @@ void TraverseBreakableWalls(short start_sect, int x, int y, int z, short ang, in continue; // make sure its not on the list - for (k = sectlistend - 1; k >= 0; k--) + for (k = GlobalSectorList.Size() - 1; k >= (int)sectliststart; k--) { - if (sectlist[k] == nextsector) + if (GlobalSectorList[k] == nextsector) break; } // if its not on the list add it to the end if (k < 0) { - sectlist[sectlistend++] = nextsector; - ASSERT((uint16_t)sectlistend < SIZ(sectlist)); + GlobalSectorList.Push(nextsector); } } } + GlobalSectorList.Resize(sectliststart); } -int DoExpDamageTest(short Weapon) +int DoExpDamageTest(DSWActor* actor) { + auto wu = actor->u(); + int Weapon = wu->SpriteNum; SPRITEp wp = &sprite[Weapon]; - USERp wu = User[Weapon].Data(); USERp u; SPRITEp sp; @@ -7917,10 +7889,11 @@ int DoExpDamageTest(short Weapon) } -int DoMineExpMine(short Weapon) +int DoMineExpMine(DSWActor* actor) { + auto wu = actor->u(); + int Weapon = wu->SpriteNum; SPRITEp wp = &sprite[Weapon]; - USERp wu = User[Weapon].Data(); USERp u; SPRITEp sp; @@ -7961,10 +7934,11 @@ int DoMineExpMine(short Weapon) } int -DoStar(int16_t Weapon) +DoStar(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); USERp su; int vel; @@ -8188,11 +8162,10 @@ DoStar(int16_t Weapon) } int -DoCrossBolt(int16_t Weapon) +DoCrossBolt(DSWActor* actor) { - USERp u = User[Weapon].Data(); - - u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; ASSERT(Weapon >= 0); @@ -8226,10 +8199,11 @@ DoCrossBolt(int16_t Weapon) int -DoPlasmaDone(int16_t Weapon) +DoPlasmaDone(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); sp->xrepeat += u->Counter; sp->yrepeat -= 4; @@ -8624,11 +8598,12 @@ InitPlasmaFountain(SPRITEp wp, SPRITEp sp) } int -DoPlasmaFountain(int16_t Weapon) +DoPlasmaFountain(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; SPRITEp ap; - USERp u = User[Weapon].Data(); short bak_cstat; // if no owner then die @@ -8673,10 +8648,11 @@ DoPlasmaFountain(int16_t Weapon) } int -DoPlasma(int16_t Weapon) +DoPlasma(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int32_t dax, day, daz; int ox,oy,oz; @@ -8752,10 +8728,11 @@ DoPlasma(int16_t Weapon) int -DoCoolgFire(int16_t Weapon) +DoCoolgFire(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); u->ret = move_missile(Weapon, u->xchange, u->ychange, u->zchange, u->ceiling_dist, u->floor_dist, CLIPMASK_MISSILE, MISSILEMOVETICS); @@ -8782,9 +8759,10 @@ DoCoolgFire(int16_t Weapon) } int -DoEelFire(short Weapon) +DoEelFire(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; if (TEST(u->Flags, SPR_UNDERWATER) && (RANDOM_P2(1024 << 4) >> 4) < 256) SpawnBubble(Weapon); @@ -8920,10 +8898,11 @@ bool SlopeBounce(short SpriteNum, bool *hit_wall) extern STATE s_Phosphorus[]; int -DoGrenade(int16_t Weapon) +DoGrenade(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); short i; if (TEST(u->Flags, SPR_UNDERWATER)) @@ -9167,10 +9146,11 @@ DoGrenade(int16_t Weapon) } int -DoVulcanBoulder(int16_t Weapon) +DoVulcanBoulder(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); u->Counter += 40; u->zchange += u->Counter; @@ -9393,10 +9373,11 @@ DoMineRangeTest(short Weapon, short range) int -DoMineStuck(int16_t Weapon) +DoMineStuck(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); #define MINE_DETONATE_STATE 99 // if no owner then die @@ -9575,10 +9556,11 @@ SetMineStuck(int16_t Weapon) } int -DoMine(int16_t Weapon) +DoMine(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); if (TEST(u->Flags, SPR_UNDERWATER)) { @@ -9738,11 +9720,12 @@ DoMine(int16_t Weapon) } int -DoPuff(short SpriteNum) +DoPuff(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - + sp->x += u->xchange; sp->y += u->ychange; sp->z += u->zchange; @@ -9751,8 +9734,10 @@ DoPuff(short SpriteNum) } int -DoRailPuff(short SpriteNum) +DoRailPuff(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; sp->xrepeat += 4; @@ -9762,10 +9747,11 @@ DoRailPuff(short SpriteNum) } int -DoBoltThinMan(int16_t Weapon) +DoBoltThinMan(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int32_t dax, day, daz; DoBlurExtend(Weapon, 0, 4); @@ -9801,10 +9787,11 @@ DoBoltThinMan(int16_t Weapon) } int -DoTracer(int16_t Weapon) +DoTracer(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); short i; for (i = 0; i < 4; i++) @@ -9829,10 +9816,11 @@ DoTracer(int16_t Weapon) } int -DoEMP(int16_t Weapon) +DoEMP(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); short i; for (i = 0; i < 4; i++) @@ -9868,10 +9856,11 @@ DoEMP(int16_t Weapon) } int -DoEMPBurst(int16_t Weapon) +DoEMPBurst(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); if (u->Attach >= 0) { @@ -9905,7 +9894,7 @@ DoEMPBurst(int16_t Weapon) if ((RANDOM_P2(1024<<6)>>6) < 700) { - SpawnShrapX(Weapon); + SpawnShrapX(actor); } u->WaitTics -= (MISSILEMOVETICS * 2); @@ -9922,9 +9911,10 @@ DoEMPBurst(int16_t Weapon) } int -DoTankShell(int16_t Weapon) +DoTankShell(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; short i; for (i = 0; i < 4; i++) @@ -9949,10 +9939,10 @@ DoTankShell(int16_t Weapon) } int -DoTracerStart(int16_t Weapon) +DoTracerStart(DSWActor* actor) { - USERp u = User[Weapon].Data(); - + USER* u = actor->u(); + int Weapon = u->SpriteNum; u->ret = move_missile(Weapon, u->xchange, u->ychange, u->zchange, u->ceiling_dist, u->floor_dist, CLIPMASK_MISSILE, MISSILEMOVETICS); @@ -9971,10 +9961,11 @@ DoTracerStart(int16_t Weapon) } int -DoLaser(int16_t Weapon) +DoLaser(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); SPRITEp np; USERp nu; short New; @@ -10020,9 +10011,10 @@ DoLaser(int16_t Weapon) } int -DoLaserStart(int16_t Weapon) +DoLaserStart(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; if (SW_SHAREWARE) return false; // JBF: verify @@ -10044,10 +10036,11 @@ DoLaserStart(int16_t Weapon) } int -DoRail(int16_t Weapon) +DoRail(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); SPRITEp np; USERp nu; short New; @@ -10075,14 +10068,14 @@ DoRail(int16_t Weapon) short cstat_save = sprite[hit_sprite].cstat; RESET(sprite[hit_sprite].cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN|CSTAT_SPRITE_BLOCK_MISSILE); - DoRail(Weapon); + DoRail(actor); sprite[hit_sprite].cstat = cstat_save; return true; } else { SpawnTracerExp(Weapon); - SpawnShrapX(Weapon); + SpawnShrapX(actor); KillSprite((short) Weapon); return true; } @@ -10090,7 +10083,7 @@ DoRail(int16_t Weapon) else { SpawnTracerExp(Weapon); - SpawnShrapX(Weapon); + SpawnShrapX(actor); KillSprite((short) Weapon); return true; } @@ -10133,9 +10126,10 @@ DoRail(int16_t Weapon) } int -DoRailStart(int16_t Weapon) +DoRailStart(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; if (SW_SHAREWARE) return false; // JBF: verify @@ -10148,7 +10142,7 @@ DoRailStart(int16_t Weapon) if (WeaponMoveHit(Weapon)) { SpawnTracerExp(Weapon); - SpawnShrapX(Weapon); + SpawnShrapX(actor); KillSprite((short) Weapon); return true; } @@ -10158,10 +10152,11 @@ DoRailStart(int16_t Weapon) } int -DoRocket(int16_t Weapon) +DoRocket(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int dist,a,b,c; auto pos = sp->pos; @@ -10246,9 +10241,10 @@ DoRocket(int16_t Weapon) } int -DoMicroMini(int16_t Weapon) +DoMicroMini(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; short i; for (i = 0; i < 3; i++) @@ -10272,10 +10268,11 @@ DoMicroMini(int16_t Weapon) } int -SpawnExtraMicroMini(int16_t Weapon) +SpawnExtraMicroMini(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); SPRITEp wp; USERp wu; short w; @@ -10311,10 +10308,11 @@ SpawnExtraMicroMini(int16_t Weapon) } int -DoMicro(int16_t Weapon) +DoMicro(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); short New; if (SW_SHAREWARE) return false; // JBF: verify @@ -10365,7 +10363,7 @@ DoMicro(int16_t Weapon) NewStateGroup(Weapon, &sg_MicroMini[0]); sp->xrepeat = sp->yrepeat = 10; RESET(sp->cstat, CSTAT_SPRITE_INVISIBLE); - SpawnExtraMicroMini(Weapon); + SpawnExtraMicroMini(actor); return true; } } @@ -10386,10 +10384,11 @@ DoMicro(int16_t Weapon) } int -DoUziBullet(int16_t Weapon) +DoUziBullet(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int32_t dax, day, daz; int sx,sy; short i; @@ -10458,10 +10457,11 @@ DoUziBullet(int16_t Weapon) int -DoBoltSeeker(int16_t Weapon) +DoBoltSeeker(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int32_t dax, day, daz; MissileSeek(Weapon, 30, 768/*, 4, 48, 6*/); @@ -10493,22 +10493,23 @@ DoBoltSeeker(int16_t Weapon) } int -DoBoltShrapnel(int16_t Weapon) +DoBoltShrapnel(DSWActor* actor) { return 0; } int -DoBoltFatMan(int16_t Weapon) +DoBoltFatMan(DSWActor* actor) { return 0; } int -DoElectro(int16_t Weapon) +DoElectro(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int32_t dax, day, daz; DoBlurExtend(Weapon, 0, 4); @@ -10562,9 +10563,10 @@ DoElectro(int16_t Weapon) } int -DoLavaBoulder(int16_t Weapon) +DoLavaBoulder(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; u->ret = move_missile(Weapon, u->xchange, u->ychange, u->zchange, u->ceiling_dist, u->floor_dist, CLIPMASK_MISSILE, MISSILEMOVETICS); @@ -10591,9 +10593,10 @@ DoLavaBoulder(int16_t Weapon) } int -DoSpear(int16_t Weapon) +DoSpear(DSWActor* actor) { - USERp u = User[Weapon].Data(); + USER* u = actor->u(); + int Weapon = u->SpriteNum; u->ret = move_missile(Weapon, u->xchange, u->ychange, u->zchange, u->ceiling_dist, u->floor_dist, CLIPMASK_MISSILE, MISSILEMOVETICS); @@ -10621,9 +10624,11 @@ DoSpear(int16_t Weapon) return false; } -int SpawnCoolieExp(short SpriteNum) +int SpawnCoolieExp(DSWActor* actor) { - USERp u = User[SpriteNum].Data(), eu; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + USERp eu; SPRITEp sp = &sprite[SpriteNum]; short explosion; @@ -10642,6 +10647,7 @@ int SpawnCoolieExp(short SpriteNum) explosion = SpawnSprite(STAT_MISSILE, BOLT_EXP, s_BoltExp, sp->sectnum, nx, ny, zh, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -10654,7 +10660,7 @@ int SpawnCoolieExp(short SpriteNum) eu->Radius = DamageData[DMG_BOLT_EXP].radius; - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); return explosion; } @@ -10678,6 +10684,7 @@ SpawnBasicExp(int16_t Weapon) explosion = SpawnSprite(STAT_MISSILE, BASIC_EXP, s_BasicExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -10697,7 +10704,7 @@ SpawnBasicExp(int16_t Weapon) // SpawnExpZadjust(Weapon, exp, Z(15), Z(15)); - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); SpawnVis(-1, exp->sectnum, exp->x, exp->y, exp->z, 16); return explosion; @@ -11031,6 +11038,7 @@ SpawnBoltExp(int16_t Weapon) explosion = SpawnSprite(STAT_MISSILE, BOLT_EXP, s_BoltExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11047,7 +11055,7 @@ SpawnBoltExp(int16_t Weapon) SpawnExpZadjust(Weapon, exp, Z(40), Z(40)); - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); SetExpQuake(explosion); // !JIM! made rocket launcher shake things SpawnVis(-1, exp->sectnum, exp->x, exp->y, exp->z, 16); @@ -11058,6 +11066,7 @@ SpawnBoltExp(int16_t Weapon) int SpawnBunnyExp(int16_t Weapon) { + auto actor = &swActors[Weapon]; SPRITEp sp = &sprite[Weapon]; USERp u = User[Weapon].Data(); @@ -11072,7 +11081,7 @@ SpawnBunnyExp(int16_t Weapon) InitBloodSpray(Weapon,true,-1); InitBloodSpray(Weapon,true,-1); InitBloodSpray(Weapon,true,-1); - DoExpDamageTest(Weapon); + DoExpDamageTest(actor); return 0; } @@ -11095,6 +11104,7 @@ SpawnTankShellExp(int16_t Weapon) explosion = SpawnSprite(STAT_MISSILE, TANK_SHELL_EXP, s_TankShellExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11110,7 +11120,7 @@ SpawnTankShellExp(int16_t Weapon) eu->Radius = DamageData[DMG_TANK_SHELL_EXP].radius; SpawnExpZadjust(Weapon, exp, Z(40), Z(40)); - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); SpawnVis(-1, exp->sectnum, exp->x, exp->y, exp->z, 16); return explosion; @@ -11217,6 +11227,7 @@ SpawnNuclearExp(int16_t Weapon) // Do central explosion explosion = SpawnSprite(STAT_MISSILE, MUSHROOM_CLOUD, s_GrenadeExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11233,7 +11244,7 @@ SpawnNuclearExp(int16_t Weapon) SpawnExpZadjust(Weapon, exp, Z(30), Z(30)); - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); // Nuclear effects SetNuclearQuake(explosion); @@ -11279,6 +11290,7 @@ SpawnTracerExp(int16_t Weapon) explosion = SpawnSprite(STAT_MISSILE, TRACER_EXP, s_TracerExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11296,7 +11308,7 @@ SpawnTracerExp(int16_t Weapon) if (u->ID == BOLT_THINMAN_R1) { eu->Radius = DamageData[DMG_BASIC_EXP].radius; - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); } else eu->Radius = DamageData[DMG_BOLT_EXP].radius; @@ -11512,12 +11524,13 @@ SpawnGrenadeSecondaryExp(int16_t Weapon, short ang) } int -SpawnGrenadeSmallExp(int16_t Weapon) +SpawnGrenadeSmallExp(DSWActor* actor) { + USER* u = actor->u(); short ang; ang = RANDOM_P2(2048); - SpawnGrenadeSecondaryExp(Weapon, ang); + SpawnGrenadeSecondaryExp(u->SpriteNum, ang); return 0; } @@ -11559,6 +11572,7 @@ SpawnGrenadeExp(int16_t Weapon) explosion = SpawnSprite(STAT_MISSILE, GRENADE_EXP, s_GrenadeExp, sp->sectnum, dx, dy, dz, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11579,8 +11593,7 @@ SpawnGrenadeExp(int16_t Weapon) SpawnExpZadjust(Weapon, exp, Z(100), Z(30)); - DoExpDamageTest(explosion); - //InitMineShrap(explosion); + DoExpDamageTest(expActor); SetExpQuake(explosion); SpawnVis(-1, exp->sectnum, exp->x, exp->y, exp->z, 0); @@ -11686,77 +11699,23 @@ SpawnMineExp(int16_t Weapon) SetExpQuake(explosion); - //DoExpDamageTest(explosion); + //DoExpDamageTest(expActor); return explosion; } -int -InitMineShrap(short SpriteNum) +int DoMineExp(DSWActor* actor) { - SPRITEp sp = &sprite[SpriteNum]; - SPRITEp wp; - short ang, w, i; - hitdata_t hitinfo; - int daz; - - for (i = 0; i < 18; i++) - { - ang = RANDOM_P2(2048); - daz = Z(RANDOM_P2(48))<<3; - daz -= DIV2(Z(48)<<3); - - FAFhitscan(sp->x, sp->y, sp->z - Z(30), sp->sectnum, // Start position - bcos(ang), // X vector of 3D ang - bsin(ang), // Y vector of 3D ang - daz, // Z vector of 3D ang - &hitinfo, CLIPMASK_MISSILE); - - if (hitinfo.sect < 0) - continue; - - - // check to see what you hit - if (hitinfo.sprite < 0 && hitinfo.wall < 0) - { - } - -#define MINE_SHRAP_DIST_MAX 20000 - if (Distance(hitinfo.pos.x, hitinfo.pos.y, sp->x, sp->y) > MINE_SHRAP_DIST_MAX) - continue; - - w = SpawnSprite(STAT_MISSILE, MINE_SHRAP, s_MineSpark, hitinfo.sect, hitinfo.pos.x, hitinfo.pos.y, hitinfo.pos.z, ang, 0); - wp = &sprite[w]; - wp->shade = -40; - wp->hitag = LUMINOUS; //Always full brightness - SetOwner(sp->owner, w); - SET(wp->cstat, CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_YCENTER); - - wp->clipdist = 32 >> 2; - - HitscanSpriteAdjust(w, hitinfo.wall); - } - - return 0; -} - -int DoMineExp(short SpriteNum) -{ - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - - DoExpDamageTest(SpriteNum); - //InitMineShrap(SpriteNum); - + DoExpDamageTest(actor); return 0; } int -DoSectorExp(int16_t SpriteNum) +DoSectorExp(DSWActor* actor) { - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + SPRITEp sp = &sprite[u->SpriteNum]; sp->x += u->xchange; sp->y += u->ychange; @@ -11781,6 +11740,7 @@ SpawnSectorExp(int16_t Weapon) explosion = SpawnSprite(STAT_MISSILE, GRENADE_EXP, s_SectorExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11793,7 +11753,7 @@ SpawnSectorExp(int16_t Weapon) RESET(exp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); eu->Radius = DamageData[DMG_SECTOR_EXP].radius; - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); SetExpQuake(explosion); SpawnVis(-1, exp->sectnum, exp->x, exp->y, exp->z, 16); @@ -11813,6 +11773,7 @@ SpawnLargeExp(int16_t Weapon) explosion = SpawnSprite(STAT_MISSILE, GRENADE_EXP, s_SectorExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11828,7 +11789,7 @@ SpawnLargeExp(int16_t Weapon) SpawnExpZadjust(Weapon, exp, Z(50), Z(50)); // Should not cause other sectors to explode - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); SetExpQuake(explosion); SpawnVis(-1, exp->sectnum, exp->x, exp->y, exp->z, 16); @@ -11897,6 +11858,7 @@ SpawnLittleExp(int16_t Weapon) PlaySound(DIGI_HEADSHOTHIT, sp, v3df_none); explosion = SpawnSprite(STAT_MISSILE, BOLT_EXP, s_SectorExp, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); + auto expActor = &swActors[explosion]; exp = &sprite[explosion]; eu = User[explosion].Data(); @@ -11907,17 +11869,18 @@ SpawnLittleExp(int16_t Weapon) SET(exp->cstat, CSTAT_SPRITE_YCENTER); RESET(exp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); eu->Radius = DamageData[DMG_BASIC_EXP].radius; - DoExpDamageTest(explosion); + DoExpDamageTest(expActor); SpawnVis(-1, exp->sectnum, exp->x, exp->y, exp->z, 16); return explosion; } int -DoFireball(int16_t Weapon) +DoFireball(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); u = User[Weapon].Data(); @@ -11928,7 +11891,7 @@ DoFireball(int16_t Weapon) sp->xrepeat = sp->yrepeat -= 1; if (sp->xrepeat <= 37) { - SpawnSmokePuff(Weapon); + SpawnSmokePuff(actor); KillSprite(Weapon); return true; } @@ -12017,7 +11980,7 @@ DoFindGround(int16_t SpriteNum) save_cstat = sp->cstat; RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); - FAFgetzrange(sp->x, sp->y, sp->z, sp->sectnum, &u->hiz, &ceilhit, &u->loz, &florhit, (((int) sp->clipdist) << 2) - GETZRANGE_CLIP_ADJ, CLIPMASK_PLAYER); + FAFgetzrange(sp->pos, sp->sectnum, &u->hiz, &ceilhit, &u->loz, &florhit, (((int) sp->clipdist) << 2) - GETZRANGE_CLIP_ADJ, CLIPMASK_PLAYER); sp->cstat = save_cstat; ASSERT(TEST(florhit, HIT_SPRITE | HIT_SECTOR)); @@ -12122,10 +12085,12 @@ DoFindGroundPoint(int16_t SpriteNum) } int -DoNapalm(int16_t Weapon) +DoNapalm(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon], exp; - USERp u = User[Weapon].Data(); + short explosion; int ox, oy, oz; @@ -12138,7 +12103,7 @@ DoNapalm(int16_t Weapon) sp->xrepeat = sp->yrepeat -= 1; if (sp->xrepeat <= 30) { - SpawnSmokePuff(Weapon); + SpawnSmokePuff(actor); KillSprite(Weapon); return true; } @@ -12238,15 +12203,16 @@ DoNapalm(int16_t Weapon) #if WORM == 1 int -DoBloodWorm(int16_t Weapon) +DoBloodWorm(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); short ang; int xvect,yvect; int bx,by; int amt; - short sectnum; + int sectnum; u = User[Weapon].Data(); @@ -12328,149 +12294,19 @@ DoBloodWorm(int16_t Weapon) } #endif -#if WORM == 2 -int -DoBloodWorm(int16_t Weapon) -{ - SPRITEp sp = &sprite[Weapon], exp; - USERp u = User[Weapon].Data(); - int offset; - short ang; - int x,y,z,xvect,yvect; - int bx,by; - int amt; - short sectnum; - - u = User[Weapon].Data(); - - u->ret = move_missile(Weapon, u->xchange, u->ychange, u->zchange, u->ceiling_dist, u->floor_dist, CLIPMASK_MISSILE, MISSILEMOVETICS); - - // stay on ground - sp->z = u->loz - Z(32); - - if (u->ret) - { - switch (TEST(u->ret, HIT_MASK)) - { - - case HIT_PLAX_WALL: - KillSprite(Weapon); - return true; - - case HIT_SPRITE: - case HIT_WALL: - { - u->xchange = -u->xchange; - u->ychange = -u->ychange; - u->ret = 0; - sp->ang = NORM_ANGLE(sp->ang + 1024); - break; - } - - case HIT_SECTOR: - { - sp->z -= Z(32); - - u->xchange = -u->xchange; - u->ychange = -u->ychange; - u->ret = 0; - sp->ang = NORM_ANGLE(sp->ang + 1024); - break; - } - - } - } - - if (++u->Counter3 > 3) - { - SPRITEp tsp; - USERp tu; - int i; - - InitBloodSpray(Weapon, false, 1); - InitBloodSpray(Weapon, false, 1); - - // Kill any old zombies you own - StatIterator it(STAT_ENEMY); - while ((i = it.NextIndex()) >= 0) - { - tsp = &sprite[i]; - tu = User[i].Data(); - - ASSERT(tu); - - if (tu->ID == ZOMBIE_RUN_R0 && tsp->owner == sp->owner) - { - InitBloodSpray(i,true,105); - InitBloodSpray(i,true,105); - SetSuicide(i); - break; - } - } - - SpawnZombie2(Weapon); - KillSprite(Weapon); - return true; - } - - ang = NORM_ANGLE(sp->ang + 512); - - xvect = bcos(ang); - yvect = bsin(ang); - - bx = sp->x; - by = sp->y; - - amt = RANDOM_P2(2048) - 1024; - sp->x += MulScale(amt,xvect, 15); - sp->y += MulScale(amt,yvect, 15); - - sectnum = sp->sectnum; - updatesectorz(sp->x, sp->y, sp->z, §num); - if (sectnum >= 0) - { - //GlobalSkipZrange = true; - InitBloodSpray(Weapon, false, 1); - //GlobalSkipZrange = false; - } - - if (RANDOM_P2(2048) < 512) - { - sp->x = bx; - sp->y = by; - - amt = RANDOM_P2(2048) - 1024; - sp->x += MulScale(amt,xvect, 15); - sp->y += MulScale(amt,yvect, 15); - - sectnum = sp->sectnum; - updatesectorz(sp->x, sp->y, sp->z, §num); - if (sectnum >= 0) - { - //GlobalSkipZrange = true; - InitBloodSpray(Weapon, false, 1); - //GlobalSkipZrange = false; - } - } - - sp->x = bx; - sp->y = by; - - return false; -} -#endif int -DoMeteor(int16_t Weapon) +DoMeteor(DSWActor* actor) { return false; } int -DoSerpMeteor(int16_t Weapon) +DoSerpMeteor(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); int ox, oy, oz; ox = sp->x; @@ -12525,12 +12361,11 @@ DoSerpMeteor(int16_t Weapon) int -DoMirvMissile(int16_t Weapon) +DoMirvMissile(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); - - u = User[Weapon].Data(); sp->xrepeat += MISSILEMOVETICS * 2; if (sp->xrepeat > 80) @@ -12558,15 +12393,15 @@ DoMirvMissile(int16_t Weapon) } int -DoMirv(int16_t Weapon) +DoMirv(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon], np; - USERp u = User[Weapon].Data(), nu; + USERp nu; short New; // int ox, oy, oz; - u = User[Weapon].Data(); - // ox = sp->x; // oy = sp->y; // oz = sp->z; @@ -12666,6 +12501,7 @@ bool MissileSetPos(short Weapon, ANIMATORp DoWeapon, int dist) { SPRITEp wp = &sprite[Weapon]; + auto actor = &swActors[Weapon]; USERp wu = User[Weapon].Data(); int oldvel, oldzvel; int oldxc, oldyc, oldzc; @@ -12689,7 +12525,7 @@ MissileSetPos(short Weapon, ANIMATORp DoWeapon, int dist) wu->zchange = wp->zvel; SET(wu->Flags, SPR_SET_POS_DONT_KILL); - if ((*DoWeapon)(Weapon)) + if ((*DoWeapon)(actor)) retval = true; RESET(wu->Flags, SPR_SET_POS_DONT_KILL); @@ -12709,6 +12545,7 @@ MissileSetPos(short Weapon, ANIMATORp DoWeapon, int dist) bool TestMissileSetPos(short Weapon, ANIMATORp DoWeapon, int dist, int zvel) { + auto actor = &swActors[Weapon]; SPRITEp wp = &sprite[Weapon]; USERp wu = User[Weapon].Data(); int oldvel, oldzvel; @@ -12733,7 +12570,7 @@ TestMissileSetPos(short Weapon, ANIMATORp DoWeapon, int dist, int zvel) wu->zchange = zvel; SET(wu->Flags, SPR_SET_POS_DONT_KILL); - if ((*DoWeapon)(Weapon)) + if ((*DoWeapon)(actor)) retval = true; RESET(wu->Flags, SPR_SET_POS_DONT_KILL); @@ -12751,10 +12588,11 @@ TestMissileSetPos(short Weapon, ANIMATORp DoWeapon, int dist, int zvel) } int -DoRing(int16_t Weapon) +DoRing(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); PLAYERp pp = User[sp->owner]->PlayerP; SPRITEp so = &sprite[sp->owner]; int cz,fz; @@ -12770,7 +12608,7 @@ DoRing(int16_t Weapon) sp->xrepeat = sp->yrepeat -= 1; if (sp->xrepeat <= 30) { - SpawnSmokePuff(Weapon); + SpawnSmokePuff(actor); KillSprite(Weapon); return true; } @@ -12839,7 +12677,7 @@ DoRing(int16_t Weapon) } // Done last - check for damage - DoDamageTest(Weapon); + DoDamageTest(actor); return 0; } @@ -12915,10 +12753,11 @@ InitSpellRing(PLAYERp pp) } int -DoSerpRing(int16_t Weapon) +DoSerpRing(DSWActor* actor) { + USER* u = actor->u(); + int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - USERp u = User[Weapon].Data(); USERp ou = User[sp->owner].Data(); int dist,a,b,c; int cz,fz; @@ -12928,7 +12767,7 @@ DoSerpRing(int16_t Weapon) if (sp->owner == -1 || ou->RotNum < 5) { UpdateSinglePlayKills(Weapon); - DoSkullBeginDeath(Weapon); + DoSkullBeginDeath(actor); // +2 does not spawn shrapnel u->ID = SKULL_SERP; return 0; @@ -12993,8 +12832,8 @@ DoSerpRing(int16_t Weapon) // if ((dist ok and random ok) OR very few skulls left) if ((dist < 18000 && (RANDOM_P2(2048<<5)>>5) < 16) || User[sp->owner]->Counter < 4) { - short sectnum = sp->sectnum; - COVERupdatesector(sp->x,sp->y,§num); + int sectnum = sp->sectnum; + updatesector(sp->x,sp->y,§num); // if (valid sector and can see target) if (sectnum != -1 && CanSeePlayer(Weapon)) @@ -13033,16 +12872,18 @@ DoSerpRing(int16_t Weapon) } int -InitLavaFlame(short SpriteNum) +InitLavaFlame(DSWActor* actor) { return 0; } int -InitLavaThrow(short SpriteNum) +InitLavaThrow(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz, dist, nang; short w; @@ -13097,8 +12938,10 @@ InitLavaThrow(short SpriteNum) } int -InitVulcanBoulder(short SpriteNum) +InitVulcanBoulder(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; USERp wu; int nx, ny, nz, nang; @@ -13171,67 +13014,13 @@ InitVulcanBoulder(short SpriteNum) return w; } -#if 0 int -InitSerpRing(short SpriteNum) +InitSerpRing(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP, np; - USERp u = User[SpriteNum].Data(), nu; - short ang, ang_diff, ang_start, ang_finish, missiles, NewSprite; - short max_missiles = 16; - - u->Counter = max_missiles; - - ang_diff = 2048 / max_missiles; - - ang_start = NORM_ANGLE(sp->ang - DIV2(2048)); - - if (!SW_SHAREWARE) - PlaySound(DIGI_RFWIZ, sp, v3df_none); - - for (missiles = 0, ang = ang_start; missiles < max_missiles; ang += ang_diff, missiles++) - { - NewSprite = SpawnSprite(STAT_MISSILE_SKIP4, FIREBALL1, s_Ring2, sp->sectnum, sp->x, sp->y, SPRITEp_TOS(sp)+Z(20), ang, 0); - - np = &sprite[NewSprite]; - - np->hitag = LUMINOUS; //Always full brightness - np->xvel = 500; - SetOwner(SpriteNum, NewSprite); - np->shade = -40; - np->xrepeat = 32; - np->yrepeat = 32; - np->zvel = 0; - - nu = User[NewSprite]; - - nu->sz = Z(20); - nu->Dist = 800; - nu->Counter = max_missiles; - nu->Counter2 = 0; - nu->ceiling_dist = Z(10); - nu->floor_dist = Z(10); - nu->spal = np->pal = 27; // Bright Green - - // put it out there - np->x += MulScale(nu->Dist, bcos(np->ang), 14); - np->y += MulScale(nu->Dist, bsin(np->ang), 14); - np->z = SPRITEp_TOS(sp) + Z(20); - - np->ang = NORM_ANGLE(np->ang + 512); - - np->backuppos(); - - if (SpriteInUnderwaterArea(sp)) - SET(nu->Flags, SPR_UNDERWATER); - } -} -#else -int -InitSerpRing(short SpriteNum) -{ - SPRITEp sp = User[SpriteNum]->SpriteP, np; - USERp u = User[SpriteNum].Data(), nu; + USERp nu; short ang, ang_diff, ang_start, missiles, New; short max_missiles; @@ -13300,86 +13089,6 @@ InitSerpRing(short SpriteNum) } return 0; } -#endif - -#if 0 -int -InitSerpRing2(short SpriteNum) -{ - SPRITEp sp = User[SpriteNum]->SpriteP, np; - USERp u = User[SpriteNum].Data(), nu; - short ang, ang_diff, ang_start, ang_finish, missiles, New; - short max_missiles; - short i; - - extern STATE s_SkullExplode[]; - extern STATE s_SkullRing[5][1]; - extern STATEp sg_SkullRing[]; - -#define NUM_SERP_RING 2 - - static int zpos[NUM_SERP_RING] = {Z(25), Z(130)}; - - PlaySound(DIGI_SERPSUMMONHEADS, sp, v3df_none); - - for (i = 0; i < NUM_SERP_RING; i++) - { - max_missiles = 12; - - ang_diff = 2048 / max_missiles; - - ang_start = i * (2048/NUM_SERP_RING); //NORM_ANGLE(sp->ang - DIV2(2048)); - - for (missiles = 0, ang = ang_start; missiles < max_missiles; ang += ang_diff, missiles++) - { - New = SpawnSprite(STAT_MISSILE_SKIP4, SKULL_SERP, &s_SkullRing[0][0], sp->sectnum, sp->x, sp->y, sp->z, ang, 0); - - np = &sprite[New]; - nu = User[New].Data(); - - //np->owner = SpriteNum; - SetOwner(SpriteNum, New); - np->shade = -20; - np->xrepeat = 64; - np->yrepeat = 64; - np->zvel = Z(10); - np->yvel = 4*RINGMOVETICS; - np->pal = 0; - - np->z = SPRITEp_TOS(sp) - Z(20); - nu->sz = zpos[i]; //Z(20) + (i * (SPRITEp_SIZE_Z(sp)/NUM_SERP_RING)); - - // ang around the serp is now slide_ang - nu->slide_ang = np->ang; - // randomize the head turning angle - np->ang = RANDOM_P2(2048<<5)>>5; - - // control direction of spinning - FLIP(u->Flags, SPR_BOUNCE); - SET(nu->Flags, TEST(u->Flags, SPR_BOUNCE)); - - nu->Dist = 400; - nu->TargetDist = 2500; - nu->Counter2 = 0; - - nu->StateEnd = s_SkullExplode; - nu->Rot = sg_SkullRing; - - // defaults do change the statnum - EnemyDefaults(New, nullptr, nullptr); - RESET(np->extra, SPRX_PLAYER_OR_ENEMY); - change_sprite_stat(New, STAT_MISSILE_SKIP4); - - np->clipdist = (128+64) >> 2; - SET(nu->Flags, SPR_XFLIP_TOGGLE); - SET(np->cstat, CSTAT_SPRITE_YCENTER); - - nu->Radius = 400; - } - } - return 0; -} -#endif void InitSpellNapalm(PLAYERp pp) @@ -13478,11 +13187,13 @@ InitSpellNapalm(PLAYERp pp) } int -InitEnemyNapalm(short SpriteNum) +InitEnemyNapalm(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; short w; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; short dist; unsigned i; @@ -13613,10 +13324,12 @@ InitSpellMirv(PLAYERp pp) } int -InitEnemyMirv(short SpriteNum) +InitEnemyMirv(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; short w; int dist; @@ -15272,10 +14985,11 @@ InitRail(PLAYERp pp) } int -InitZillaRail(short SpriteNum) +InitZillaRail(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); USERp wu; SPRITEp wp; int nx, ny, nz; @@ -15723,10 +15437,11 @@ InitNuke(PLAYERp pp) } int -InitEnemyNuke(short SpriteNum) +InitEnemyNuke(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); USERp wu; SPRITEp wp; int nx, ny, nz; @@ -15945,9 +15660,11 @@ InitMicro(PLAYERp pp) } int -InitRipperSlash(short SpriteNum) +InitRipperSlash(DSWActor* actor) { - USERp u = User[SpriteNum].Data(), hu; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + USERp hu; SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp hp; int i; @@ -15984,8 +15701,10 @@ InitRipperSlash(short SpriteNum) } int -InitBunnySlash(short SpriteNum) +InitBunnySlash(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp hp; int i; @@ -16018,8 +15737,10 @@ InitBunnySlash(short SpriteNum) int -InitSerpSlash(short SpriteNum) +InitSerpSlash(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp hp; int i; @@ -16177,8 +15898,10 @@ DoStaticFlamesDamage(short SpriteNum) } int -InitCoolgBash(short SpriteNum) +InitCoolgBash(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp hp; int i; @@ -16215,8 +15938,10 @@ InitCoolgBash(short SpriteNum) } int -InitSkelSlash(short SpriteNum) +InitSkelSlash(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp hp; int i; @@ -16249,8 +15974,10 @@ InitSkelSlash(short SpriteNum) } int -InitGoroChop(short SpriteNum) +InitGoroChop(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp hp; int i; @@ -16283,22 +16010,25 @@ InitGoroChop(short SpriteNum) } int -InitHornetSting(short SpriteNum) +InitHornetSting(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; short HitSprite = NORM_SPRITE(u->ret); DoDamage(HitSprite, SpriteNum); - InitActorReposition(SpriteNum); + InitActorReposition(actor); return 0; } int -InitSerpSpell(short SpriteNum) +InitSerpSpell(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], np; - USERp u = User[SpriteNum].Data(), nu; + USERp nu; int dist; short New, i; @@ -16411,10 +16141,12 @@ SpawnDemonFist(int16_t Weapon) } int -InitSerpMonstSpell(short SpriteNum) +InitSerpMonstSpell(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], np; - USERp u = User[SpriteNum].Data(), nu; + USERp nu; int dist; short New, i; @@ -16490,8 +16222,10 @@ InitSerpMonstSpell(short SpriteNum) } int -DoTeleRipper(short SpriteNum) +DoTeleRipper(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; extern void Ripper2Hatch(short Weapon); @@ -16503,10 +16237,12 @@ DoTeleRipper(short SpriteNum) int -InitEnemyRocket(short SpriteNum) +InitEnemyRocket(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz, dist, nang; short w; @@ -16569,9 +16305,10 @@ InitEnemyRocket(short SpriteNum) } int -InitEnemyRail(short SpriteNum) +InitEnemyRail(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = u->SpriteP; USERp wu; SPRITEp wp; @@ -16664,10 +16401,12 @@ InitEnemyRail(short SpriteNum) int -InitZillaRocket(short SpriteNum) +InitZillaRocket(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz, dist, nang; short w, i; @@ -16752,10 +16491,12 @@ InitZillaRocket(short SpriteNum) } int -InitEnemyStar(short SpriteNum) +InitEnemyStar(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz, dist, nang; short w; @@ -16841,10 +16582,12 @@ InitEnemyStar(short SpriteNum) } int -InitEnemyCrossbow(short SpriteNum) +InitEnemyCrossbow(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz, dist, nang; short w; @@ -16936,10 +16679,12 @@ InitEnemyCrossbow(short SpriteNum) int -InitSkelSpell(short SpriteNum) +InitSkelSpell(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz, dist, nang; short w; @@ -16985,10 +16730,12 @@ InitSkelSpell(short SpriteNum) int -InitCoolgFire(short SpriteNum) +InitCoolgFire(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz, dist, nang; short w; @@ -17049,10 +16796,11 @@ InitCoolgFire(short SpriteNum) return w; } -int DoCoolgDrip(short SpriteNum) +int DoCoolgDrip(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); u->Counter += 220; sp->z += u->Counter; @@ -17102,10 +16850,12 @@ InitCoolgDrip(short SpriteNum) } int -GenerateDrips(short SpriteNum) +GenerateDrips(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; + USERp wu; int nx, ny, nz; short w = 0; @@ -17150,9 +16900,11 @@ GenerateDrips(short SpriteNum) } int -InitEelFire(short SpriteNum) +InitEelFire(DSWActor* actor) { - USERp u = User[SpriteNum].Data(), hu; + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; + USERp hu; SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp hp; int i; @@ -17184,7 +16936,7 @@ InitEelFire(short SpriteNum) DoDamage(i, SpriteNum); } else - InitActorReposition(SpriteNum); + InitActorReposition(actor); } } @@ -17192,8 +16944,10 @@ InitEelFire(short SpriteNum) } int -InitFireballTrap(short SpriteNum) +InitFireballTrap(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; USERp wu; int nx, ny, nz; @@ -17230,8 +16984,10 @@ InitFireballTrap(short SpriteNum) } int -InitBoltTrap(short SpriteNum) +InitBoltTrap(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum], wp; USERp wu; int nx, ny, nz; @@ -17268,59 +17024,6 @@ InitBoltTrap(short SpriteNum) return w; } -#if 0 -int -InitEnemyCrossbow(short SpriteNum) -{ - SPRITEp sp = &sprite[SpriteNum], wp; - USERp u = User[SpriteNum].Data(), wu; - int nx, ny, nz, dist, nang; - short w; - - // get angle to player and also face player when attacking - sp->ang = nang = NORM_ANGLE(getangle(u->tgt_sp->x - sp->x, u->tgt_sp->y - sp->y)); - - nx = sp->x; - ny = sp->y; - nz = SPRITEp_MID(sp); - - // Spawn a shot - wp = &sprite[w = SpawnSprite(STAT_MISSILE, CROSSBOLT, s_CrossBolt, sp->sectnum, - nx, ny, nz, u->tgt_sp->ang, 800)]; - - wu = User[w].Data(); - - //wp->owner = SpriteNum; - SetOwner(SpriteNum, w); - wp->xrepeat = 16; - wp->yrepeat = 26; - wp->shade = -25; - wp->zvel = 0; - wp->ang = nang; - wp->clipdist = 64L>>2; - - wu->RotNum = 5; - NewStateGroup(w, &sg_CrossBolt); - - wu->xchange = MOVEx(wp->xvel, wp->ang); - wu->ychange = MOVEy(wp->xvel, wp->ang); - wu->zchange = wp->zvel; - - SET(wu->Flags, SPR_XFLIP_TOGGLE); - - MissileSetPos(w, DoStar, 400); - - // find the distance to the target (player) - dist = Distance(wp->x, wp->y, u->tgt_sp->x, u->tgt_sp->y); - - if (dist != 0) - wu->zchange = wp->zvel = (wp->xvel * (SPRITEp_UPPER(u->tgt_sp) - wp->z)) / dist; - - PlaySound(DIGI_STAR, sp, v3df_none); - - return w; -} -#endif int InitSpearTrap(short SpriteNum) @@ -17373,15 +17076,19 @@ InitSpearTrap(short SpriteNum) } int -DoSuicide(short SpriteNum) +DoSuicide(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; KillSprite(SpriteNum); return 0; } int -DoDefaultStat(short SpriteNum) +DoDefaultStat(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; change_sprite_stat(SpriteNum, STAT_DEFAULT); return 0; } @@ -17584,6 +17291,7 @@ int BulletHitSprite(SPRITEp sp, short hit_sprite, int hit_x, int hit_y, int hit_z, short ID) { vec3_t hit_pos = { hit_x, hit_y, hit_z }; + auto actor = &swActors[hit_sprite]; SPRITEp hsp = &sprite[hit_sprite]; USERp hu = User[hit_sprite].Data(); SPRITEp wp; @@ -17626,7 +17334,7 @@ BulletHitSprite(SPRITEp sp, short hit_sprite, int hit_x, int hit_y, int hit_z, s wp->xrepeat = UZI_SMOKE_REPEAT; wp->yrepeat = UZI_SMOKE_REPEAT; if (RANDOM_P2(1024) > 800) - SpawnShrapX(hit_sprite); + SpawnShrapX(actor); break; default: wp->xrepeat = UZI_SMOKE_REPEAT/3; @@ -17714,7 +17422,7 @@ HitscanSpriteAdjust(short SpriteNum, short hit_wall) SPRITEp sp = &sprite[SpriteNum]; int16_t ang; int xvect,yvect; - short sectnum; + int sectnum; #if 1 if (hit_wall >= 0) @@ -17736,12 +17444,9 @@ HitscanSpriteAdjust(short SpriteNum, short hit_wall) xvect = bcos(ang, 4); yvect = bsin(ang, 4); - clipmoveboxtracenum = 1; - // must have this sectnum = sp->sectnum; - clipmove(&sp->pos, §num, xvect, yvect, 4L, 4L<<8, 4L<<8, CLIPMASK_MISSILE); - clipmoveboxtracenum = 3; + clipmove(&sp->pos, §num, xvect, yvect, 4L, 4L<<8, 4L<<8, CLIPMASK_MISSILE, 1); if (sp->sectnum != sectnum) changespritesect(SpriteNum, sectnum); @@ -19059,10 +18764,11 @@ InitTurretMgun(SECTOR_OBJECTp sop) int -InitEnemyUzi(short SpriteNum) +InitEnemyUzi(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP,wp; - USERp u = User[SpriteNum].Data(); USERp wu; short daang, j; hitdata_t hitinfo = { { -2, -2, -2 }, -2, -2, -2 }; @@ -19328,10 +19034,11 @@ InitGrenade(PLAYERp pp) } int -InitSpriteGrenade(short SpriteNum) +InitSpriteGrenade(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); USERp wu; SPRITEp wp; int nx, ny, nz; @@ -19463,10 +19170,11 @@ InitMine(PLAYERp pp) } int -InitEnemyMine(short SpriteNum) +InitEnemyMine(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); USERp wu; SPRITEp wp; int nx, ny, nz; @@ -19631,10 +19339,11 @@ InitFireball(PLAYERp pp) } int -InitEnemyFireball(short SpriteNum) +InitEnemyFireball(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP, fp = nullptr; - USERp u = User[SpriteNum].Data(); SPRITEp wp; int nz, dist; int size_z; @@ -20246,10 +19955,11 @@ SpawnBubble(short SpriteNum) } int -DoVehicleSmoke(short SpriteNum) +DoVehicleSmoke(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); sp->z -= sp->zvel; @@ -20261,8 +19971,10 @@ DoVehicleSmoke(short SpriteNum) } int -DoWaterSmoke(short SpriteNum) +DoWaterSmoke(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; sp->z -= sp->zvel; @@ -20271,8 +19983,10 @@ DoWaterSmoke(short SpriteNum) } int -SpawnVehicleSmoke(short SpriteNum) +SpawnVehicleSmoke(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum],np; USERp nu; short New; @@ -20308,8 +20022,10 @@ SpawnVehicleSmoke(short SpriteNum) } int -SpawnSmokePuff(short SpriteNum) +SpawnSmokePuff(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum],np; USERp nu; short New; @@ -20344,10 +20060,11 @@ SpawnSmokePuff(short SpriteNum) int -DoBubble(short SpriteNum) +DoBubble(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); sp->z -= sp->zvel; sp->zvel += 32; @@ -20490,7 +20207,7 @@ bool TestDontStick(short SpriteNum, short hit_wall) return true; // if blocking red wallo - if (TEST(wp->cstat, CSTAT_WALL_BLOCK) && (uint16_t)wp->nextwall < MAXWALLS) + if (TEST(wp->cstat, CSTAT_WALL_BLOCK) && validWallIndex(wp->nextwall)) return true; return false; @@ -20547,7 +20264,7 @@ int QueueHole(short hit_sect, short hit_wall, int hit_x, int hit_y, int hit_z) short SpriteNum; int nx,ny; SPRITEp sp; - short sectnum; + int sectnum; if (TestDontStick(-1,hit_wall)) @@ -20592,9 +20309,7 @@ int QueueHole(short hit_sect, short hit_wall, int hit_x, int hit_y, int hit_z) sectnum = sp->sectnum; - clipmoveboxtracenum = 1; - clipmove(&sp->pos, §num, nx, ny, 0L, 0L, 0L, CLIPMASK_MISSILE); - clipmoveboxtracenum = 3; + clipmove(&sp->pos, §num, nx, ny, 0L, 0L, 0L, CLIPMASK_MISSILE, 1); if (sp->sectnum != sectnum) changespritesect(SpriteNum, sectnum); @@ -20610,12 +20325,13 @@ STATE s_FloorBlood1[] = {FLOORBLOOD1, FLOORBLOOD_RATE, NullAnimator, &s_FloorBlood1[0]}, }; -int QueueFloorBlood(short hit_sprite) +int QueueFloorBlood(DSWActor* actor) { + USER* u = actor->u(); + int hit_sprite = u->SpriteNum; SPRITEp hsp = &sprite[hit_sprite]; short SpriteNum; SPRITEp sp; - USERp u = User[hit_sprite].Data(); SECTORp sectp = §or[hsp->sectnum]; @@ -20825,7 +20541,7 @@ int QueueWallBlood(short hit_sprite, short ang) short SpriteNum; int nx,ny; SPRITEp sp; - short sectnum; + int sectnum; short rndnum; int daz; hitdata_t hitinfo; @@ -20925,9 +20641,7 @@ int QueueWallBlood(short hit_sprite, short ang) sectnum = sp->sectnum; - clipmoveboxtracenum = 1; - clipmove(&sp->pos, §num, nx, ny, 0L, 0L, 0L, CLIPMASK_MISSILE); - clipmoveboxtracenum = 3; + clipmove(&sp->pos, §num, nx, ny, 0L, 0L, 0L, CLIPMASK_MISSILE, 1); if (sp->sectnum != sectnum) changespritesect(SpriteNum, sectnum); @@ -20937,8 +20651,10 @@ int QueueWallBlood(short hit_sprite, short ang) #define FEET_IN_BLOOD_DIST 300 int -DoFloorBlood(short SpriteNum) +DoFloorBlood(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; SPRITEp psp = User[SpriteNum]->SpriteP; @@ -21007,8 +20723,10 @@ DoFloorBlood(short SpriteNum) } int -DoWallBlood(short SpriteNum) +DoWallBlood(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; // Make blood drip down the wall @@ -21322,6 +21040,7 @@ DoShrapVelocity(int16_t SpriteNum) int ShrapKillSprite(short SpriteNum) { + auto actor = &swActors[SpriteNum]; SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum].Data(); short rnd_num; @@ -21440,7 +21159,7 @@ ShrapKillSprite(short SpriteNum) case GORE_Head: if (RandomRange(1000) > 500) break; sp->clipdist = SPRITEp_SIZE_X(sp); - QueueFloorBlood(SpriteNum); + QueueFloorBlood(actor); QueueGeneric(SpriteNum,GORE_Head); return 0; break; @@ -21643,67 +21362,32 @@ int QueueLoWangs(short SpriteNum) static saveable_code saveable_weapon_code[] = { - SAVE_CODE(MissileHitMatch), SAVE_CODE(SpawnShrapX), SAVE_CODE(DoLavaErupt), - SAVE_CODE(UserShrapSetup), - SAVE_CODE(SpawnShrap), - SAVE_CODE(DoShrapMove), - SAVE_CODE(DoVomit), SAVE_CODE(DoVomit), SAVE_CODE(DoVomitSplash), SAVE_CODE(DoFastShrapJumpFall), SAVE_CODE(DoTracerShrap), SAVE_CODE(DoShrapJumpFall), SAVE_CODE(DoShrapDamage), - SAVE_CODE(SpawnBlood), - SAVE_CODE(VehicleMoveHit), - SAVE_CODE(WeaponMoveHit), SAVE_CODE(DoUziSmoke), SAVE_CODE(DoShotgunSmoke), SAVE_CODE(DoMineSpark), SAVE_CODE(DoFireballFlames), SAVE_CODE(DoBreakFlames), - SAVE_CODE(SetSuicide), SAVE_CODE(DoActorScale), SAVE_CODE(DoRipperGrow), - SAVE_CODE(ActorChooseDeath), - SAVE_CODE(ActorHealth), - SAVE_CODE(SopDamage), - SAVE_CODE(SopCheckKill), - SAVE_CODE(ActorPain), - SAVE_CODE(ActorPainPlasma), - SAVE_CODE(ActorStdMissile), - SAVE_CODE(ActorDamageSlide), - SAVE_CODE(PlayerDamageSlide), - SAVE_CODE(GetDamage), - SAVE_CODE(RadiusGetDamage), - SAVE_CODE(PlayerCheckDeath), - SAVE_CODE(PlayerTakeDamage), - SAVE_CODE(StarBlood), - SAVE_CODE(DoDamage), SAVE_CODE(DoDamageTest), - SAVE_CODE(DoHitscanDamage), - SAVE_CODE(DoFlamesDamageTest), SAVE_CODE(DoStar), SAVE_CODE(DoCrossBolt), SAVE_CODE(DoPlasmaDone), - SAVE_CODE(MissileSeek), - SAVE_CODE(ComboMissileSeek), - SAVE_CODE(VectorMissileSeek), - SAVE_CODE(VectorWormSeek), - SAVE_CODE(DoBlurExtend), - SAVE_CODE(InitPlasmaFountain), SAVE_CODE(DoPlasmaFountain), SAVE_CODE(DoPlasma), SAVE_CODE(DoCoolgFire), SAVE_CODE(DoEelFire), SAVE_CODE(DoGrenade), SAVE_CODE(DoVulcanBoulder), - SAVE_CODE(OwnerIsPlayer), - SAVE_CODE(DoMineRangeTest), SAVE_CODE(DoMineStuck), - SAVE_CODE(SetMineStuck), SAVE_CODE(DoMine), SAVE_CODE(DoPuff), SAVE_CODE(DoRailPuff), @@ -21728,26 +21412,9 @@ static saveable_code saveable_weapon_code[] = SAVE_CODE(DoElectro), SAVE_CODE(DoLavaBoulder), SAVE_CODE(DoSpear), - SAVE_CODE(SpawnBasicExp), - SAVE_CODE(SpawnFireballFlames), - SAVE_CODE(SpawnBreakFlames), - SAVE_CODE(SpawnBreakStaticFlames), - SAVE_CODE(SpawnFireballExp), - SAVE_CODE(SpawnGoroFireballExp), - SAVE_CODE(SpawnBoltExp), - SAVE_CODE(SpawnBunnyExp), - SAVE_CODE(SpawnTankShellExp), - SAVE_CODE(SpawnNuclearSecondaryExp), - SAVE_CODE(SpawnNuclearExp), - SAVE_CODE(SpawnTracerExp), - SAVE_CODE(SpawnMicroExp), - SAVE_CODE(AddSpriteToSectorObject), - SAVE_CODE(SpawnBigGunFlames), - SAVE_CODE(SpawnGrenadeSecondaryExp), SAVE_CODE(SpawnGrenadeSmallExp), SAVE_CODE(SpawnGrenadeExp), SAVE_CODE(SpawnMineExp), - SAVE_CODE(InitMineShrap), SAVE_CODE(DoSectorExp), SAVE_CODE(SpawnSectorExp), SAVE_CODE(SpawnLargeExp), @@ -21758,22 +21425,17 @@ static saveable_code saveable_weapon_code[] = SAVE_CODE(DoFindGroundPoint), SAVE_CODE(DoNapalm), SAVE_CODE(DoBloodWorm), - SAVE_CODE(DoBloodWorm), SAVE_CODE(DoMeteor), SAVE_CODE(DoSerpMeteor), SAVE_CODE(DoMirvMissile), SAVE_CODE(DoMirv), - SAVE_CODE(MissileSetPos), - SAVE_CODE(TestMissileSetPos), SAVE_CODE(DoRing), - SAVE_CODE(InitSpellRing), SAVE_CODE(DoSerpRing), SAVE_CODE(InitLavaFlame), SAVE_CODE(InitLavaThrow), SAVE_CODE(InitVulcanBoulder), SAVE_CODE(InitSerpRing), SAVE_CODE(InitSerpRing), - //SAVE_CODE(InitSerpRing2), SAVE_CODE(InitSpellNapalm), SAVE_CODE(InitEnemyNapalm), SAVE_CODE(InitSpellMirv), @@ -21784,35 +21446,16 @@ static saveable_code saveable_weapon_code[] = SAVE_CODE(InitSumoSkull), SAVE_CODE(InitSumoStompAttack), SAVE_CODE(InitMiniSumoClap), - SAVE_CODE(WeaponAutoAim), - SAVE_CODE(WeaponAutoAimZvel), - SAVE_CODE(AimHitscanToTarget), - SAVE_CODE(WeaponAutoAimHitscan), - SAVE_CODE(WeaponHitscanShootFeet), - SAVE_CODE(InitStar), - SAVE_CODE(InitHeartAttack), - SAVE_CODE(InitHeartAttack), - SAVE_CODE(InitShotgun), - SAVE_CODE(InitLaser), - SAVE_CODE(InitRail), SAVE_CODE(InitZillaRail), - SAVE_CODE(InitRocket), - SAVE_CODE(InitBunnyRocket), - SAVE_CODE(InitNuke), SAVE_CODE(InitEnemyNuke), - SAVE_CODE(InitMicro), SAVE_CODE(InitRipperSlash), SAVE_CODE(InitBunnySlash), SAVE_CODE(InitSerpSlash), - SAVE_CODE(WallSpriteInsideSprite), - SAVE_CODE(DoBladeDamage), - SAVE_CODE(DoStaticFlamesDamage), SAVE_CODE(InitCoolgBash), SAVE_CODE(InitSkelSlash), SAVE_CODE(InitGoroChop), SAVE_CODE(InitHornetSting), SAVE_CODE(InitSerpSpell), - SAVE_CODE(SpawnDemonFist), SAVE_CODE(InitSerpMonstSpell), SAVE_CODE(DoTeleRipper), SAVE_CODE(InitEnemyRocket), @@ -21831,55 +21474,17 @@ static saveable_code saveable_weapon_code[] = SAVE_CODE(InitSpearTrap), SAVE_CODE(DoSuicide), SAVE_CODE(DoDefaultStat), - SAVE_CODE(InitTracerUzi), - SAVE_CODE(InitTracerTurret), - SAVE_CODE(InitTracerAutoTurret), - SAVE_CODE(BulletHitSprite), - SAVE_CODE(HitscanSpriteAdjust), - SAVE_CODE(InitUzi), - SAVE_CODE(InitEMP), - SAVE_CODE(InitTankShell), - SAVE_CODE(InitTurretMicro), - SAVE_CODE(InitTurretRocket), - SAVE_CODE(InitTurretFireball), - SAVE_CODE(InitTurretRail), - SAVE_CODE(InitTurretLaser), - SAVE_CODE(InitSobjMachineGun), - SAVE_CODE(InitSobjGun), - SAVE_CODE(SpawnBoatSparks), - SAVE_CODE(SpawnSwordSparks), - SAVE_CODE(SpawnTurretSparks), - SAVE_CODE(SpawnShotgunSparks), - SAVE_CODE(InitTurretMgun), SAVE_CODE(InitEnemyUzi), - SAVE_CODE(InitGrenade), SAVE_CODE(InitSpriteGrenade), - SAVE_CODE(InitMine), SAVE_CODE(InitEnemyMine), - SAVE_CODE(HelpMissileLateral), - SAVE_CODE(InitFireball), SAVE_CODE(InitEnemyFireball), - SAVE_CODE(WarpToUnderwater), - SAVE_CODE(WarpToSurface), - SAVE_CODE(SpriteWarpToUnderwater), - SAVE_CODE(SpriteWarpToSurface), - SAVE_CODE(SpawnSplash), - SAVE_CODE(SpawnSplashXY), - SAVE_CODE(SpawnUnderSplash), - SAVE_CODE(MissileHitDiveArea), - SAVE_CODE(SpawnBubble), SAVE_CODE(DoVehicleSmoke), SAVE_CODE(DoWaterSmoke), SAVE_CODE(SpawnVehicleSmoke), SAVE_CODE(SpawnSmokePuff), SAVE_CODE(DoBubble), - SAVE_CODE(SpriteQueueDelete), SAVE_CODE(DoFloorBlood), SAVE_CODE(DoWallBlood), - //SAVE_CODE(DoShellShrap), - SAVE_CODE(SpawnShell), - SAVE_CODE(DoShrapVelocity), - SAVE_CODE(ShrapKillSprite), SAVE_CODE(DoItemFly), }; diff --git a/source/games/sw/src/weapon.h b/source/games/sw/src/weapon.h index 8b1ab5a7e..427ce0dda 100644 --- a/source/games/sw/src/weapon.h +++ b/source/games/sw/src/weapon.h @@ -160,7 +160,7 @@ int DoActorBeginSlide(int SpriteNum, short ang, short vel, short dec); int GetOverlapSector(int x, int y, short *over, short *under); bool MissileHitDiveArea(short SpriteNum); -int DoDamageTest(short); +int DoDamageTest(DSWActor*); extern short StatDamageList[STAT_DAMAGE_LIST_SIZE]; @@ -208,10 +208,10 @@ void InitSpellRing(PLAYERp pp); void InitSpellNapalm(PLAYERp pp); int InitUzi(PLAYERp pp); int InitSobjGun(PLAYERp pp); -int InitBoltTrap(short SpriteNum); +int InitBoltTrap(DSWActor* actor); int InitSpearTrap(short SpriteNum); int InitTurretMgun(SECTOR_OBJECTp sop); -int InitVulcanBoulder(short SpriteNum); +int InitVulcanBoulder(DSWActor* actor); int DoBladeDamage(short SpriteNum); int DoFindGround(int16_t SpriteNum); int DoFindGroundPoint(int16_t SpriteNum); @@ -233,7 +233,7 @@ int SpawnTracerExp(int16_t Weapon); int SpawnGoroFireballExp(int16_t Weapon); bool MissileHitMatch(short Weapon,short WeaponNum,short hit_sprite); int DoItemFly(int16_t SpriteNum); -int SpawnVehicleSmoke(short SpriteNum); +int SpawnVehicleSmoke(DSWActor* actor); short PrevWall(short wall_num); int DoDamage(short SpriteNum,short Weapon); diff --git a/source/games/sw/src/zilla.cpp b/source/games/sw/src/zilla.cpp index 4ca5c8800..0d5b39ec2 100644 --- a/source/games/sw/src/zilla.cpp +++ b/source/games/sw/src/zilla.cpp @@ -678,13 +678,14 @@ SetupZilla(short SpriteNum) return 0; } -int NullZilla(short SpriteNum) +int NullZilla(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; //if (TEST(u->Flags,SPR_SLIDING)) - //DoActorSlide(SpriteNum); + //DoActorSlide(actor); #if 0 if (u->State == s_ZillaDie) @@ -705,19 +706,20 @@ int NullZilla(short SpriteNum) u->hi_sp = nullptr; sp->z = u->loz; - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoZillaMove(short SpriteNum) +int DoZillaMove(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); short choose; //if (TEST(u->Flags,SPR_SLIDING)) - //DoActorSlide(SpriteNum); + //DoActorSlide(actor); // Random Zilla taunts if (!SoundValidAndActive(sp, CHAN_AnimeMad)) @@ -737,11 +739,11 @@ int DoZillaMove(short SpriteNum) if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); KeepActorOnFloor(SpriteNum); - if (DoActorSectorDamage(SpriteNum)) + if (DoActorSectorDamage(actor)) { return 0; } @@ -749,8 +751,10 @@ int DoZillaMove(short SpriteNum) return 0; } -int DoZillaStomp(short SpriteNum) +int DoZillaStomp(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; PlaySound(DIGI_ZILLASTOMP, sp, v3df_follow); @@ -760,10 +764,11 @@ int DoZillaStomp(short SpriteNum) extern int SpawnGrenadeExp(int16_t Weapon); -int DoZillaDeathMelt(short SpriteNum) +int DoZillaDeathMelt(DSWActor* actor) { + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); if (RandomRange(1000) > 800) SpawnGrenadeExp(SpriteNum); @@ -795,7 +800,6 @@ int DoZillaDeathMelt(short SpriteNum) static saveable_code saveable_zilla_code[] = { - SAVE_CODE(SetupZilla), SAVE_CODE(NullZilla), SAVE_CODE(DoZillaMove), SAVE_CODE(DoZillaStomp), diff --git a/source/games/sw/src/zombie.cpp b/source/games/sw/src/zombie.cpp index f201d5929..5e6382a41 100644 --- a/source/games/sw/src/zombie.cpp +++ b/source/games/sw/src/zombie.cpp @@ -843,7 +843,7 @@ SpawnZombie2(short Weapon) if (FAF_ConnectArea(sp->sectnum)) { - short sectnum = sp->sectnum; + int sectnum = sp->sectnum; updatesectorz(sp->x, sp->y, sp->z + Z(10), §num); if (sectnum >= 0 && SectorIsUnderwaterArea(sectnum)) return -1; @@ -880,9 +880,10 @@ SpawnZombie2(short Weapon) } int -DoZombieMove(short SpriteNum) +DoZombieMove(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (u->Counter3++ >= ZOMBIE_TIME_LIMIT) { @@ -900,21 +901,21 @@ DoZombieMove(short SpriteNum) if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING)) { if (TEST(u->Flags, SPR_JUMPING)) - DoActorJump(SpriteNum); + DoActorJump(actor); else if (TEST(u->Flags, SPR_FALLING)) - DoActorFall(SpriteNum); + DoActorFall(actor); } // sliding if (TEST(u->Flags, SPR_SLIDING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); // Do track or call current action function - such as DoActorMoveCloser() if (u->track >= 0) ActorFollowTrack(SpriteNum, ACTORMOVETICS); else { - (*u->ActorActionFunc)(SpriteNum); + (*u->ActorActionFunc)(actor); } // stay on floor unless doing certain things @@ -924,15 +925,16 @@ DoZombieMove(short SpriteNum) } // take damage from environment - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } int -NullZombie(short SpriteNum) +NullZombie(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; if (u->Counter3++ >= ZOMBIE_TIME_LIMIT) { @@ -950,25 +952,26 @@ NullZombie(short SpriteNum) u->WaitTics -= ACTORMOVETICS; if (TEST(u->Flags, SPR_SLIDING) && !TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) - DoActorSlide(SpriteNum); + DoActorSlide(actor); if (!TEST(u->Flags, SPR_JUMPING|SPR_FALLING)) KeepActorOnFloor(SpriteNum); - DoActorSectorDamage(SpriteNum); + DoActorSectorDamage(actor); return 0; } -int DoZombiePain(short SpriteNum) +int DoZombiePain(DSWActor* actor) { - USERp u = User[SpriteNum].Data(); + USER* u = actor->u(); + int SpriteNum = u->SpriteNum; - NullZombie(SpriteNum); + NullZombie(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) - InitActorDecide(SpriteNum); + InitActorDecide(actor); return 0; } @@ -978,9 +981,6 @@ int DoZombiePain(short SpriteNum) static saveable_code saveable_zombie_code[] = { - SAVE_CODE(SetupZombie), - SAVE_CODE(SpawnZombie), - SAVE_CODE(SpawnZombie2), SAVE_CODE(DoZombieMove), SAVE_CODE(NullZombie), SAVE_CODE(DoZombiePain), diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 8b87857f2..1bb967363 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -165,7 +165,7 @@ void GLInstance::SetShade(int32_t shade, int numshades) // Ugh... This particular palette does not fade to black. Should be handled better. // It's really too bad that everything runs through here without being able to identify it anymore. renderState.drawblack = (!(g_gameType & GAMEFLAG_PSEXHUMED) || globalpal != 4) ? shade > numshades : false; - renderState.Shade = std::min(shade, numshades - 1); + renderState.Shade = min(shade, numshades - 1); } bool PolymostRenderState::Apply(FRenderState& state, GLState& oldState) diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 4cd6c1305..3692f9a67 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -12,7 +13,7 @@ #include "hw_material.h" #include "hw_renderstate.h" #include "pm_renderstate.h" -#include "templates.h" + class FShader; class FGameTexture; diff --git a/source/glbackend/pm_renderstate.h b/source/glbackend/pm_renderstate.h index c1d45580b..1c20f2383 100644 --- a/source/glbackend/pm_renderstate.h +++ b/source/glbackend/pm_renderstate.h @@ -1,5 +1,6 @@ #pragma once +#include #include "palentry.h" #include "gl_buffers.h" #include "renderstyle.h" diff --git a/tools/lemon/CMakeLists.txt b/tools/lemon/CMakeLists.txt index 71418eda5..52551248d 100644 --- a/tools/lemon/CMakeLists.txt +++ b/tools/lemon/CMakeLists.txt @@ -3,6 +3,10 @@ cmake_minimum_required( VERSION 3.1.0 ) if( NOT CMAKE_CROSSCOMPILING ) set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) +if (MSVC) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4244 /wd4267" ) +endif() + add_executable( lemon lemon.c ) set( CROSS_EXPORTS ${CROSS_EXPORTS} lemon PARENT_SCOPE ) diff --git a/tools/re2c/CMakeLists.txt b/tools/re2c/CMakeLists.txt index 9fcfef5a2..1fd3cd5d8 100644 --- a/tools/re2c/CMakeLists.txt +++ b/tools/re2c/CMakeLists.txt @@ -7,7 +7,7 @@ include( CheckTypeSize ) if( MSVC ) # Runtime type information is required and don't complain about uint32_t to bool conversions - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR /wd4800" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR /wd4800 /wd4244" ) endif() set( PACKAGE_NAME re2c ) diff --git a/wadsrc/static/engine/grpinfo.txt b/wadsrc/static/engine/grpinfo.txt index 644fddf0a..421dce36c 100644 --- a/wadsrc/static/engine/grpinfo.txt +++ b/wadsrc/static/engine/grpinfo.txt @@ -415,6 +415,32 @@ grpinfo gamefilter "Duke.Zone.13" } +// original .zip release +grpinfo +{ + name "Duke Nukem's Penthouse Paradise" + scriptname "PPAKGAME.CON" + size 2112419 + crc 0x7CD82A3B + flags GAMEFLAG_DUKE|GAMEFLAG_ADDON + dependency DUKE15_CRC + gamefilter "Duke.PParadise" + exclepisodes "LUNAR APOCALYPSE", "SHRAPNEL CITY", "THE BIRTH" +} + +// ZOOM Platform repacked .grp +grpinfo +{ + name "Duke Nukem's Penthouse Paradise" + scriptname "PPAKGAME.CON" + size 4247491 + crc 0xCF928A58 + flags GAMEFLAG_DUKE|GAMEFLAG_ADDON + dependency DUKE15_CRC + gamefilter "Duke.PParadise" + exclepisodes "LUNAR APOCALYPSE", "SHRAPNEL CITY", "THE BIRTH" +} + grpinfo { name "BLOOD: 1.0" diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 2283b976d..be3b2c067 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -67,6 +67,7 @@ LISTMENU "MainMenu" class ExhumedMainMenu Position 160, 65 linespacing 22 + Animated ExhumedPlasma ExhumedTextItem "$MNU_NEWGAME", "n", "StartGameNoSkill", 0 ExhumedTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" @@ -1119,10 +1120,6 @@ OptionMenu GameplayOptions protected Option "$EXPLOS_BEHAVIOR", "cl_bloodvanillaexplosions", "ExplosBehavior" Option "$ENEMY_BEHAVIOR", "cl_bloodvanillaenemies", "EnemyBehavior" } - ifgame(Exhumed) - { - Option "$PLRMNU_EXHUMEDOLDTURN", "cl_exhumedoldturn", "OnOff" - } StaticText "" ifgame(Blood) { diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index 281f3d43c..c84922460 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -416,7 +416,7 @@ struct Screen native native static int GetHeight(); native static Vector2 GetTextScreenSize(); native static void Clear(int left, int top, int right, int bottom, Color color, int palcolor = -1); - native static void Dim(Color col, double amount, int x, int y, int w, int h); + native static void Dim(Color col, double amount, int x, int y, int w, int h, ERenderStyle style = STYLE_Translucent); native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...); native static vararg void DrawShape(TextureID tex, bool animate, Shape2D s, ...); diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 25ef14cad..de2c58209 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -157,18 +157,19 @@ struct DukePlayer native int player_par, visibility; native int bobcounter; native int randomflamex, crack_time; - native int aim_mode, ftt; - native int16 cursectnum, last_extra, subweapon; + native int cursectnum, one_parallax_sectnum, access_wallnum; + + native int16 last_extra, subweapon; native int16 ammo_amount[DukeWpn.MAX_WEAPONS], frag, fraggedself; native int16 curr_weapon, last_weapon, tipincs, wantweaponfire; native int16 holoduke_amount, hurt_delay, hbomb_hold_delay; native int16 jumping_counter, airleft, knee_incs, access_incs; - native int16 ftq, access_wallnum; + native int16 ftq; native int16 got_access, weapon_ang, firstaid_amount; - native int16 i, one_parallax_sectnum; + native int16 i; native int16 over_shoulder_on, fist_incs; native int16 cheat_phase; native int16 extra_extra8, quick_kick, last_quick_kick; diff --git a/wadsrc/static/zscript/games/duke/ui/menu.zs b/wadsrc/static/zscript/games/duke/ui/menu.zs index c1b9a6df4..dccfec24e 100644 --- a/wadsrc/static/zscript/games/duke/ui/menu.zs +++ b/wadsrc/static/zscript/games/duke/ui/menu.zs @@ -137,7 +137,7 @@ class ListMenuItemDukeLogo : ListMenuItem if (gameinfo.gametype & GAMEFLAG_PLUTOPAK) { int mclock = MSTime() * 120 / 1000; - int light = 223 + (Raze.bsin(mclock<<4) >> 9); + int light = 223 + Raze.bsin(mclock<<4, -9); let pe = Color(255, light, light, light); Screen.DrawTexture(TexMan.CheckForTexture("MENUPLUTOPAKSPRITE"), false, x + 100, 36, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_Color, pe, DTA_CenterOffsetRel, true); } @@ -176,7 +176,7 @@ class ListMenuItemDukeTextItem : ListMenuItemTextItem if (selected) { int mclock = MSTime() * 120 / 1000; - int light = 231 + (Raze.bsin(mclock<<5) >> 9); + int light = 231 + ((Raze.bsin(mclock<<5) * 3) >> 11); pe = Color(255, light, light, light); } else diff --git a/wadsrc/static/zscript/games/duke/ui/sbar_d.zs b/wadsrc/static/zscript/games/duke/ui/sbar_d.zs index 5e50b26e7..ded62e621 100644 --- a/wadsrc/static/zscript/games/duke/ui/sbar_d.zs +++ b/wadsrc/static/zscript/games/duke/ui/sbar_d.zs @@ -147,7 +147,7 @@ class DukeStatusBar : DukeCommonStatusBar { int s = -8; if (hud_flashing && p.last_extra > Duke.MaxPlayerHealth()) - s += Raze.bsin(Raze.GetBuildTime() << 5) / 768; + s += Raze.bsin(Raze.GetBuildTime() << 5, -10); int intens = clamp(255 - 6 * s, 0, 255); format = String.Format("%d", p.last_extra); DrawString(numberFont, format, (25, texty), DI_TEXT_ALIGN_LEFT, Font.CR_UNTRANSLATED, intens / 255., 0, 0); diff --git a/wadsrc/static/zscript/games/duke/ui/sbar_r.zs b/wadsrc/static/zscript/games/duke/ui/sbar_r.zs index fc05db7f4..33ccf2e6b 100644 --- a/wadsrc/static/zscript/games/duke/ui/sbar_r.zs +++ b/wadsrc/static/zscript/games/duke/ui/sbar_r.zs @@ -94,7 +94,7 @@ class RedneckStatusBar : DukeCommonStatusBar { int s = -8; if (hud_flashing && p.last_extra > Duke.MaxPlayerHealth()) - s += Raze.bsin(Raze.GetBuildTime() << 5) / 768; + s += Raze.bsin(Raze.GetBuildTime() << 5, -10); int intens = clamp(255 - 6 * s, 0, 255); format = String.Format("%d", p.last_extra); DrawString(numberFont, format, (26.5, -numberFont.mFont.GetHeight() * scale + 4), DI_TEXT_ALIGN_LEFT, Font.CR_UNTRANSLATED, intens / 255., 0, 0, (scale, scale)); diff --git a/wadsrc/static/zscript/games/exhumed/exhumedgame.zs b/wadsrc/static/zscript/games/exhumed/exhumedgame.zs index ee7ed3729..281f0800c 100644 --- a/wadsrc/static/zscript/games/exhumed/exhumedgame.zs +++ b/wadsrc/static/zscript/games/exhumed/exhumedgame.zs @@ -41,7 +41,7 @@ struct ExhumedPlayer native native int16 nTorch; native int16 field_2; native int16 nAction; - native int16 nSprite; + //native int16 nSprite; native int16 bIsMummified; native int16 invincibility; native int16 nAir; diff --git a/wadsrc/static/zscript/games/exhumed/ui/menu.zs b/wadsrc/static/zscript/games/exhumed/ui/menu.zs index c483a5a26..52585f439 100644 --- a/wadsrc/static/zscript/games/exhumed/ui/menu.zs +++ b/wadsrc/static/zscript/games/exhumed/ui/menu.zs @@ -101,7 +101,7 @@ class ListMenuItemExhumedTextItem : ListMenuItemTextItem double y = mYpos + v.y / 2; int shade; - if (selected) shade = Raze.bsin(MSTime() * 16 * 120 / 1000) >> 9; + if (selected) shade = Raze.bsin(MSTime() * 16 * 120 / 1000, -9); else if (Selectable()) shade = 0; else shade = 25; let color = Raze.shadeToLight(shade); diff --git a/wadsrc/static/zscript/games/sw/swgame.zs b/wadsrc/static/zscript/games/sw/swgame.zs index 970819541..a4f7f15d9 100644 --- a/wadsrc/static/zscript/games/sw/swgame.zs +++ b/wadsrc/static/zscript/games/sw/swgame.zs @@ -211,7 +211,7 @@ struct SWPlayer native native int16 circle_camera_ang; native int16 camera_check_time_delay; - native int16 cursectnum,lastcursectnum; + native int cursectnum,lastcursectnum; native int turn180_target; // 180 degree turn // variables that do not fit into sprite structure