diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index d72fc79a20..03a7495e4e 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -923,10 +923,21 @@ static bool IsActorACountItem(AActor *mo) return mo->IsKindOf(RUNTIME_CLASS(AInventory)) && mo->flags&MF_SPECIAL && mo->flags&MF_COUNTITEM; } -static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const char *FilterName) +// [SP] for all actors +static bool IsActor(AActor *mo) +{ + if (mo->IsKindOf(RUNTIME_CLASS(AInventory))) + return static_cast(mo)->Owner == NULL; // [SP] Exclude inventory-owned items + else + return true; +} + +// [SP] modified - now allows showing count only, new arg must be passed. Also now still counts regardless, if lists are printed. +static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const char *FilterName, bool countOnly) { AActor *mo; const PClass *FilterClass = NULL; + int counter = 0; if (FilterName != NULL) { @@ -943,10 +954,32 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha { if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo)) { - Printf ("%s at (%f,%f,%f)\n", - mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z()); + counter++; + if (!countOnly) + Printf ("%s at (%f,%f,%f)\n", + mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z()); } } + Printf("%i match(s) found.\n", counter); +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- +CCMD(actorlist) // [SP] print all actors (this can get quite big?) +{ + if (CheckCheatmode ()) return; + + PrintFilteredActorList(IsActor, argv.argc() > 1 ? argv[1] : NULL, false); +} + +CCMD(actornum) // [SP] count all actors +{ + if (CheckCheatmode ()) return; + + PrintFilteredActorList(IsActor, argv.argc() > 1 ? argv[1] : NULL, true); } //----------------------------------------------------------------------------- @@ -958,7 +991,14 @@ CCMD(monster) { if (CheckCheatmode ()) return; - PrintFilteredActorList(IsActorAMonster, argv.argc() > 1 ? argv[1] : NULL); + PrintFilteredActorList(IsActorAMonster, argv.argc() > 1 ? argv[1] : NULL, false); +} + +CCMD(monsternum) // [SP] count monsters +{ + if (CheckCheatmode ()) return; + + PrintFilteredActorList(IsActorAMonster, argv.argc() > 1 ? argv[1] : NULL, true); } //----------------------------------------------------------------------------- @@ -970,7 +1010,14 @@ CCMD(items) { if (CheckCheatmode ()) return; - PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL); + PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL, false); +} + +CCMD(itemsnum) // [SP] # of any items +{ + if (CheckCheatmode ()) return; + + PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL, true); } //----------------------------------------------------------------------------- @@ -982,7 +1029,14 @@ CCMD(countitems) { if (CheckCheatmode ()) return; - PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL); + PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL, false); +} + +CCMD(countitemsnum) // [SP] # of counted items +{ + if (CheckCheatmode ()) return; + + PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL, true); } //----------------------------------------------------------------------------- diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index e40233defd..c4d8ec1ede 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -1108,7 +1108,7 @@ void DrawHUD() } else { - if (CheckRatio(SCREENWIDTH, SCREENHEIGHT) == 4) + if (AspectTallerThanWide(WidescreenRatio)) { hudheight = hudwidth * 30 / AspectMultiplier(WidescreenRatio); // BaseRatioSizes is inverted for this mode } diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 71bac435c2..b18b367c37 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -213,6 +213,17 @@ FFlatVertexBuffer::~FFlatVertexBuffer() map = nullptr; } +void FFlatVertexBuffer::OutputResized(int width, int height) +{ + vbo_shadowdata[4].Set(0, 0, 0, 0, 0); + vbo_shadowdata[5].Set(0, (float)height, 0, 0, 0); + vbo_shadowdata[6].Set((float)width, 0, 0, 0, 0); + vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0); + + Map(); + memcpy(map, &vbo_shadowdata[4], 4 * sizeof(FFlatVertex)); + Unmap(); +} void FFlatVertexBuffer::BindVBO() { diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 1e9692f487..596de35d9d 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -131,6 +131,8 @@ public: FFlatVertexBuffer(int width, int height); ~FFlatVertexBuffer(); + void OutputResized(int width, int height); + void BindVBO(); void CreateVBO(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 200541ebac..af76de8269 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -107,6 +107,44 @@ static const float LARGE_VALUE = 1e19f; void GLSprite::CalculateVertices(FVector3 *v) { + if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE) + { + Matrix3x4 mat; + mat.MakeIdentity(); + + // [MC] Rotate around the center or offsets given to the sprites. + // Counteract any existing rotations, then rotate the angle. + // Tilt the actor up or down based on pitch (increase 'somersaults' forward). + // Then counteract the roll and DO A BARREL ROLL. + + FAngle pitch = (float)-actor->Angles.Pitch.Degrees; + pitch.Normalized180(); + + mat.Translate(x, z, y); + mat.Rotate(0, 1, 0, 270. - actor->Angles.Yaw.Degrees); + mat.Rotate(1, 0, 0, pitch.Degrees); + + if (actor->renderflags & RF_ROLLCENTER) + { + float cx = (x1 + x2) * 0.5; + float cy = (y1 + y2) * 0.5; + + mat.Translate(cx - x, 0, cy - y); + mat.Rotate(0, 1, 0, - actor->Angles.Roll.Degrees); + mat.Translate(-cx, -z, -cy); + } + else + { + mat.Rotate(0, 1, 0, - actor->Angles.Roll.Degrees); + mat.Translate(-x, -z, -y); + } + v[0] = mat * FVector3(x1, z, y2); + v[1] = mat * FVector3(x2, z, y2); + v[2] = mat * FVector3(x1, z, y1); + v[3] = mat * FVector3(x2, z, y1); + return; + } + // [BB] Billboard stuff const bool drawWithXYBillboard = ((particle && gl_billboard_particles) || (!(actor && actor->renderflags & RF_FORCEYBILLBOARD) //&& GLRenderer->mViewActor != NULL @@ -363,15 +401,8 @@ void GLSprite::Draw(int pass) gl_RenderState.Apply(); FVector3 v[4]; - if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE) - { - } - else - { - CalculateVertices(v); - } - - + CalculateVertices(v); + FQuadDrawer qd; qd.Set(0, v[0][0], v[0][1], v[0][2], ul, vt); qd.Set(1, v[1][0], v[1][1], v[1][2], ur, vt); @@ -595,7 +626,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) sector_t * rendersector; // Don't waste time projecting sprites that are definitely not visible. - if (thing == NULL || thing->sprite == 0 || !thing->IsVisibleToPlayer()) + if (thing == nullptr || thing->sprite == 0 || !thing->IsVisibleToPlayer()) { return; } @@ -728,7 +759,8 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) float rightfac = -r.left; float leftfac = rightfac - r.width; - + float bottomfac = -r.top; + float topfac = bottomfac - r.height; z1 = z - r.top; z2 = z1 - r.height; @@ -753,11 +785,15 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) y1 = y + viewvecX*leftfac; y2 = y + viewvecX*rightfac; break; - + case RF_FLATSPRITE: - // needs careful rethinking - return; - + { + x1 = x + leftfac; + x2 = x + rightfac; + y1 = y - topfac; + y2 = y - bottomfac; + } + break; case RF_WALLSPRITE: viewvecX = thing->Angles.Yaw.Cos(); viewvecY = thing->Angles.Yaw.Sin(); diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index a61d139c07..07d8abaef7 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -192,6 +192,7 @@ void OpenGLFrameBuffer::Update() { Resize(clientWidth, clientHeight); V_OutputResized(Width, Height); + GLRenderer->mVBO->OutputResized(Width, Height); } } diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 1328e2f7a9..b1b4d792fd 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -95,7 +95,7 @@ CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE) } else { - BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits); + BuildModesList (screen->VideoWidth, screen->VideoHeight, DisplayBits); } } @@ -139,7 +139,7 @@ public: DVideoModeMenu() { - SetModesMenu (SCREENWIDTH, SCREENHEIGHT, DisplayBits); + SetModesMenu (screen->VideoWidth, screen->VideoHeight, DisplayBits); } bool MenuEvent(int mkey, bool fromcontroller) @@ -163,13 +163,13 @@ public: { if (!GetSelectedSize (&NewWidth, &NewHeight)) { - NewWidth = SCREENWIDTH; - NewHeight = SCREENHEIGHT; + NewWidth = screen->VideoWidth; + NewHeight = screen->VideoHeight; } else { - OldWidth = SCREENWIDTH; - OldHeight = SCREENHEIGHT; + OldWidth = screen->VideoWidth; + OldHeight = screen->VideoHeight; OldBits = DisplayBits; NewBits = BitTranslate[DummyDepthCvar]; setmodeneeded = true; @@ -297,11 +297,11 @@ void M_RestoreMode () void M_SetDefaultMode () { // Make current resolution the default - vid_defwidth = SCREENWIDTH; - vid_defheight = SCREENHEIGHT; + vid_defwidth = screen->VideoWidth; + vid_defheight = screen->VideoHeight; vid_defbits = DisplayBits; testingmode = 0; - SetModesMenu (SCREENWIDTH, SCREENHEIGHT, DisplayBits); + SetModesMenu (screen->VideoWidth, screen->VideoHeight, DisplayBits); } @@ -314,7 +314,7 @@ void M_SetDefaultMode () void M_RefreshModesList () { - BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits); + BuildModesList (screen->VideoWidth, screen->VideoHeight, DisplayBits); } void M_InitVideoModesMenu () @@ -385,8 +385,8 @@ void M_SetVideoMode() { if (!GetSelectedSize (&NewWidth, &NewHeight)) { - NewWidth = SCREENWIDTH; - NewHeight = SCREENHEIGHT; + NewWidth = screen->VideoWidth; + NewHeight = screen->VideoHeight; } else { diff --git a/src/v_video.cpp b/src/v_video.cpp index af190d3724..b1f1ced9cf 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -850,6 +850,9 @@ DFrameBuffer::DFrameBuffer (int width, int height) { LastMS = LastSec = FrameCount = LastCount = LastTic = 0; Accel2D = false; + + VideoWidth = width; + VideoHeight = height; } //========================================================================== @@ -1352,6 +1355,7 @@ void V_OutputResized (int width, int height) { StatusBar->ScreenSizeChanged(); } + C_NewModeAdjust(); } void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2) diff --git a/src/v_video.h b/src/v_video.h index 7317c9d1a3..d19a3b06ec 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -422,6 +422,10 @@ public: virtual bool Is8BitMode() = 0; #endif + // The original size of the framebuffer as selected in the video menu. + int VideoWidth = 0; + int VideoHeight = 0; + protected: void DrawRateStuff (); void CopyFromBuff (BYTE *src, int srcPitch, int width, int height, BYTE *dest); diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 52b354028f..0d45ad90a3 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -156,6 +156,15 @@ enum ATAG_RNG, // pointer to FRandom }; +enum EVMAbortException +{ + X_READ_NIL, + X_WRITE_NIL, + X_TOO_MANY_TRIES, + X_ARRAY_OUT_OF_BOUNDS, + X_DIVISION_BY_ZERO, +}; + class VMFunction : public DObject { DECLARE_ABSTRACT_CLASS(VMFunction, DObject); diff --git a/src/zscript/vmexec.cpp b/src/zscript/vmexec.cpp index 070aeb30a4..454f02d03f 100644 --- a/src/zscript/vmexec.cpp +++ b/src/zscript/vmexec.cpp @@ -44,7 +44,7 @@ #define ASSERTKA(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstA) #define ASSERTKS(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstS) -#define THROW(x) +#define THROW(x) throw(EVMAbortException(x)) #define CMPJMP(test) \ if ((test) == (a & CMP_CHECK)) { \ @@ -54,14 +54,6 @@ pc += 1; \ } -enum -{ - X_READ_NIL, - X_WRITE_NIL, - X_TOO_MANY_TRIES, - X_ARRAY_OUT_OF_BOUNDS -}; - #define GETADDR(a,o,x) \ if (a == NULL) { THROW(x); } \ ptr = (VM_SBYTE *)a + o diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index 8232340a0e..42a3740301 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -786,27 +786,51 @@ begin: OP(DIV_RR): ASSERTD(a); ASSERTD(B); ASSERTD(C); + if (reg.d[C] == 0) + { + THROW(X_DIVISION_BY_ZERO); + } reg.d[a] = reg.d[B] / reg.d[C]; NEXTOP; OP(DIV_RK): ASSERTD(a); ASSERTD(B); ASSERTKD(C); + if (konstd[C] == 0) + { + THROW(X_DIVISION_BY_ZERO); + } reg.d[a] = reg.d[B] / konstd[C]; NEXTOP; OP(DIV_KR): ASSERTD(a); ASSERTKD(B); ASSERTD(C); + if (reg.d[C] == 0) + { + THROW(X_DIVISION_BY_ZERO); + } reg.d[a] = konstd[B] / reg.d[C]; NEXTOP; OP(MOD_RR): ASSERTD(a); ASSERTD(B); ASSERTD(C); + if (reg.d[C] == 0) + { + THROW(X_DIVISION_BY_ZERO); + } reg.d[a] = reg.d[B] % reg.d[C]; NEXTOP; OP(MOD_RK): ASSERTD(a); ASSERTD(B); ASSERTKD(C); + if (konstd[C] == 0) + { + THROW(X_DIVISION_BY_ZERO); + } reg.d[a] = reg.d[B] % konstd[C]; NEXTOP; OP(MOD_KR): ASSERTD(a); ASSERTKD(B); ASSERTD(C); + if (reg.d[C] == 0) + { + THROW(X_DIVISION_BY_ZERO); + } reg.d[a] = konstd[B] % reg.d[C]; NEXTOP; @@ -981,14 +1005,26 @@ begin: OP(DIVF_RR): ASSERTF(a); ASSERTF(B); ASSERTF(C); + if (reg.f[C] == 0.) + { + THROW(X_DIVISION_BY_ZERO); + } reg.f[a] = reg.f[B] / reg.f[C]; NEXTOP; OP(DIVF_RK): ASSERTF(a); ASSERTF(B); ASSERTKF(C); + if (konstf[C] == 0.) + { + THROW(X_DIVISION_BY_ZERO); + } reg.f[a] = reg.f[B] / konstf[C]; NEXTOP; OP(DIVF_KR): ASSERTF(a); ASSERTKF(B); ASSERTF(C); + if (reg.f[C] == 0.) + { + THROW(X_DIVISION_BY_ZERO); + } reg.f[a] = konstf[B] / reg.f[C]; NEXTOP; @@ -996,6 +1032,10 @@ begin: ASSERTF(a); ASSERTF(B); ASSERTF(C); fb = reg.f[B]; fc = reg.f[C]; Do_MODF: + if (fc == 0.) + { + THROW(X_DIVISION_BY_ZERO); + } reg.f[a] = luai_nummod(fb, fc); NEXTOP; OP(MODF_RK): diff --git a/src/zscript/vmframe.cpp b/src/zscript/vmframe.cpp index c7d9cb87d7..29da0c5b91 100644 --- a/src/zscript/vmframe.cpp +++ b/src/zscript/vmframe.cpp @@ -407,6 +407,44 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur } throw; } + catch (EVMAbortException exception) + { + if (allocated) + { + PopFrame(); + } + if (trap != nullptr) + { + *trap = nullptr; + } + + Printf("VM execution aborted: "); + switch (exception) + { + case X_READ_NIL: + Printf("tried to read from address zero."); + break; + + case X_WRITE_NIL: + Printf("tried to write to address zero."); + break; + + case X_TOO_MANY_TRIES: + Printf("too many try-catch blocks."); + break; + + case X_ARRAY_OUT_OF_BOUNDS: + Printf("array access out of bounds."); + break; + + case X_DIVISION_BY_ZERO: + Printf("division by zero."); + break; + } + Printf("\n"); + + return -1; + } catch (...) { if (allocated) diff --git a/wadsrc/static/shaders/glsl/fuzz_noise.fp b/wadsrc/static/shaders/glsl/fuzz_noise.fp index 9f5da5f25c..17f15d03b2 100644 --- a/wadsrc/static/shaders/glsl/fuzz_noise.fp +++ b/wadsrc/static/shaders/glsl/fuzz_noise.fp @@ -5,9 +5,10 @@ vec4 ProcessTexel() { vec2 texCoord = vTexCoord.st; vec4 basicColor = getTexel(texCoord); + ivec2 texSize = textureSize(tex, 0); - texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0; - texCoord.y = float( int(texCoord.y * 128.0) ) / 128.0; + texCoord.x = float( int(texCoord.x * texSize.x) ) / texSize.x; + texCoord.y = float( int(texCoord.y * texSize.y) ) / texSize.y; float texX = sin(mod(texCoord.x * 100.0 + timer*5.0, 3.489)) + texCoord.x / 4.0; float texY = cos(mod(texCoord.y * 100.0 + timer*5.0, 3.489)) + texCoord.y / 4.0; diff --git a/wadsrc/static/shaders/glsl/fuzz_standard.fp b/wadsrc/static/shaders/glsl/fuzz_standard.fp index fd87eaa468..95ba524319 100644 --- a/wadsrc/static/shaders/glsl/fuzz_standard.fp +++ b/wadsrc/static/shaders/glsl/fuzz_standard.fp @@ -5,9 +5,10 @@ vec4 ProcessTexel() { vec2 texCoord = vTexCoord.st; vec4 basicColor = getTexel(texCoord); + ivec2 texSize = textureSize(tex, 0); - texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0; - texCoord.y = float( int(texCoord.y * 128.0) ) / 128.0; + texCoord.x = float( int(texCoord.x * texSize.x) ) / texSize.x; + texCoord.y = float( int(texCoord.y * texSize.y) ) / texSize.y; float texX = texCoord.x / 3.0 + 0.66; float texY = 0.34 - texCoord.y / 3.0;