From 2b985bda857fabcd07710265cafdd68e9dabfd50 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 Jul 2016 14:57:19 +0100 Subject: [PATCH 001/207] Make sure we detect if start >= numlines so we can deal with that properly for some apparent reason the compiler didn't like the while loop condition edit on its own (it complained about inline failures for P_MobjReadyToTrigger for some reason), so I had to add that extra bit above the while loop... and it was happy again, huh --- src/p_spec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 0bd53027..e11235d8 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1188,7 +1188,10 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) { start++; - while (lines[start].special != special) + if (start >= (INT32)numlines) + return -1; + + while (start < (INT32)numlines && lines[start].special != special) start++; if (start >= (INT32)numlines) From 4c4f124611a98c66b929403aaaad0eb1a8f63018 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 Jul 2016 16:07:26 +0100 Subject: [PATCH 002/207] Detect if -warp's parm is actually a valid map name (MAPxx or plain number), and print an "invalid map name" message if not --- src/d_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 14a8a06e..b61ec414 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1060,10 +1060,11 @@ void D_SRB2Main(void) if (M_CheckParm("-warp") && M_IsNextParm()) { const char *word = M_GetNextParm(); - if (fastncmp(word, "MAP", 3)) + char ch; // use this with sscanf to catch non-digits with + if (fastncmp(word, "MAP", 3)) // MAPxx name pstartmap = M_MapNumber(word[3], word[4]); - else - pstartmap = atoi(word); + else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number + I_Error("Cannot warp to map %s (invalid map name)\n", word); // Don't check if lump exists just yet because the wads haven't been loaded! // Just do a basic range check here. if (pstartmap < 1 || pstartmap > NUMMAPS) From 02d3382408adaa81bc68af99c5699747f345014b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 7 Aug 2016 12:17:31 -0500 Subject: [PATCH 003/207] Leave a note to anyone foolish enough to try to fix this --- src/p_spec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index e11235d8..30b08ebb 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1188,6 +1188,8 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) { start++; + // This redundant check stops the compiler from complaining about function expansion + // elsewhere for some reason and everything is awful if (start >= (INT32)numlines) return -1; From 7795e146fa36959426539001a0176479146103c9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 12 Aug 2016 15:56:07 +0100 Subject: [PATCH 004/207] Two seperate single-line fixes, both concerning the end of NiGHTS maps. * The NiGHTS drone had a single tic of visibility when you hit the goal, which is evident stepping frame by frame through http://gfycat.com/ComplicatedComposedAoudad (the contents of which may or may not make it into 2.2). * When completing a NiGHTS stage with a non-zero link, the link could flash up in the final few tics before the fade to black. This just checks for player->exiting to make sure it shouldn't be shown. --- src/p_mobj.c | 1 + src/st_stuff.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 62dee0a6..000022b1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6931,6 +6931,7 @@ void P_MobjThinker(mobj_t *mobj) { mobj->flags &= ~MF_NOGRAVITY; P_SetMobjState(mobj, S_NIGHTSDRONE1); + mobj->flags2 |= MF2_DONTDRAW; } } else if (mobj->tracer && mobj->tracer->player) diff --git a/src/st_stuff.c b/src/st_stuff.c index aac6b09d..5b208d33 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -974,8 +974,8 @@ static void ST_drawNiGHTSHUD(void) if (cv_debug & DBG_NIGHTSBASIC) minlink = 0; - // Cheap hack: don't display when the score is showing - if (stplyr->texttimer && stplyr->textvar == 4) + // Cheap hack: don't display when the score is showing or you're exiting a map + if ((stplyr->exiting) || (stplyr->texttimer && stplyr->textvar == 4)) minlink = INT32_MAX; if (G_IsSpecialStage(gamemap)) From 104fc8ba98db280b3681198a52f693a8fe3d3e1d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 12 Aug 2016 16:01:03 +0100 Subject: [PATCH 005/207] Partially reverted on Inu's reccomendation. --- src/st_stuff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 5b208d33..06639d4f 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -974,8 +974,8 @@ static void ST_drawNiGHTSHUD(void) if (cv_debug & DBG_NIGHTSBASIC) minlink = 0; - // Cheap hack: don't display when the score is showing or you're exiting a map - if ((stplyr->exiting) || (stplyr->texttimer && stplyr->textvar == 4)) + // Cheap hack: don't display when the score is showing (it popping up for a split second when exiting a map is intentional) + if (stplyr->texttimer && stplyr->textvar == 4) minlink = INT32_MAX; if (G_IsSpecialStage(gamemap)) From 5d6463fafc1fb16930f23f8bd314a41d690bc565 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 13 Aug 2016 13:39:24 +0100 Subject: [PATCH 006/207] Fixed Knuckles being able to climb in space in OpenGL. To understand: look at AjustSegs(void) in hw_bsp.c. It reallocates the vetex_t pointers for lines as POLYVERTEX_T pointers, and of COURSE things are gonna get wacky when you're casting pointers. I dunno how resilient the FLOAT_TO_FIXED solution is or whether it'll be netgame compatible (yayyy float precision loss) but it's not like our builds are netgame compatible with themselves --- src/r_main.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 1ad125cd..4c81b9d8 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -33,6 +33,7 @@ #ifdef HWRENDER #include "hardware/hw_main.h" +#include "hardware/hw_glob.h" // polyvertex_t #endif //profile stuff --------------------------------------------------------- @@ -268,10 +269,28 @@ INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node) // killough 5/2/98: reformatted INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) { - fixed_t lx = line->v1->x; - fixed_t ly = line->v1->y; - fixed_t ldx = line->v2->x - lx; - fixed_t ldy = line->v2->y - ly; + fixed_t lx, ly, ldx, ldy; + +#ifdef HWRENDER // how did nobody notice this for years + // used for the hardware render + if (rendermode != render_soft && rendermode != render_none) + { + lx = FLOAT_TO_FIXED(((polyvertex_t *)line->v1)->x); + ly = FLOAT_TO_FIXED(((polyvertex_t *)line->v1)->y); + ldx = FLOAT_TO_FIXED(((polyvertex_t *)line->v2)->x); + ldy = FLOAT_TO_FIXED(((polyvertex_t *)line->v2)->y); + } + else +#endif + { + lx = line->v1->x; + ly = line->v1->y; + ldx = line->v2->x; + ldy = line->v2->y; + } + + ldx -= lx; + ldy -= ly; if (!ldx) return x <= lx ? ldy > 0 : ldy < 0; From 612575620be9a98c4d42806617e8a7b44a26cacc Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 13 Aug 2016 14:16:06 +0100 Subject: [PATCH 007/207] Solved the climbing-on-one-sided-lines problem another way, using the last touched line's attributes. (After talking to Alam, we can't have floats anywhere near P_ functions, so.) --- src/p_map.c | 2 +- src/p_user.c | 23 ++++++++++------------- src/r_main.c | 27 ++++----------------------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 1f2d903e..48f4cca2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2657,7 +2657,7 @@ isblocking: // see about climbing on the wall if (!(checkline->flags & ML_NOCLIMB)) { - boolean canclimb; // FUCK C90 + boolean canclimb; angle_t climbangle, climbline; INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); diff --git a/src/p_user.c b/src/p_user.c index 9cd6aa40..f390650f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2276,25 +2276,24 @@ static void P_DoClimbing(player_t *player) fixed_t platy; subsector_t *glidesector; boolean climb = true; + boolean onesided = ((player->lastsidehit != -1 && player->lastlinehit != -1) && !(lines[player->lastlinehit].backsector)); platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy); + glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); - if (!glidesector || glidesector->sector != player->mo->subsector->sector) + if (onesided || glidesector->sector != player->mo->subsector->sector) { - boolean floorclimb; - boolean thrust; - boolean boostup; - boolean skyclimber; + boolean floorclimb = false; + boolean thrust = false; + boolean boostup = false; + boolean skyclimber = false; fixed_t floorheight, ceilingheight; // ESLOPE - thrust = false; - floorclimb = false; - boostup = false; - skyclimber = false; - if (glidesector) + if (onesided) + floorclimb = true; + else { #ifdef ESLOPE floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) @@ -2589,8 +2588,6 @@ static void P_DoClimbing(player_t *player) } } } - else - floorclimb = true; if (player->lastsidehit != -1 && player->lastlinehit != -1) { diff --git a/src/r_main.c b/src/r_main.c index 4c81b9d8..1ad125cd 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -33,7 +33,6 @@ #ifdef HWRENDER #include "hardware/hw_main.h" -#include "hardware/hw_glob.h" // polyvertex_t #endif //profile stuff --------------------------------------------------------- @@ -269,28 +268,10 @@ INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node) // killough 5/2/98: reformatted INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) { - fixed_t lx, ly, ldx, ldy; - -#ifdef HWRENDER // how did nobody notice this for years - // used for the hardware render - if (rendermode != render_soft && rendermode != render_none) - { - lx = FLOAT_TO_FIXED(((polyvertex_t *)line->v1)->x); - ly = FLOAT_TO_FIXED(((polyvertex_t *)line->v1)->y); - ldx = FLOAT_TO_FIXED(((polyvertex_t *)line->v2)->x); - ldy = FLOAT_TO_FIXED(((polyvertex_t *)line->v2)->y); - } - else -#endif - { - lx = line->v1->x; - ly = line->v1->y; - ldx = line->v2->x; - ldy = line->v2->y; - } - - ldx -= lx; - ldy -= ly; + fixed_t lx = line->v1->x; + fixed_t ly = line->v1->y; + fixed_t ldx = line->v2->x - lx; + fixed_t ldy = line->v2->y - ly; if (!ldx) return x <= lx ? ldy > 0 : ldy < 0; From da23d93b00cece0ecd413c9090472dbfd6e6cafb Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 13 Aug 2016 10:03:17 -0400 Subject: [PATCH 008/207] Disable netplay for DirectDraw builds --- src/doomdef.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doomdef.h b/src/doomdef.h index 66e649ee..fb8ab1ca 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -60,6 +60,7 @@ #endif #ifdef _WINDOWS +#define NONET #if !defined (HWRENDER) && !defined (NOHW) #define HWRENDER #endif From be973d6990039eaec8b0fcec460d8cac72a1f273 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 13 Aug 2016 15:07:40 +0100 Subject: [PATCH 009/207] expanded comment for future generations --- src/r_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index 1ad125cd..498f4dab 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -771,7 +771,7 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y) } // -// R_IsPointInSubsector, same as above but returns 0 if not in subsector +// R_IsPointInSubsector, same as above but returns 0 if not in subsector - this does not work in opengl because of polyvertex_t // subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) { From bdb5db878a7d62545743575c8420d1b2db3e9ce9 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 13 Aug 2016 10:12:14 -0400 Subject: [PATCH 010/207] NONET should also disable UPNP support --- src/i_tcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index eca218c8..f6212458 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -56,7 +56,9 @@ //#define NONET #endif -#ifndef NONET +#ifdef NONET +#undef HAVE_MINIUPNPC +#else #ifdef USE_WINSOCK1 #include #elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__) From f1a96342607a165963e754b580cab2a405a154a4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 13 Aug 2016 21:41:18 +0100 Subject: [PATCH 011/207] P_LineOpening now takes a mobj_t argument, instead of relying on tmthing . tmthing can be NULL if called from PTR_SlideTraverse, so we should use slidemo instead This fixes a crash that occurs in yet ANOTHER SUGOI map, involving bouncy walls next to sloped floors/ceilings --- src/p_map.c | 4 ++-- src/p_maputl.c | 42 +++++++++++++++++++++--------------------- src/p_maputl.h | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 1f2d903e..ccf2b100 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1153,7 +1153,7 @@ static boolean PIT_CheckLine(line_t *ld) } // set openrange, opentop, openbottom - P_LineOpening(ld); + P_LineOpening(ld, tmthing); // adjust floor / ceiling heights if (opentop < tmceilingz) @@ -2581,7 +2581,7 @@ static boolean PTR_SlideTraverse(intercept_t *in) } // set openrange, opentop, openbottom - P_LineOpening(li); + P_LineOpening(li, slidemo); if (openrange < slidemo->height) goto isblocking; // doesn't fit diff --git a/src/p_maputl.c b/src/p_maputl.c index c3a6fa84..df2bf8f5 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -489,7 +489,7 @@ void P_CameraLineOpening(line_t *linedef) } } -void P_LineOpening(line_t *linedef) +void P_LineOpening(line_t *linedef, mobj_t *mobj) { sector_t *front, *back; @@ -520,8 +520,8 @@ void P_LineOpening(line_t *linedef) { // Set open and high/low values here fixed_t frontheight, backheight; - frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef); - backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef); + frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef); + backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef); if (frontheight < backheight) { @@ -540,8 +540,8 @@ void P_LineOpening(line_t *linedef) #endif } - frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); - backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef); + frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef); + backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef); if (frontheight > backheight) { @@ -561,9 +561,9 @@ void P_LineOpening(line_t *linedef) } } - if (tmthing) + if (mobj) { - fixed_t thingtop = tmthing->z + tmthing->height; + fixed_t thingtop = mobj->z + mobj->height; // Check for collision with front side's midtexture if Effect 4 is set if (linedef->flags & ML_EFFECT4) { @@ -598,7 +598,7 @@ void P_LineOpening(line_t *linedef) texmid = texbottom+(textop-texbottom)/2; - delta1 = abs(tmthing->z - texmid); + delta1 = abs(mobj->z - texmid); delta2 = abs(thingtop - texmid); if (delta1 > delta2) { // Below @@ -636,16 +636,16 @@ void P_LineOpening(line_t *linedef) if (!(rover->flags & FF_EXISTS)) continue; - if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover))) + if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover))) ; - else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player) - || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) + else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) continue; - topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef); + topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef); - delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF @@ -680,16 +680,16 @@ void P_LineOpening(line_t *linedef) if (!(rover->flags & FF_EXISTS)) continue; - if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover))) + if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover))) ; - else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player) - || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) + else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) continue; - topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef); + topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef); - delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF @@ -723,7 +723,7 @@ void P_LineOpening(line_t *linedef) { const sector_t *polysec = linedef->backsector; - delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); + delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); if (polysec->floorheight < lowestceiling && delta1 >= delta2) { lowestceiling = polysec->floorheight; diff --git a/src/p_maputl.h b/src/p_maputl.h index c160bfa2..3d74e927 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -59,7 +59,7 @@ extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; extern pslope_t *opentopslope, *openbottomslope; #endif -void P_LineOpening(line_t *plinedef); +void P_LineOpening(line_t *plinedef, mobj_t *mobj); boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *)); boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *)); From 758c77fe53a90a6013801f754bb083c851c99d8c Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 13 Aug 2016 17:43:22 -0500 Subject: [PATCH 012/207] Fixed non-players having fucked slope stepup/down --- src/p_map.c | 8 ++++++-- src/p_mobj.c | 6 ++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 1f2d903e..24573605 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1970,8 +1970,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } // Ramp test - if (thing->player && maxstep > 0 - && !(P_PlayerTouchingSectorSpecial(thing->player, 1, 14) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)) + if (maxstep > 0 && !( + thing->player && ( + P_PlayerTouchingSectorSpecial(thing->player, 1, 14) + || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14) + ) + ) { // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. diff --git a/src/p_mobj.c b/src/p_mobj.c index 62dee0a6..77dfd192 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1650,8 +1650,6 @@ void P_XYMovement(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - moved = true; - // if it's stopped if (!mo->momx && !mo->momy) { @@ -1708,9 +1706,9 @@ void P_XYMovement(mobj_t *mo) if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG)) { // blocked move + moved = false; if (player) { - moved = false; if (player->bot) B_MoveBlocked(player); } @@ -1815,7 +1813,7 @@ void P_XYMovement(mobj_t *mo) else mo->momx = mo->momy = 0; } - else if (player) + else moved = true; if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; From 55b8ef9f641947d68e6ce40bd7b03f775ed984fd Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 14 Aug 2016 00:03:00 -0500 Subject: [PATCH 013/207] More stepping upward fixing ugh --- src/p_mobj.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 77dfd192..1eb50323 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2373,6 +2373,12 @@ static boolean P_ZMovement(mobj_t *mo) mo->z = mo->floorz; #ifdef ESLOPE + if (mo->standingslope) // You're still on the ground; why are we here? + { + mo->momz = 0; + return; + } + P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { From 0264fd24ae541adaa8d261e6ebe4690470c84d00 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 14 Aug 2016 10:43:44 -0400 Subject: [PATCH 014/207] @MonsterIestyn: Should probably be returning true then --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1eb50323..e1a1820a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2376,7 +2376,7 @@ static boolean P_ZMovement(mobj_t *mo) if (mo->standingslope) // You're still on the ground; why are we here? { mo->momz = 0; - return; + return true; } P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly From 1530183ddf1323748938cd41919aa4816b1f68a7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 14 Aug 2016 16:56:41 +0100 Subject: [PATCH 015/207] Fix multiple solid midtexture-related issues: * Effect 3 (Peg Midtexture) is now accounted for properly, flipping the collision box position to match the actual rendered position of the midtexture * Fixed incorrect application of y-offsets for non-lower unpegged midtextures collision boxes; +ve always goes up, -ve always goes down! * Effect 4 now doesn't make midtextures solid for polyobjects at all - this "conflicted" with First Line having both Effect 4 (visible planes) and Effect 3 (intangible) simultaneously, where we kind of expect the first line's wall to not be made solid. This may be less of a problem in future SRB2 versions, but for now solid midtextures for polyobjects are disabled. --- src/p_maputl.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index df2bf8f5..37367912 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -566,7 +566,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) fixed_t thingtop = mobj->z + mobj->height; // Check for collision with front side's midtexture if Effect 4 is set - if (linedef->flags & ML_EFFECT4) { + if (linedef->flags & ML_EFFECT4 + && !linedef->polyobj // don't do anything for polyobjects! ...for now + ) { side_t *side = &sides[linedef->sidenum[0]]; fixed_t textop, texbottom, texheight; fixed_t texmid, delta1, delta2; @@ -575,23 +577,25 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS; // Set texbottom and textop to the Z coordinates of the texture's boundaries -#ifdef POLYOBJECTS +#if 0 // #ifdef POLYOBJECTS + // don't remove this code unless solid midtextures + // on non-solid polyobjects should NEVER happen in the future if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { - if (linedef->flags & ML_DONTPEGBOTTOM) { + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { texbottom = back->floorheight + side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); } else { - textop = back->ceilingheight - side->rowoffset; + textop = back->ceilingheight + side->rowoffset; texbottom = textop - texheight*(side->repeatcnt+1); } } else #endif { - if (linedef->flags & ML_DONTPEGBOTTOM) { + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { texbottom = openbottom + side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); } else { - textop = opentop - side->rowoffset; + textop = opentop + side->rowoffset; texbottom = textop - texheight*(side->repeatcnt+1); } } From 3d9fe7c899d7c63c91f8605fe6e503b68201540c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 19 Aug 2016 00:06:12 +0100 Subject: [PATCH 016/207] The ability to disable weapon rings, as heavily requested by Lat and Speedwagon for their high effort character .wads and selfishly also desired to make thokker less hacky. --- src/lua_hud.h | 3 +++ src/lua_hudlib.c | 3 +++ src/st_stuff.c | 14 ++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/src/lua_hud.h b/src/lua_hud.h index 799ce2fb..80e8ae03 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -18,6 +18,9 @@ enum hud { hud_time, hud_rings, hud_lives, + // Match + hud_weaponrings, + hud_powerstones, // NiGHTS mode hud_nightslink, hud_nightsdrill, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 31549afa..7aadd9c0 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -44,6 +44,9 @@ static const char *const hud_disable_options[] = { "rings", "lives", + "weaponrings", + "powerstones", + "nightslink", "nightsdrill", "nightsrings", diff --git a/src/st_stuff.c b/src/st_stuff.c index aac6b09d..ca315ce2 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1385,6 +1385,10 @@ static void ST_drawMatchHUD(void) if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT)) return; +#ifdef HAVE_BLUA + if (LUA_HudEnabled(hud_weaponrings)) { +#endif + if (stplyr->powers[pw_infinityring]) ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring); else if (stplyr->health > 1) @@ -1408,6 +1412,12 @@ static void ST_drawMatchHUD(void) offset += 20; ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring); +#ifdef HAVE_BLUA + } + + if (LUA_HudEnabled(hud_powerstones)) { +#endif + // Power Stones collected offset = 136; // Used for Y now @@ -1439,6 +1449,10 @@ static void ST_drawMatchHUD(void) if (stplyr->powers[pw_emeralds] & EMERALD7) V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]); + +#ifdef HAVE_BLUA + } +#endif } static inline void ST_drawRaceHUD(void) From 3db3433a513b84ddd26774490e4f51f6c8758c09 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 19 Aug 2016 00:07:32 +0100 Subject: [PATCH 017/207] More consistent comment. --- src/lua_hud.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index 80e8ae03..ba0a1d89 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -18,7 +18,7 @@ enum hud { hud_time, hud_rings, hud_lives, - // Match + // Match / CTF / Tag / Ringslinger hud_weaponrings, hud_powerstones, // NiGHTS mode From 44df9358dd37bec003674e44141441165dba1ee1 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Fri, 19 Aug 2016 22:18:43 -0700 Subject: [PATCH 018/207] If the game becomes modified during a record attack run, end it RA menu can be opened if the game is modified, but Start can't be selected. (Obvious reason: so scripts to display info can be used easier) Fixed the stupid background for messages in the Record Attack menu, it was bugging me --- src/g_game.c | 4 ++++ src/m_menu.c | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 8931f8b6..f891b010 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -711,6 +711,10 @@ void G_SetGameModified(boolean silent) if (!silent) CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n")); + + // If in record attack recording, cancel it. + if (modeattacking) + M_EndModeAttackRun(); } /** Builds an original game map name from a map number. diff --git a/src/m_menu.c b/src/m_menu.c index 6c129444..78c38127 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -705,7 +705,7 @@ static menuitem_t SP_TimeAttackMenu[] = {IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100}, {IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110}, {IT_DISABLED, NULL, "Ghosts...", &SP_GhostDef, 120}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_ChooseTimeAttack, 130}, + {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseTimeAttack, 130}, }; enum @@ -797,7 +797,7 @@ static menuitem_t SP_NightsAttackMenu[] = {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 108}, {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 118}, {IT_DISABLED, NULL, "Ghosts...", &SP_NightsGhostDef, 128}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_ChooseNightsAttack, 138}, + {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseNightsAttack, 138}, }; enum @@ -3702,6 +3702,11 @@ static void M_DrawMessageMenu(void) mlines = currentMenu->lastOn>>8; max = (INT16)((UINT8)(currentMenu->lastOn & 0xFF)*8); + + // hack: draw RA background in RA menus + if (gamestate == GS_TIMEATTACK) + V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); + M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines); while (*(msg+start)) @@ -4310,9 +4315,9 @@ static void M_SinglePlayerMenu(INT32 choice) { (void)choice; SP_MainMenu[sprecordattack].status = - (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; + (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; SP_MainMenu[spnightsmode].status = - (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; + (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; M_SetupNextMenu(&SP_MainDef); } From ab3f677e664fc732e265c4a0d87f4ab05d241d13 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 25 Aug 2016 17:58:54 +0100 Subject: [PATCH 019/207] F_EndCutScene now sets cutsceneover to true BEFORE running Y_EndGame and the like, not AFTER --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 784d8204..2245a534 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1725,6 +1725,7 @@ static void F_AdvanceToNextScene(void) void F_EndCutScene(void) { + cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later if (runningprecutscene) { if (server) @@ -1741,7 +1742,6 @@ void F_EndCutScene(void) else Y_EndGame(); } - cutsceneover = true; } void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer) From 2a6a21a4a28bfcce0c16fa83090386ac4ecbd467 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 27 Aug 2016 17:14:21 +0100 Subject: [PATCH 020/207] Solid midtextures now account for "infinite" repeats --- src/p_maputl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 37367912..fea8530a 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -581,7 +581,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // don't remove this code unless solid midtextures // on non-solid polyobjects should NEVER happen in the future if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + texbottom = back->floorheight + side->rowoffset; + textop = back->ceilingheight + side->rowoffset; + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { texbottom = back->floorheight + side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); } else { @@ -591,7 +594,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) } else #endif { - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + texbottom = openbottom + side->rowoffset; + textop = opentop + side->rowoffset; + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { texbottom = openbottom + side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); } else { From 50ce152c69fa11faef84cb51f215d787852d4742 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 Aug 2016 13:19:17 +0100 Subject: [PATCH 021/207] Cleaned up some performance issues in Skytop Zone (2.1.16: THE SUGOI UPDATE) arising from some inefficiencies with P_GetMobjGravity. FPS drops only occasionally to 34 now, which is a big improvement when I was frequently getting 27 in Salt's 15andahalf.exe. --- src/p_mobj.c | 57 +++++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 62dee0a6..91451e06 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1278,25 +1278,23 @@ fixed_t P_GetMobjGravity(mobj_t *mo) for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!((rover->flags & FF_EXISTS) && (P_InsideANonSolidFFloor(mo, rover)))) continue; - if (P_InsideANonSolidFFloor(mo, rover)) - { - if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) - goopgravity = true; - if (rover->master->frontsector->gravity) - { - gravityadd = -FixedMul(gravity, - (FixedDiv(*rover->master->frontsector->gravity>>FRACBITS, 1000))); + if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) + goopgravity = true; - if (rover->master->frontsector->verticalflip && gravityadd > 0) - mo->eflags |= MFE_VERTICALFLIP; + if (!(rover->master->frontsector->gravity)) + continue; - no3dfloorgrav = false; - break; - } - } + gravityadd = -FixedMul(gravity, + (FixedDiv(*rover->master->frontsector->gravity>>FRACBITS, 1000))); + + if (rover->master->frontsector->verticalflip && gravityadd > 0) + mo->eflags |= MFE_VERTICALFLIP; + + no3dfloorgrav = false; + break; } } @@ -1318,28 +1316,22 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (mo->player) { - if (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly] - || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4]))) - gravityadd = gravityadd/3; // less gravity while flying - if (mo->player->pflags & PF_GLIDING) - gravityadd = gravityadd/3; // less gravity while gliding - if (mo->player->climbing) - gravityadd = 0; - if (mo->player->pflags & PF_NIGHTSMODE) + if ((mo->player->pflags & PF_GLIDING) + || (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly] + || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4])))) + gravityadd = gravityadd/3; // less gravity while flying/gliding + if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)) gravityadd = 0; { - UINT8 bits = 0; - if (mo->flags2 & MF2_OBJECTFLIP) - bits ^= 1; - if (mo->player->powers[pw_gravityboots]) - bits ^= 1; - if (bits & 1) + if (!!(mo->flags2 & MF2_OBJECTFLIP) != !!(mo->player->powers[pw_gravityboots])) { gravityadd = -gravityadd; mo->eflags ^= MFE_VERTICALFLIP; } } + if (!!(mo->eflags & MFE_VERTICALFLIP) != wasflip) + P_PlayerFlip(mo); } else { @@ -1347,10 +1339,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (mo->flags2 & MF2_OBJECTFLIP) { mo->eflags |= MFE_VERTICALFLIP; - if (gravityadd < 0) // Don't sink, only rise up - gravityadd *= -1; if (mo->z + mo->height >= mo->ceilingz) gravityadd = 0; + else if (gravityadd < 0) // Don't sink, only rise up + gravityadd *= -1; } else //Otherwise, sort through the other exceptions. { @@ -1396,9 +1388,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (goopgravity) gravityadd = -gravityadd/5; - if (mo->player && !!(mo->eflags & MFE_VERTICALFLIP) != wasflip) - P_PlayerFlip(mo); - gravityadd = FixedMul(gravityadd, mo->scale); return gravityadd; From c0f5f22b6a11d66f68ff72ba1127f640964dfacf Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 Aug 2016 13:51:32 +0100 Subject: [PATCH 022/207] Suggested improvement by MI on irc. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 91451e06..a66e9cf7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1278,7 +1278,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - if (!((rover->flags & FF_EXISTS) && (P_InsideANonSolidFFloor(mo, rover)))) + if (!(rover->flags & FF_EXISTS) || !P_InsideANonSolidFFloor(mo, rover)) continue; if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) From 25ab97786285cc89a66b5f2c765b5632c85af905 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 Aug 2016 14:06:20 +0100 Subject: [PATCH 023/207] ...didn't realise P_InsideANonSolidFFloor checks for FF_EXISTS itself, so HM --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a66e9cf7..7a96dfd5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1278,7 +1278,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !P_InsideANonSolidFFloor(mo, rover)) + if (!P_InsideANonSolidFFloor(mo, rover)) // P_InsideANonSolidFFloor checks for FF_EXISTS itself continue; if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) From e8775419d135a40ea549824fe90139c8d134cbc4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 Aug 2016 14:09:15 +0100 Subject: [PATCH 024/207] Removed now-irrelevant braces. --- src/p_mobj.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7a96dfd5..547941e7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1323,12 +1323,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)) gravityadd = 0; + if (!!(mo->flags2 & MF2_OBJECTFLIP) != !!(mo->player->powers[pw_gravityboots])) { - if (!!(mo->flags2 & MF2_OBJECTFLIP) != !!(mo->player->powers[pw_gravityboots])) - { - gravityadd = -gravityadd; - mo->eflags ^= MFE_VERTICALFLIP; - } + gravityadd = -gravityadd; + mo->eflags ^= MFE_VERTICALFLIP; } if (!!(mo->eflags & MFE_VERTICALFLIP) != wasflip) P_PlayerFlip(mo); From 3bad307e2d464eeae5d106183db6b7620c6e3bd7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 Aug 2016 20:46:56 +0100 Subject: [PATCH 025/207] Sorry, Inu. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 547941e7..68f4f40f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1278,7 +1278,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - if (!P_InsideANonSolidFFloor(mo, rover)) // P_InsideANonSolidFFloor checks for FF_EXISTS itself + if (!(rover->flags & FF_EXISTS) || !P_InsideANonSolidFFloor(mo, rover)) // P_InsideANonSolidFFloor checks for FF_EXISTS itself, but let's not always call this function continue; if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) From eae47c9808335c7177a85769a10f1ddaf58e59b5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 1 Sep 2016 21:21:20 +0100 Subject: [PATCH 026/207] Fix Knuckles in 2D mode attempting to latch onto air when gliding into a slope. Now he just attempts to latch onto the slope directly (which I'll fix another time, if I can figure out how) (fix for SUGOI's Retro Hill Zone) --- src/p_user.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index f390650f..4d8b6af1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6976,6 +6976,7 @@ static void P_MovePlayer(player_t *player) msecnode_t *node; // only place it's being used in P_MovePlayer now fixed_t oldx; fixed_t oldy; + fixed_t floorz, ceilingz; oldx = player->mo->x; oldy = player->mo->y; @@ -6993,31 +6994,34 @@ static void P_MovePlayer(player_t *player) if (node->m_sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) + continue; - if ((rover->flags & FF_BLOCKPLAYER)) + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + if (topheight > player->mo->z && bottomheight < player->mo->z) { - if (*rover->topheight > player->mo->z && *rover->bottomheight < player->mo->z) - { - P_ResetPlayer(player); - S_StartSound(player->mo, sfx_s3k4a); - player->climbing = 5; - player->mo->momx = player->mo->momy = player->mo->momz = 0; - break; - } + P_ResetPlayer(player); + S_StartSound(player->mo, sfx_s3k4a); + player->climbing = 5; + player->mo->momx = player->mo->momy = player->mo->momz = 0; + break; } } } - if (player->mo->z+player->mo->height > node->m_sector->ceilingheight + floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL); + ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL); + + if (player->mo->z+player->mo->height > ceilingz && node->m_sector->ceilingpic == skyflatnum) continue; - if (node->m_sector->floorheight > player->mo->z - || node->m_sector->ceilingheight < player->mo->z) + if (floorz > player->mo->z || ceilingz < player->mo->z) { P_ResetPlayer(player); S_StartSound(player->mo, sfx_s3k4a); From 8f02c50c1068ee6440b0f8e180f2805f9f778062 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 2 Sep 2016 21:41:45 +0100 Subject: [PATCH 027/207] Fix players and pushables not accounting for slopes on bustable FOFs --- src/p_mobj.c | 19 +++++++++++-------- src/p_user.c | 22 +++++++++++++--------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e1a1820a..9f4f2429 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1553,6 +1553,7 @@ static void P_PushableCheckBustables(mobj_t *mo) if (node->m_sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; for (rover = node->m_sector->ffloors; rover; rover = rover->next) { @@ -1565,37 +1566,39 @@ static void P_PushableCheckBustables(mobj_t *mo) if (!rover->master->frontsector->crumblestate) { + topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); + bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); // Height checks if (rover->flags & FF_SHATTERBOTTOM) { - if (mo->z+mo->momz + mo->height < *rover->bottomheight) + if (mo->z+mo->momz + mo->height < bottomheight) continue; - if (mo->z+mo->height > *rover->bottomheight) + if (mo->z+mo->height > bottomheight) continue; } else if (rover->flags & FF_SPINBUST) { - if (mo->z+mo->momz > *rover->topheight) + if (mo->z+mo->momz > topheight) continue; - if (mo->z+mo->height < *rover->bottomheight) + if (mo->z+mo->height < bottomheight) continue; } else if (rover->flags & FF_SHATTER) { - if (mo->z+mo->momz > *rover->topheight) + if (mo->z+mo->momz > topheight) continue; - if (mo->z+mo->momz + mo->height < *rover->bottomheight) + if (mo->z+mo->momz + mo->height < bottomheight) continue; } else { - if (mo->z >= *rover->topheight) + if (mo->z >= topheight) continue; - if (mo->z+mo->height < *rover->bottomheight) + if (mo->z+mo->height < bottomheight) continue; } diff --git a/src/p_user.c b/src/p_user.c index 4d8b6af1..3867137a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1692,6 +1692,7 @@ static void P_CheckBustableBlocks(player_t *player) if (node->m_sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; for (rover = node->m_sector->ffloors; rover; rover = rover->next) { @@ -1717,42 +1718,45 @@ static void P_CheckBustableBlocks(player_t *player) if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) && !(player->charability == CA_GLIDEANDCLIMB)) continue; + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + // Height checks if (rover->flags & FF_SHATTERBOTTOM) { - if (player->mo->z+player->mo->momz + player->mo->height < *rover->bottomheight) + if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) continue; - if (player->mo->z+player->mo->height > *rover->bottomheight) + if (player->mo->z+player->mo->height > bottomheight) continue; } else if (rover->flags & FF_SPINBUST) { - if (player->mo->z+player->mo->momz > *rover->topheight) + if (player->mo->z+player->mo->momz > topheight) continue; - if (player->mo->z + player->mo->height < *rover->bottomheight) + if (player->mo->z + player->mo->height < bottomheight) continue; } else if (rover->flags & FF_SHATTER) { - if (player->mo->z + player->mo->momz > *rover->topheight) + if (player->mo->z + player->mo->momz > topheight) continue; - if (player->mo->z+player->mo->momz + player->mo->height < *rover->bottomheight) + if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) continue; } else { - if (player->mo->z >= *rover->topheight) + if (player->mo->z >= topheight) continue; - if (player->mo->z + player->mo->height < *rover->bottomheight) + if (player->mo->z + player->mo->height < bottomheight) continue; } // Impede the player's fall a bit - if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= *rover->topheight) + if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight) player->mo->momz >>= 1; else if (rover->flags & FF_SHATTER) { From a860c068d8852c531f1ae23a9fd8c53c2cdeb98b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 2 Sep 2016 22:53:55 +0100 Subject: [PATCH 028/207] BONUS UNRELATED FIX: Fix FF_SHATTERBOTTOM FOFs acting like THZ goop when stood on --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index d8c48fa4..c4616db4 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1271,7 +1271,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL); bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL); - if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY)) + if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER) && !(thing->flags & MF_NOGRAVITY)) { // If you're inside goowater and slowing down fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); From 6ff75d2aa1bd6f2aa32e8e5a65de2e7ce79525ec Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Sep 2016 21:37:52 +0100 Subject: [PATCH 029/207] Double negation becomes single negation, with handy comment! --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 68f4f40f..eaef05aa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1323,7 +1323,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)) gravityadd = 0; - if (!!(mo->flags2 & MF2_OBJECTFLIP) != !!(mo->player->powers[pw_gravityboots])) + if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be { gravityadd = -gravityadd; mo->eflags ^= MFE_VERTICALFLIP; From 5bb0b5684e822ed773fda46a1d1c6b6f61732df2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Sep 2016 21:43:02 +0100 Subject: [PATCH 030/207] More irrelevant negation reduction, sorry. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index eaef05aa..6337730f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1328,7 +1328,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) gravityadd = -gravityadd; mo->eflags ^= MFE_VERTICALFLIP; } - if (!!(mo->eflags & MFE_VERTICALFLIP) != wasflip) + if (!(mo->eflags & MFE_VERTICALFLIP) == wasflip) P_PlayerFlip(mo); } else From 2d94256490d2c11fa91d0e9a05932cb508cc393b Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 3 Sep 2016 16:05:45 -0500 Subject: [PATCH 031/207] Shut the compiler up --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 6337730f..0d7f8884 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1328,7 +1328,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) gravityadd = -gravityadd; mo->eflags ^= MFE_VERTICALFLIP; } - if (!(mo->eflags & MFE_VERTICALFLIP) == wasflip) + if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way P_PlayerFlip(mo); } else From f1ab448442d9a8387634649de191c1be440b0cfa Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 3 Sep 2016 16:50:00 -0500 Subject: [PATCH 032/207] Readme rewrite --- README.md | 22 ++++++++ readme.txt | 155 ----------------------------------------------------- 2 files changed, 22 insertions(+), 155 deletions(-) create mode 100644 README.md delete mode 100644 readme.txt diff --git a/README.md b/README.md new file mode 100644 index 00000000..a357feea --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +Sonic Robo Blast 2 +================== +[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2) [![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2) +================== + +[Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/). + +## Dependencies +- NASM (x86 builds only) +- SDL2 (Linux/OS X only) +- SDL2-Mixer (Linux/OS X only) +- libupnp (Linux/OS X only) +- libgme (Linux/OS X only) + +Warning: 64-bit builds are not netgame compatible. Use at your own risk. + +## Compiling + +See [SRB2 Wiki/Source code compiling](http://wiki.srb2.org/wiki/Source_code_compiling) + +### Disclaimer +Sonic Team Junior is in no way affiliated with SEGA or Sonic Team. We do not claim ownership of any of SEGA's intellectual property used in SRB2. diff --git a/readme.txt b/readme.txt deleted file mode 100644 index c1898d49..00000000 --- a/readme.txt +++ /dev/null @@ -1,155 +0,0 @@ -Here it is! SRB2 v2.1.14 source code! -(why do we keep the version number up to date - when everything else in this file is hilariously old? - - Inuyasha) - - -Win32 with Visual C (6SP6+Processor Pack OR 7) -~~~ - -2 VC++ 6.0 project files are included: - -Win32/DirectX/FMOD -src\win32\wLegacy.dsw -You'll need FMOD to compile this version (www.fmod.org) -or -Win32/SDL/SDL_mixer -src\sdl\Win32SDL.dsp -You'll need SDL and SDL_mixer for this version (www.libsdl.org) - -Both needs NASM (http://sourceforge.net/projects/nasm) -For PNG screenshot, libPNG, and Zlib (from http://gnuwin32.sourceforge.net/) - -No warranty, support, etc. of any kind is offered, -just plain old as is. -Some bits of code are still really scary. -Go nuts! - - -Win32 with Dev-C++ (http://bloodshed.net/ free!) -~~~ -2 Dev-C++ project files are included: - -Win32/DirectX/FMOD -src\win32\SRB2.dev -or -Win32/SDL/SDL_mixer -src\sdl\Win32SDL.dev -You'll need SDL and SDL_mixer for this version (www.libsdl.org) -libPNG and Zlib (from http://gnuwin32.sourceforge.net/) -Note there are precompiled libpng.a and libz.a for Mingw - -you will need NASM for both SDL/SDL_mixer and DirectX/FMOD -and you need DirectX 6 (or up) Dev-Paks to compile DirectX version - -GNU/Linux -~~~ - -Dependencies: - SDL 1.2.7 or better (from libsdl.org) - SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org) - Nasm (use NOASM=1 if you don't have it or have an non-i386 system, I think) - libPNG 1.2.7 - Zlib 1.2.3 - The Xiph.org libogg and libvorbis libraries - The OpenGL headers (from Mesa, usually shipped with your X.org or XFree - installation, so you needn't worry, most likely) - GCC 3.x toolchain and binutils - GNU Make - -Build instructions: - -make -C src LINUX=1 - -Build instructions (64 bit): - -make -C src LINUX64=1 - -Build instructions to build for Wii Linux/SRB2Wii on a PowerPC system, -follow cross-compiling instructions for cross-compiling on a x86 system: - -make -C src LINUX=1 WIILINUX=1 - -Build instructions to build for Pandora (Linux) on a ARM system, -follow cross-compiling instructions for cross-compiling on a x86 system: - -make -C src PANDORA=1 - -Solaris -~~~ - -Dependencies: - SDL 1.2.5 or better (from libsdl.org) - SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org) - libPNG 1.2.7 - Zlib 1.2.3 - The Xiph.org libogg and libvorbis libraries - The OpenGL headers (from Mesa, usually shipped with your X.org or XFree - installation, so you needn't worry, most likely) - GCC 3.x toolchain and binutils - GNU Make - - You can get all these programs/libraries from the Companion CD (except SDL_mixer and OpenGL) - -Build instructions: - -gmake -C src SOLARIS=1 - -FreeBSD -~~~ - -Dependencies: - SDL 1.2.7 or better (from libsdl.org) - SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org) - Nasm (use NOASM=1 if you don't have it or have an non-i386 system, I think) - libPNG 1.2.7 - Zlib 1.2.3 - The Xiph.org libogg and libvorbis libraries - The OpenGL headers (from Mesa, usually shipped with your X.org or XFree - installation, so you needn't worry, most likely) - GCC 3.x toolchain and binutils - GNU Make - -Build instructions: - -gmake -C src FREEBSD=1 - -DJGPP/DOS -~~~ - -Dependencies: - Allegro 3.12 game programming library, (from - http://alleg.sourceforge.net/index.html) - Nasm (use NOASM=1 if you don't have it) - libsocket (from http://homepages.nildram.co.uk/~phekda/richdawe/lsck/) or - Watt-32 (from http://www.bgnett.no/~giva/) - GCC 3.x toolchain and binutils - GNU Make - -Build instructions: - -make -C src # to link with Watt-32, add WATTCP=1 - # for remote debugging over the COM port, add RDB=1 - -Notes: - use tools\djgpp\all313.diff to update Allegro to a "more usable" version ;) - Example: E:\djgpp\allegro>patch -p# < D:\SRB2Code\1.1\srb2\tools\djgpp\all313.diff - -Windows CE -~~~ - -Dependencies: - SDL 1.27 - -Build instructions: - -use src\SDL\WinCE\SRB2CE.vcw - -------------------------------------------------------------------------------- - -binaries will turn in up in bin/ - -note: read the src/makefile for more options - -- Sonic Team Junior -http://www.srb2.org From f9e01c2b652666d205f32a8c9f474b04f7f141f2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 4 Sep 2016 20:12:59 +0100 Subject: [PATCH 033/207] Fixed up markdown so the build status isn't treated as a header anywhere --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a357feea..b0841759 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -Sonic Robo Blast 2 -================== -[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2) [![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2) -================== +# Sonic Robo Blast 2 + +[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2) +[![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2) [Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/). From 86ccecc6c13ab4727ccb540b0b1e05c0675dbcbd Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 4 Sep 2016 21:26:34 +0100 Subject: [PATCH 034/207] Let's be more specific here --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0841759..4ee6ebec 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - libupnp (Linux/OS X only) - libgme (Linux/OS X only) -Warning: 64-bit builds are not netgame compatible. Use at your own risk. +Warning: 64-bit builds are not netgame compatible with 32-bit builds. Use at your own risk. ## Compiling From 0595325f4bf2b3ea7638eae8cecc8ee40c2dda50 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 4 Sep 2016 21:54:11 +0100 Subject: [PATCH 035/207] Make disclaimer H2 instead of H3 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ee6ebec..eb06156b 100644 --- a/README.md +++ b/README.md @@ -18,5 +18,5 @@ Warning: 64-bit builds are not netgame compatible with 32-bit builds. Use at you See [SRB2 Wiki/Source code compiling](http://wiki.srb2.org/wiki/Source_code_compiling) -### Disclaimer +## Disclaimer Sonic Team Junior is in no way affiliated with SEGA or Sonic Team. We do not claim ownership of any of SEGA's intellectual property used in SRB2. From 7be8c0017efbaf0e7abc83db42e261743ebe0cd0 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 19:20:51 -0400 Subject: [PATCH 036/207] appveyor: let see what version of GCC are here --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index e0ee99c6..f9acf0a2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -77,9 +77,9 @@ deploy: active_mode: false on: branch: master - appveyor_repo_tag: true + appveyor_repo_tag: false on_finish: -#- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: -#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: +- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From 038a9f19cb55ac7d0786d9b69c7d2d74c7ebd58f Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 19:49:07 -0400 Subject: [PATCH 037/207] appveyor: let use GCC 4.9.3 from Mingw32 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index f9acf0a2..33c0f3aa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,7 +5,7 @@ environment: CC: ccache CCACHE_CC: i686-w64-mingw32-gcc WINDRES: windres - MINGW_SDK: c:\msys64\mingw32 + MINGW_SDK: c:\MinGW CFLAGS: -Wall -W -Werror NASM_ZIP: nasm-2.12.01 NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip From df6d3de8cabbbe859ee1543b5427256e642a719c Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 19:57:28 -0400 Subject: [PATCH 038/207] appveyor: use mingw32-gcc as compiler --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 33c0f3aa..297ad055 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,7 @@ os: MinGW environment: CC: ccache - CCACHE_CC: i686-w64-mingw32-gcc + CCACHE_CC: mingw32-gcc WINDRES: windres MINGW_SDK: c:\MinGW CFLAGS: -Wall -W -Werror @@ -75,9 +75,9 @@ deploy: folder: appveyor application: active_mode: false - on: - branch: master - appveyor_repo_tag: false +# on: +# branch: master +# appveyor_repo_tag: true on_finish: From ab322179f59a56144ff9fff3da2deaa363a5299e Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 19:59:15 -0400 Subject: [PATCH 039/207] appveyor: compile with GCC 4.9 warning flags --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 297ad055..8954257c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -47,7 +47,7 @@ before_build: - upx -V - ccache -V - ccache -s -- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC53=1 CCACHE=1 +- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC49=1 CCACHE=1 build_script: - cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean From f5ae094e5b7c7e200e3a411b88e14b297a4283a3 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 20:09:45 -0400 Subject: [PATCH 040/207] appveyor: fixup PATH --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 8954257c..246bf6fd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -40,8 +40,8 @@ configuration: - DD before_build: -- set Path=%MINGW_SDK%\bin;%Path% -- i686-w64-mingw32-gcc --version +- set PATH=%MINGW_SDK%\bin;%PATH% +- mingw32-gcc --version - mingw32-make --version - nasm -v - upx -V @@ -81,5 +81,5 @@ deploy: on_finish: -- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: -- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +#- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: +#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From d79804c1191ca022b2d9f140030e426d7bfe6ddd Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 20:14:01 -0400 Subject: [PATCH 041/207] appveyor: call up Mingw GCC directly --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 246bf6fd..573ef74b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,7 @@ os: MinGW environment: CC: ccache - CCACHE_CC: mingw32-gcc + CCACHE_CC: C:\MinGW\bin\mingw32-gcc.exe WINDRES: windres MINGW_SDK: c:\MinGW CFLAGS: -Wall -W -Werror @@ -41,7 +41,7 @@ configuration: before_build: - set PATH=%MINGW_SDK%\bin;%PATH% -- mingw32-gcc --version +- C:\MinGW\bin\mingw32-gcc.exe --version - mingw32-make --version - nasm -v - upx -V From 1afe83250d95c7e2d0774a64e649d72c4e0ce398 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 20:40:00 -0400 Subject: [PATCH 042/207] appveyor: let use CCACHE_PATH --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 573ef74b..61cbff19 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,8 @@ os: MinGW environment: CC: ccache - CCACHE_CC: C:\MinGW\bin\mingw32-gcc.exe + CCACHE_CC: mingw32-gcc.exe + CCACHE_PATH: C:\MinGW\bin WINDRES: windres MINGW_SDK: c:\MinGW CFLAGS: -Wall -W -Werror From ad9956294c5a2ef3b05bd2768c7381f733c99208 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 20:54:15 -0400 Subject: [PATCH 043/207] appveyor: revert MINGW_SDK --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 61cbff19..94d1fdf5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: CCACHE_CC: mingw32-gcc.exe CCACHE_PATH: C:\MinGW\bin WINDRES: windres - MINGW_SDK: c:\MinGW + MINGW_SDK: c:\msys64\mingw32 CFLAGS: -Wall -W -Werror NASM_ZIP: nasm-2.12.01 NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip From e38329e965abcc0827a756465d6842d5a9cab062 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 21:04:16 -0400 Subject: [PATCH 044/207] appveyor: reenable RDP --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 94d1fdf5..22187831 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -83,4 +83,4 @@ deploy: on_finish: #- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: -#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From ae4f68088897792bf001348233fa19afdcee7030 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 21:23:28 -0400 Subject: [PATCH 045/207] appveyor: add both Mingw folders into the PATH --- appveyor.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 22187831..6dcd3201 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,9 +2,7 @@ version: 2.1.16.{branch}-{build} os: MinGW environment: - CC: ccache - CCACHE_CC: mingw32-gcc.exe - CCACHE_PATH: C:\MinGW\bin + CC: mingw32-gcc.exe WINDRES: windres MINGW_SDK: c:\msys64\mingw32 CFLAGS: -Wall -W -Werror @@ -41,8 +39,8 @@ configuration: - DD before_build: -- set PATH=%MINGW_SDK%\bin;%PATH% -- C:\MinGW\bin\mingw32-gcc.exe --version +- set PATH=%MINGW_SDK%\bin;C:\Mingw\bin;%PATH% +- mingw32-gcc.exe --version - mingw32-make --version - nasm -v - upx -V From ad32803370fae55e57a6d5d4b114b203bea45c21 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 6 Sep 2016 21:23:28 -0400 Subject: [PATCH 046/207] appveyor: disable FTP upload and RDP --- appveyor.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6dcd3201..13ee48f7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -62,18 +62,18 @@ after_build: test: off -deploy: - - provider: FTP - protocol: ftps - host: - secure: NsLJEPIBvmwCOj8Tg8RoRQ== - username: - secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= - password: - secure: Hbn6Uy3lT0YZ88yFJ3aW4w== - folder: appveyor - application: - active_mode: false +#deploy: +# - provider: FTP +# protocol: ftps +# host: +# secure: NsLJEPIBvmwCOj8Tg8RoRQ== +# username: +# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= +# password: +# secure: Hbn6Uy3lT0YZ88yFJ3aW4w== +# folder: appveyor +# application: +# active_mode: false # on: # branch: master # appveyor_repo_tag: true @@ -81,4 +81,4 @@ deploy: on_finish: #- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: -- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From 9f87841936a957c4c7552089654cfdd2bd22cc15 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Sep 2016 22:55:11 +0100 Subject: [PATCH 047/207] Fix bottom of FOF with a pusher special not accounting for slopes --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 30b08ebb..92f62af4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7428,7 +7428,7 @@ void T_Pusher(pusher_t *p) } else { - if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) + if (top < thing->z || bottom > (thing->z + (thing->height >> 1))) continue; if (thing->z + thing->height > top) touching = true; From c9aebc6f81837faa09183c10de3f048e4bdb936e Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 9 Sep 2016 17:41:30 -0400 Subject: [PATCH 048/207] libz pkgconfig --- src/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Makefile b/src/Makefile index ce4b569e..b83b201e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -179,6 +179,9 @@ endif ifdef LINUX UNIXCOMMON=1 +ifndef NOGME +HAVE_LIBGME=1 +endif endif ifdef SOLARIS @@ -318,6 +321,13 @@ endif ifdef HAVE_LIBGME OPTS+=-DHAVE_LIBGME +ZLIB_PKGCONFIG?=zlib +ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) +ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) + +LIBS+=$(ZLIB_LDFLAGS) +CFLAGS+=$(ZLIB_CFLAGS) + LIBGME_PKGCONFIG?=libgme LIBGME_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --cflags) LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs) From c977d174166142a47b5aa7a2d32f57a2a5412702 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 09:41:18 -0700 Subject: [PATCH 049/207] Prevent truncation when resampling sounds with non-multiples of 11250. --- src/sdl/mixer_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 4a46813c..88bbadd2 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -220,7 +220,7 @@ static Mix_Chunk *ds2chunk(void *stream) break; default: // convert arbitrary hz to 44100. step = 0; - frac = ((UINT32)freq << FRACBITS) / 44100; + frac = ((UINT32)freq << FRACBITS) / 44100 + 1; //Add 1 to counter truncation. while (i < samples) { o = (INT16)(*s+0x80)<<8; // changed signedness and shift up to 16 bits From 2798bd5c163b239eb7dd2eed40944b067eb3bc94 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 10:40:49 -0700 Subject: [PATCH 050/207] Ensure demo files will save to srb2home, where SRB2 already looks for them. --- src/g_game.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index f891b010..9ad8460d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5579,7 +5579,10 @@ boolean G_CheckDemoStatus(void) WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. #endif - saved = FIL_WriteFile(demoname, demobuffer, demo_p - demobuffer); // finally output the file. + + char fulldemoname [128]; + sprintf(fulldemoname, "%s"PATHSEP"%s", srb2home, demoname); + saved = FIL_WriteFile(fulldemoname, demobuffer, demo_p - demobuffer); // finally output the file. free(demobuffer); demorecording = false; From 4abfe1e8f36f654b467f38b23debfcc8c156cbd0 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 10:57:14 -0700 Subject: [PATCH 051/207] Fix MinGW/AppVeyor build. --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 9ad8460d..08c6be10 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5529,6 +5529,7 @@ void G_StopDemo(void) boolean G_CheckDemoStatus(void) { boolean saved; + char fulldemoname[128]; //Demo name with srb2home path if(ghosts) // ... ... ... ghosts = NULL; // :) @@ -5580,7 +5581,6 @@ boolean G_CheckDemoStatus(void) md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. #endif - char fulldemoname [128]; sprintf(fulldemoname, "%s"PATHSEP"%s", srb2home, demoname); saved = FIL_WriteFile(fulldemoname, demobuffer, demo_p - demobuffer); // finally output the file. free(demobuffer); From 3b503f133640bde612862ec23310be06f9685a50 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 14:59:24 -0700 Subject: [PATCH 052/207] Use function va to avoid having to delcare a new variable. Thanks MonsterIestyn. --- src/g_game.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 08c6be10..84db9013 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5529,7 +5529,6 @@ void G_StopDemo(void) boolean G_CheckDemoStatus(void) { boolean saved; - char fulldemoname[128]; //Demo name with srb2home path if(ghosts) // ... ... ... ghosts = NULL; // :) @@ -5580,9 +5579,7 @@ boolean G_CheckDemoStatus(void) WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. #endif - - sprintf(fulldemoname, "%s"PATHSEP"%s", srb2home, demoname); - saved = FIL_WriteFile(fulldemoname, demobuffer, demo_p - demobuffer); // finally output the file. + saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. free(demobuffer); demorecording = false; From b8345aaf27ab32dd7cee8960143fc63bd666f5c2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 00:13:34 +0100 Subject: [PATCH 053/207] Solid objects are now no longer selectively intangible on slopes. HOWEVER, since these changes to PIT_CheckThing do raise questions about whether there may be unintended side effects here. As a result, I may remake this for internal only if necessary. --- src/p_map.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index c4616db4..13496bef 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -985,7 +985,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z - FixedMul(FRACUNIT, thing->scale); + topz = thing->z - thing->scale; // block only when jumping not high enough, // (dont climb max. 24units while already in air) @@ -996,7 +996,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SPRING) ; - else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) + else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) { tmceilingz = topz; #ifdef ESLOPE @@ -1022,7 +1022,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale); + topz = thing->z + thing->height + thing->scale; // block only when jumping not high enough, // (dont climb max. 24units while already in air) @@ -1032,7 +1032,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SPRING) ; - else if (topz > tmfloorz && tmthing->z >= thing->z) + else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) { tmfloorz = topz; #ifdef ESLOPE From fa16abf7ae8cf0468bb3237047687eefca997e6e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 11:15:08 +0100 Subject: [PATCH 054/207] Fixed the thing where if you thok into a solid object you spin really fast in the air without moving OR losing your momentum. --- src/p_map.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 13496bef..a3f34aa8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -989,12 +989,18 @@ static boolean PIT_CheckThing(mobj_t *thing) // block only when jumping not high enough, // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high + // since return false doesn't handle momentum properly, + // we lie to P_TryMove() so it's always too high if (tmthing->player && tmthing->z + tmthing->height > topz && tmthing->z + tmthing->height < tmthing->ceilingz) - return false; // block while in air - - if (thing->flags & MF_SPRING) + { + tmceilingz = INT32_MIN; // block while in air +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + tmfloorthing = thing; // needed for side collision + } + else if (thing->flags & MF_SPRING) ; else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) { @@ -1026,11 +1032,18 @@ static boolean PIT_CheckThing(mobj_t *thing) // block only when jumping not high enough, // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high - if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) - return false; // block while in air - - if (thing->flags & MF_SPRING) + // since return false doesn't handle momentum properly, + // we lie to P_TryMove() so it's always too high + if (tmthing->player && tmthing->z < topz + && tmthing->z > tmthing->floorz) + { + tmfloorz = INT32_MAX; // block while in air +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + tmfloorthing = thing; // needed for side collision + } + else if (thing->flags & MF_SPRING) ; else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) { From 0568712a5e3bee3335e5e0f9256c1ad07f78d25a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 12:01:13 +0100 Subject: [PATCH 055/207] Prevent overflow when attempting to calculate the space between floor and ceiling. (I didn't notice any bugs as a result of the previous behvaiour, but you never know.) --- src/p_map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index a3f34aa8..8b8c6c07 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -994,7 +994,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->player && tmthing->z + tmthing->height > topz && tmthing->z + tmthing->height < tmthing->ceilingz) { - tmceilingz = INT32_MIN; // block while in air + tmfloorz = tmceilingz = INT32_MIN; // block while in air #ifdef ESLOPE tmceilingslope = NULL; #endif @@ -1037,7 +1037,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) { - tmfloorz = INT32_MAX; // block while in air + tmfloorz = tmceilingz = INT32_MAX; // block while in air #ifdef ESLOPE tmfloorslope = NULL; #endif From 394ed30f4436dd3d9a2a8bd118a60175f350527b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 21:08:36 +0100 Subject: [PATCH 056/207] Fixed the problem with the reverseplatform_clipping branch that caused springs to fall through platforms, as tested by Wolfs in TD. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5e5961d4..82326f04 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2017,13 +2017,13 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); if (topheight > mo->floorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM) - && ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) + && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) { mo->floorz = topheight; } if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) - && ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below + && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below { mo->ceilingz = bottomheight; } From 8ad72232bea1b1b093fe9a36ca189e1c90db5127 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 22 Sep 2016 21:15:12 +0100 Subject: [PATCH 057/207] Helpful explanatory comments to assauge MI's fears. --- src/p_map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 8b8c6c07..6a555953 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -985,7 +985,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z - thing->scale; + topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways // block only when jumping not high enough, // (dont climb max. 24units while already in air) @@ -1028,7 +1028,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z + thing->height + thing->scale; + topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways // block only when jumping not high enough, // (dont climb max. 24units while already in air) From 5f4f6fdac89e01a330bf821a9ec95dd3c74cc480 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Sep 2016 18:35:13 +0100 Subject: [PATCH 058/207] Public remake of a merge request I shouldn't have put in Internal in the first place. --- src/m_misc.c | 2 ++ src/p_spec.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 457214e3..cfe73d88 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1675,6 +1675,7 @@ char *M_GetToken(const char *inputString) || stringToUse[startPos] == '\r' || stringToUse[startPos] == '\n' || stringToUse[startPos] == '\0' + || stringToUse[startPos] == '"' // we're treating this as whitespace because SLADE likes adding it for no good reason || inComment != 0) && startPos < stringLength) { @@ -1742,6 +1743,7 @@ char *M_GetToken(const char *inputString) && stringToUse[endPos] != ',' && stringToUse[endPos] != '{' && stringToUse[endPos] != '}' + && stringToUse[endPos] != '"' // see above && inComment == 0) && endPos < stringLength) { diff --git a/src/p_spec.c b/src/p_spec.c index 30b08ebb..5dac8d34 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -509,7 +509,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing TEXTURES lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname); } endPos = NULL; #ifndef AVOID_ERRNO @@ -523,7 +523,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) #endif || animSpeed < 0) // Number is not positive { - I_Error("Error parsing TEXTURES lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken); } animdefs[*i].speed = animSpeed; Z_Free(animdefsToken); From 8881a413f3c3a652675e4f451ebb849f17a8ac10 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 27 Sep 2016 17:17:23 +0100 Subject: [PATCH 059/207] Fixed that really annoying bug where you disappear when spindashing on top of a FOF whilst wearing a multi-layer shield. (the problem was that MT_OVERLAY's default radius and height were never getting changed from 1*FRACUNIT, and that meant that when you spindashed, the game considered it completely below the surface of the flat you were standing on. Since you're not usually clipped on flats that don't belong to FOFs, we didn't notice this issue sooner.) --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5e5961d4..b35b7286 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5930,6 +5930,8 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) P_UnsetThingPosition(thing); thing->x = thing->target->x; thing->y = thing->target->y; + thing->radius = thing->target->radius; + thing->height = thing->target->height; if (thing->eflags & MFE_VERTICALFLIP) thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale); else @@ -6048,6 +6050,8 @@ void P_RunOverlays(void) P_UnsetThingPosition(mo); mo->x = destx; mo->y = desty; + mo->radius = mo->target->radius; + mo->height = mo->target->height; if (mo->eflags & MFE_VERTICALFLIP) mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs; else From 1c23a84aa531b02a1f62b6ea65f1896e249d904a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 9 Oct 2016 20:55:04 +0100 Subject: [PATCH 060/207] set floorcenterz/ceilingcenterz for all of R_Subsector to use, not just FOF planes --- src/r_bsp.c | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 69aa7be2..11159db3 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -859,6 +859,7 @@ static void R_Subsector(size_t num) static sector_t tempsec; // Deep water hack extracolormap_t *floorcolormap; extracolormap_t *ceilingcolormap; + fixed_t floorcenterz, ceilingcenterz; #ifdef RANGECHECK if (num >= numsubsectors) @@ -879,6 +880,18 @@ static void R_Subsector(size_t num) floorcolormap = ceilingcolormap = frontsector->extra_colormap; + floorcenterz = +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->floorheight; + + ceilingcenterz = +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->ceilingheight; + // Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps. if (frontsector->ffloors) { @@ -891,19 +904,11 @@ static void R_Subsector(size_t num) sub->sector->moved = frontsector->moved = false; } - light = R_GetPlaneLight(frontsector, -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->floorheight, false); + light = R_GetPlaneLight(frontsector, floorcenterz, false); if (frontsector->floorlightsec == -1) floorlightlevel = *frontsector->lightlist[light].lightlevel; floorcolormap = frontsector->lightlist[light].extra_colormap; - light = R_GetPlaneLight(frontsector, -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->ceilingheight, false); + light = R_GetPlaneLight(frontsector, ceilingcenterz, false); if (frontsector->ceilinglightsec == -1) ceilinglightlevel = *frontsector->lightlist[light].lightlevel; ceilingcolormap = frontsector->lightlist[light].extra_colormap; @@ -956,7 +961,7 @@ static void R_Subsector(size_t num) if (frontsector->ffloors) { ffloor_t *rover; - fixed_t heightcheck, planecenterz, floorcenterz, ceilingcenterz; + fixed_t heightcheck, planecenterz; for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) { @@ -975,18 +980,6 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - floorcenterz = -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->floorheight; - - ceilingcenterz = -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif - frontsector->ceilingheight; - heightcheck = #ifdef ESLOPE *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : @@ -1093,8 +1086,8 @@ static void R_Subsector(size_t num) polysec = po->lines[0]->backsector; ffloor[numffloors].plane = NULL; - if (polysec->floorheight <= frontsector->ceilingheight - && polysec->floorheight >= frontsector->floorheight + if (polysec->floorheight <= ceilingcenterz + && polysec->floorheight >= floorcenterz && (viewz < polysec->floorheight)) { fixed_t xoff, yoff; @@ -1139,8 +1132,8 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; - if (polysec->ceilingheight >= frontsector->floorheight - && polysec->ceilingheight <= frontsector->ceilingheight + if (polysec->ceilingheight >= floorcenterz + && polysec->ceilingheight <= ceilingcenterz && (viewz > polysec->ceilingheight)) { fixed_t xoff, yoff; From b66925e467ca6cebbaa78fd21eb3e96898d2c8d2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 9 Oct 2016 21:48:25 +0100 Subject: [PATCH 061/207] R_FindPlane now has a polyobj argument, R_DrawPlanes now skips polyobj planes, like it does with FOF planes --- src/r_bsp.c | 20 ++++++++++++++++++-- src/r_plane.c | 13 +++++++++++-- src/r_plane.h | 3 +++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 11159db3..2562cff6 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -925,6 +925,9 @@ static void R_Subsector(size_t num) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , frontsector->f_slope #endif @@ -944,6 +947,9 @@ static void R_Subsector(size_t num) ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilingcolormap, NULL +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , frontsector->c_slope #endif @@ -1002,6 +1008,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , *rover->b_slope #endif @@ -1045,6 +1054,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef POLYOBJECTS_PLANES + , NULL +#endif #ifdef ESLOPE , *rover->t_slope #endif @@ -1111,11 +1123,13 @@ static void R_Subsector(size_t num) polysec->floorpic_angle-po->angle, NULL, NULL +#ifdef POLYOBJECTS_PLANES + , po +#endif #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif ); - //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; @@ -1155,11 +1169,13 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, NULL, NULL +#ifdef POLYOBJECTS_PLANES + , po +#endif #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif ); - //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; diff --git a/src/r_plane.c b/src/r_plane.c index 19007d88..b7b9eaff 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -431,6 +431,9 @@ static visplane_t *new_visplane(unsigned hash) visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *pfloor +#ifdef POLYOBJECTS_PLANES + , polyobj_t *polyobj +#endif #ifdef ESLOPE , pslope_t *slope #endif @@ -470,6 +473,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, #ifdef POLYOBJECTS_PLANES if (check->polyobj && pfloor) continue; + if (polyobj != check->polyobj) + continue; #endif if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel @@ -504,7 +509,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, check->viewangle = viewangle; check->plangle = plangle; #ifdef POLYOBJECTS_PLANES - check->polyobj = NULL; + check->polyobj = polyobj; #endif #ifdef ESLOPE check->slope = slope; @@ -719,7 +724,11 @@ void R_DrawPlanes(void) continue; } - if (pl->ffloor != NULL) + if (pl->ffloor != NULL +#ifdef POLYOBJECTS_PLANES + || pl->polyobj != NULL +#endif + ) continue; R_DrawSinglePlane(pl); diff --git a/src/r_plane.h b/src/r_plane.h index ec194071..16c8c12a 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -97,6 +97,9 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *ffloor +#ifdef POLYOBJECTS_PLANES + , polyobj_t *polyobj +#endif #ifdef ESLOPE , pslope_t *slope #endif From ff0b1d1dface10ab11357eee5a0a1fe66ad23403 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 11 Oct 2016 22:35:46 +0100 Subject: [PATCH 062/207] Split polyobj plane drawnode-creating code from ds->maskedtexturecol code, and add plane bounds checking --- src/r_things.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 22551a02..ed1ddeab 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1699,21 +1699,25 @@ static void R_CreateDrawNodes(void) entry->ffloor = ds->thicksides[i]; } } +#ifdef POLYOBJECTS_PLANES + // Check for a polyobject plane, but only if this is a front line + if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { + plane = ds->curline->polyseg->visplane; + R_PlaneBounds(plane); + + if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low) + ; + else { + // Put it in! + entry = R_CreateDrawNode(&nodehead); + entry->plane = plane; + entry->seg = ds; + } + ds->curline->polyseg->visplane = NULL; + } +#endif if (ds->maskedtexturecol) { -#ifdef POLYOBJECTS_PLANES - // Check for a polyobject plane, but only if this is a front line - if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { - // Put it in! - - entry = R_CreateDrawNode(&nodehead); - entry->plane = ds->curline->polyseg->visplane; - entry->seg = ds; - ds->curline->polyseg->visplane->polyobj = ds->curline->polyseg; - ds->curline->polyseg->visplane = NULL; - } -#endif - entry = R_CreateDrawNode(&nodehead); entry->seg = ds; } From e1baf02b7a3f2dd27ccf8bcf6089c5d765dfe756 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 18 Oct 2016 22:07:20 +0100 Subject: [PATCH 063/207] Lua now errors if negative scales are used with v.drawScaled --- src/lua_hudlib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 7aadd9c0..60cbbe50 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -369,6 +369,8 @@ static int libd_drawScaled(lua_State *L) x = luaL_checkinteger(L, 1); y = luaL_checkinteger(L, 2); scale = luaL_checkinteger(L, 3); + if (scale < 0) + return luaL_error(L, "negative scale"); patch = *((patch_t **)luaL_checkudata(L, 4, META_PATCH)); flags = luaL_optinteger(L, 5, 0); if (!lua_isnoneornil(L, 6)) From aa3e52f05e5b044e4f9a6f710027fae020b625c7 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 19 Oct 2016 03:17:36 -0400 Subject: [PATCH 064/207] Fix ANIMDEFS parsing to allow overwrite. ANIMATED and ANIMDEFS are now processed in reverse order, and duplicate definitions in ANIMDEFS are dropped. --- src/p_spec.c | 111 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 45 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index cb928eee..b04c5588 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -221,8 +221,8 @@ static animdef_t harddefs[] = static animdef_t *animdefs = NULL; // A prototype; here instead of p_spec.h, so they're "private" -void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i); -void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i); +void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum); +void P_ParseAnimationDefintion(SINT8 istexture); /** Sets up texture and flat animations. * @@ -232,24 +232,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i); * Issues an error if any animation cycles are invalid. * * \sa P_FindAnimatedFlat, P_SetupLevelFlatAnims - * \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs) + * \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs), JTE (had to rewrite it to handle multiple WADs _correctly_) */ void P_InitPicAnims(void) { // Init animation - INT32 i; // Position in the animdefs array INT32 w; // WAD - UINT8 *wadAnimdefs; // not to be confused with animdefs, the combined total of every ANIMATED lump in every WAD, or ANIMDEFS, the ZDoom lump I intend to implement later + UINT8 *animatedLump; UINT8 *currentPos; + size_t i; + + I_Assert(animdefs == NULL); if (W_CheckNumForName("ANIMATED") != LUMPERROR || W_CheckNumForName("ANIMDEFS") != LUMPERROR) { - if (animdefs) - { - Z_Free(animdefs); - animdefs = NULL; - } - for (w = 0, i = 0, maxanims = 0; w < numwadfiles; w++) + for (w = numwadfiles-1, maxanims = 0; w >= 0; w--) { UINT16 animatedLumpNum; UINT16 animdefsLumpNum; @@ -258,20 +255,20 @@ void P_InitPicAnims(void) animatedLumpNum = W_CheckNumForNamePwad("ANIMATED", w, 0); if (animatedLumpNum != INT16_MAX) { - wadAnimdefs = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); + animatedLump = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); // Get the number of animations in the file - for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); + i = maxanims; + for (currentPos = animatedLump; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); // Resize animdefs (or if it hasn't been created, create it) animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); // Sanity check it - if (!animdefs) { + if (!animdefs) I_Error("Not enough free memory for ANIMATED data"); - } // Populate the new array - for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; i++, currentPos+=23) + for (currentPos = animatedLump; *currentPos != UINT8_MAX; i++, currentPos+=23) { M_Memcpy(&(animdefs[i].istexture), currentPos, 1); // istexture, 1 byte M_Memcpy(animdefs[i].endname, (currentPos + 1), 9); // endname, 9 bytes @@ -279,15 +276,13 @@ void P_InitPicAnims(void) M_Memcpy(&(animdefs[i].speed), (currentPos + 19), 4); // speed, 4 bytes } - Z_Free(wadAnimdefs); + Z_Free(animatedLump); } // Now find ANIMDEFS animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); if (animdefsLumpNum != INT16_MAX) - { - P_ParseANIMDEFSLump(w, animdefsLumpNum, &i); - } + P_ParseANIMDEFSLump(w, animdefsLumpNum); } // Define the last one animdefs[maxanims].istexture = -1; @@ -347,16 +342,20 @@ void P_InitPicAnims(void) lastanim->istexture = -1; R_ClearTextureNumCache(false); + // Clear animdefs now that we're done with it. + // We'll only be using anims from now on. if (animdefs != harddefs) - Z_ChangeTag(animdefs, PU_CACHE); + Z_Free(animdefs); + animdefs = NULL; } -void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) +void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum) { char *animdefsLump; size_t animdefsLumpLength; char *animdefsText; char *animdefsToken; + char *p; // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll // need to make a space of memory where I can ensure that it will terminate @@ -376,18 +375,19 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) Z_Free(animdefsLump); // Now, let's start parsing this thing - animdefsToken = M_GetToken(animdefsText); + p = animdefsText; + animdefsToken = M_GetToken(p); while (animdefsToken != NULL) { if (stricmp(animdefsToken, "TEXTURE") == 0) { Z_Free(animdefsToken); - P_ParseAnimationDefintion(1, i); + P_ParseAnimationDefintion(1); } else if (stricmp(animdefsToken, "FLAT") == 0) { Z_Free(animdefsToken); - P_ParseAnimationDefintion(0, i); + P_ParseAnimationDefintion(0); } else if (stricmp(animdefsToken, "OSCILLATE") == 0) { @@ -398,23 +398,22 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) { I_Error("Error parsing ANIMDEFS lump: Expected \"TEXTURE\" or \"FLAT\", got \"%s\"",animdefsToken); } - animdefsToken = M_GetToken(NULL); + // parse next line + while (*p != '\0' && *p != '\n') ++p; + if (*p == '\n') ++p; + animdefsToken = M_GetToken(p); } Z_Free(animdefsToken); Z_Free((void *)animdefsText); } -void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) +void P_ParseAnimationDefintion(SINT8 istexture) { char *animdefsToken; size_t animdefsTokenLength; char *endPos; INT32 animSpeed; - - // Increase the size to make room for the new animation definition - maxanims++; - animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); - animdefs[*i].istexture = istexture; + size_t i; // Startname animdefsToken = M_GetToken(NULL); @@ -448,14 +447,39 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) { I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken); } - strncpy(animdefs[*i].startname, animdefsToken, 9); + + // Search for existing animdef + for (i = 0; i < maxanims; i++) + if (stricmp(animdefsToken, animdefs[i].startname) == 0) + { + //CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken); + + // If we weren't parsing in reverse order, we would `break` here and parse the new data into the existing slot we found. + // Instead, we're just going to skip parsing the rest of this line entirely. + Z_Free(animdefsToken); + return; + } + + // Not found + if (i == maxanims) + { + // Increase the size to make room for the new animation definition + maxanims++; + animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); + strncpy(animdefs[i].startname, animdefsToken, 9); + } + + // animdefs[i].startname is now set to animdefsToken either way. Z_Free(animdefsToken); + // set texture type + animdefs[i].istexture = istexture; + // "RANGE" animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[i].startname); } if (stricmp(animdefsToken, "ALLOWDECALS") == 0) { @@ -470,7 +494,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) } if (stricmp(animdefsToken, "RANGE") != 0) { - I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[i].startname, animdefsToken); } Z_Free(animdefsToken); @@ -478,21 +502,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[i].startname); } animdefsTokenLength = strlen(animdefsToken); if (animdefsTokenLength>8) { I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken); } - strncpy(animdefs[*i].endname, animdefsToken, 9); + strncpy(animdefs[i].endname, animdefsToken, 9); Z_Free(animdefsToken); // "TICS" animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[i].startname); } if (stricmp(animdefsToken, "RAND") == 0) { @@ -501,7 +525,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) } if (stricmp(animdefsToken, "TICS") != 0) { - I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[i].startname, animdefsToken); } Z_Free(animdefsToken); @@ -509,7 +533,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[i].startname); } endPos = NULL; #ifndef AVOID_ERRNO @@ -523,13 +547,10 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) #endif || animSpeed < 0) // Number is not positive { - I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[i].startname, animdefsToken); } - animdefs[*i].speed = animSpeed; + animdefs[i].speed = animSpeed; Z_Free(animdefsToken); - - // Increment i before we go, so this doesn't cause issues later - (*i)++; } From cdb841ef544f479cc4f9548e067f98d548987456 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 19 Oct 2016 03:22:11 -0400 Subject: [PATCH 065/207] Only P_InitPicAnims when wads are loaded. Not in P_SetupLevel. That's just dumb. --- src/p_setup.c | 7 +++---- src/r_data.c | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e56c44c7..f1d3a68c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2587,10 +2587,6 @@ boolean P_SetupLevel(boolean skipprecip) R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); CON_ReSetupBackColormap(mapheaderinfo[gamemap-1]->palette); - // now part of level loading since in future each level may have - // its own anim texture sequences, switches etc. - P_InitPicAnims(); - // SRB2 determines the sky texture to be used depending on the map header. P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true); @@ -3001,6 +2997,9 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) else R_FlushTextureCache(); // just reload it from file + // Reload ANIMATED / ANIMDEFS + P_InitPicAnims(); + // Flush and reload HUD graphics ST_UnloadGraphics(); HU_LoadGraphics(); diff --git a/src/r_data.c b/src/r_data.c index cb5cf359..87b6b119 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1499,6 +1499,9 @@ void R_InitData(void) CONS_Printf("R_LoadTextures()...\n"); R_LoadTextures(); + CONS_Printf("P_InitPicAnims()...\n"); + P_InitPicAnims(); + CONS_Printf("R_InitSprites()...\n"); R_InitSpriteLumps(); R_InitSprites(); From 8025ef2f79ec32e71053e7d9eaeb4e7f8c89972a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Oct 2016 16:08:06 +0100 Subject: [PATCH 066/207] At MI's suggestion (shields don't NEED to be tweaked, just overlays) --- src/p_mobj.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b35b7286..b3842da1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5930,8 +5930,6 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) P_UnsetThingPosition(thing); thing->x = thing->target->x; thing->y = thing->target->y; - thing->radius = thing->target->radius; - thing->height = thing->target->height; if (thing->eflags & MFE_VERTICALFLIP) thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale); else From ff443251b18e666c8618e61a6fa052ba5ac0abed Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 27 Oct 2016 23:14:22 +0100 Subject: [PATCH 067/207] P_IsPointInSubsector now works in both Software and GL, which means it can be used as the main driver behind support for Knuckles climbing on one-sided walls. Also, the "teleport" devmode command can now gracefully handle coordinates specified outside maps with no/few thok barriers, which previously prevented teleport via the thok barrier bleed's sector floor and ceiling being equal. --- src/m_cheat.c | 2 +- src/p_user.c | 7 +++---- src/r_main.c | 5 +++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 89334596..3bbaadc5 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -452,7 +452,7 @@ void Command_RTeleport_f(void) else inty = 0; - ss = R_PointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT); + ss = R_IsPointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT); if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height) { CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n")); diff --git a/src/p_user.c b/src/p_user.c index 3867137a..f8dc942c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2280,14 +2280,13 @@ static void P_DoClimbing(player_t *player) fixed_t platy; subsector_t *glidesector; boolean climb = true; - boolean onesided = ((player->lastsidehit != -1 && player->lastlinehit != -1) && !(lines[player->lastlinehit].backsector)); platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy); - if (onesided || glidesector->sector != player->mo->subsector->sector) + if (!glidesector || glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; boolean thrust = false; @@ -2295,7 +2294,7 @@ static void P_DoClimbing(player_t *player) boolean skyclimber = false; fixed_t floorheight, ceilingheight; // ESLOPE - if (onesided) + if (!glidesector) floorclimb = true; else { diff --git a/src/r_main.c b/src/r_main.c index 498f4dab..1b4322b4 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -771,7 +771,7 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y) } // -// R_IsPointInSubsector, same as above but returns 0 if not in subsector - this does not work in opengl because of polyvertex_t +// R_IsPointInSubsector, same as above but returns 0 if not in subsector // subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) { @@ -795,7 +795,8 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) ret = &subsectors[nodenum & ~NF_SUBSECTOR]; for (i = 0; i < ret->numlines; i++) - if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) + //if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) -- breaks in ogl because polyvertex_t cast over vertex pointers + if (P_PointOnLineSide(x, y, segs[ret->firstline + i].linedef) != segs[ret->firstline + i].side) return 0; return ret; From ab6fd676b5d42b1446ba4a6961abce6093a8422a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 27 Oct 2016 23:41:24 +0100 Subject: [PATCH 068/207] YUP, I just fixed OGL Precipitation with this branch too. What the fuck? Squashing ancient bugs, woo. --- src/hardware/hw_main.c | 48 ++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5251e0b3..a107ecd3 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -45,7 +45,7 @@ #include "hw_md2.h" #define R_FAKEFLOORS -//#define HWPRECIP +#define HWPRECIP #define SORTING //#define POLYSKY @@ -4401,7 +4401,6 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) FOutVector *wv; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; - sector_t *sector; if (!spr->mobj) return; @@ -4455,19 +4454,38 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) //Hurdler: 25/04/2000: now support colormap in hardware mode HWR_GetMappedPatch(gpatch, spr->colormap); - sector = spr->mobj->subsector->sector; - - if (sector->ffloors) + // colormap test { - ffloor_t *caster = sector->lightlist[R_GetPlaneLight(sector, spr->mobj->z, false)].caster; - sector = caster ? §ors[caster->secnum] : sector; - } + sector_t *sector = spr->mobj->subsector->sector; + UINT8 lightlevel = 255; + extracolormap_t *colormap = sector->extra_colormap; - // sprite lighting by modulating the RGB components - if (sector->extra_colormap) - Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,sector->extra_colormap->rgba,sector->extra_colormap->fadergba, false, false); + if (sector->numlights) + { + INT32 light; + + light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before + + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *sector->lightlist[light].lightlevel; + + if (sector->lightlist[light].extra_colormap) + colormap = sector->lightlist[light].extra_colormap; + } else - Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,NORMALFOG,FADEFOG, false, false); + { + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = sector->lightlevel; + + if (sector->extra_colormap) + colormap = sector->extra_colormap; + } + + if (colormap) + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + } if (spr->mobj->flags2 & MF2_SHADOW) { @@ -5289,6 +5307,11 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // vis = HWR_NewVisSprite(); vis->x1 = x1; +#if 0 + vis->x2 = x2; +#else + (void)x2; +#endif vis->x2 = tx; vis->tz = tz; vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST @@ -5301,7 +5324,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // set top/bottom coords vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset) - gr_viewz; - vis->sectorlight = 0xff; vis->precip = true; } #endif From 31d569a15b002d2555ac16940bae118e3096f0af Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Oct 2016 18:12:41 +0100 Subject: [PATCH 069/207] No more changing skins when you're in singleplayer and manage to enter a hole in the gamestate defenses! --- src/d_netcmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4f73a256..7fd10d08 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4062,8 +4062,7 @@ static void Skin_OnChange(void) if (!Playing()) return; // do whatever you want - if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player. - && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING)) + if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. { CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); return; From 2d72b2fac6c2d227b11ea31826d6afd4d30337ac Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 2 Nov 2016 19:31:06 +0100 Subject: [PATCH 070/207] You can now move the cursor in command prompt and chat, using left/right, ctrl+left/right, home/end, and select text with shift --- src/console.c | 213 ++++++++++++++++++++++-- src/hu_stuff.c | 437 +++++++++++++++++++++++++++++++++---------------- src/hu_stuff.h | 1 - 3 files changed, 498 insertions(+), 153 deletions(-) diff --git a/src/console.c b/src/console.c index 025bc1c1..44819fb4 100644 --- a/src/console.c +++ b/src/console.c @@ -91,11 +91,13 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines static INT32 inputline; // current input line number static INT32 inputhist; // line number of history input line to restore static size_t input_cx; // position in current input line +static INT32 input_selection; // selection border in current input line, -1 if no selection // protos. static void CON_InputInit(void); static void CON_RecalcSize(void); +static void CON_DeleteSelectedText(void); static void CONS_hudlines_Change(void); static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth); //static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth); @@ -394,6 +396,7 @@ static void CON_InputInit(void) inputlines[i][0] = CON_PROMPTCHAR; inputline = 0; input_cx = 1; + input_selection = -1; } //====================================================================== @@ -618,6 +621,25 @@ void CON_Ticker(void) } } +// Deletes selected text, assuming there is, and resets selection. +// Also sets the cursor to the correct position. +// +static void CON_DeleteSelectedText(void) +{ + UINT32 i, j; + char *line = inputlines[inputline]; + size_t selstart = min(input_cx, input_selection); + size_t selend = max(input_cx, input_selection); + + for (i = selstart, j = selend; line[j]; ++i, ++j) + line[i] = line[j]; + while (line[i]) + line[i++] = 0; + + input_cx = selstart; + input_selection = -1; +} + // Handles console key input // boolean CON_Responder(event_t *ev) @@ -704,6 +726,9 @@ boolean CON_Responder(event_t *ev) // command completion forward (tab) and backward (shift-tab) if (key == KEY_TAB) { + input_cx = strlen(inputlines[inputline]); // make sure the cursor is at the end of the string, in case we were inserting + input_selection = -1; // make sure there is no text selected, it would look odd + // show all cvars/commands that match what we have inputted if (ctrldown) { @@ -839,21 +864,51 @@ boolean CON_Responder(event_t *ev) return true; } - if (key == KEY_HOME) // oldest text in buffer + if (key == KEY_HOME) { - con_scrollup = (con_totallines-((con_curlines-16)>>3)); + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + if (ctrldown) + con_scrollup = (con_totallines-((con_curlines-16)>>3)); // oldest text in buffer + else + input_cx = 1; + + if (input_cx == input_selection) + input_selection = -1; + return true; } - else if (key == KEY_END) // most recent text in buffer + else if (key == KEY_END) { - con_scrollup = 0; + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + if (ctrldown) + con_scrollup = 0; // most recent text in buffer + else + input_cx = strlen(inputlines[inputline]); + + if (input_cx == input_selection) + input_selection = -1; + return true; } // command enter if (key == KEY_ENTER) { - if (input_cx < 2) + if (strlen(inputlines[inputline]) < 2) return true; // push the command @@ -868,18 +923,107 @@ boolean CON_Responder(event_t *ev) memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); inputlines[inputline][0] = CON_PROMPTCHAR; input_cx = 1; + input_selection = -1; return true; } - // backspace command prompt + // backspace command prompt or delete selected text if (key == KEY_BACKSPACE) { - if (input_cx > 1) + if (input_selection == -1) { - input_cx--; - inputlines[inputline][input_cx] = 0; + if (input_cx > 1) + { + UINT32 i, j; + char *line = inputlines[inputline]; + + for (i = input_cx - 1, j = input_cx; line[j]; ++i, ++j) + line[i] = line[j]; + line[i] = 0; + input_cx--; + } } + else + CON_DeleteSelectedText(); + return true; + } + + // delete character under cursor or selected text + if (key == KEY_DEL) + { + if (input_selection == -1) + { + UINT32 i, j; + char *line = inputlines[inputline]; + + for (i = input_cx, j = input_cx + 1; line[j]; ++i, ++j) + line[i] = line[j]; + line[i] = 0; + } + else + CON_DeleteSelectedText(); + + return true; + } + + if (key == KEY_LEFTARROW) + { + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + // move cursor to previous word + if (ctrldown) + { + char *line = inputlines[inputline]; + + while (input_cx > 1 && line[input_cx - 1] == ' ') + input_cx--; + while (input_cx > 1 && line[input_cx - 1] != ' ') + input_cx--; + } + // move cursor left + else if (input_cx > 1) + input_cx--; + + if (input_cx == input_selection) + input_selection = -1; + + return true; + } + + if (key == KEY_RIGHTARROW) + { + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + // move cursor to next word + if (ctrldown) + { + char *line = inputlines[inputline]; + + while (line[input_cx] && line[input_cx] != ' ') + input_cx++; + while (line[input_cx] && line[input_cx] == ' ') + input_cx++; + } + // move cursor right + else if (inputlines[inputline][input_cx]) + input_cx++; + + if (input_cx == input_selection) + input_selection = -1; + return true; } @@ -950,13 +1094,21 @@ boolean CON_Responder(event_t *ev) return false; // add key to cmd line here - if (input_cx < CON_MAXPROMPTCHARS) + if (strlen(inputlines[inputline]) < CON_MAXPROMPTCHARS - 1) { + INT32 i, j; + char *line = inputlines[inputline]; + if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers key = key + 'a' - 'A'; - inputlines[inputline][input_cx] = (char)key; - inputlines[inputline][input_cx + 1] = 0; + if (input_selection != -1) + CON_DeleteSelectedText(); + + for (i = strlen(line), j = i + 1; j > (INT32)input_cx; --i, --j) + line[j] = line[i]; + + line[input_cx] = (char)key; input_cx++; } @@ -1246,6 +1398,7 @@ static void CON_DrawInput(void) size_t c; INT32 x, y; INT32 charwidth = (INT32)con_scalefactor << 3; + INT32 f = cv_constextsize.value | V_NOSCALESTART; // input line scrolls left if it gets too long p = inputlines[inputline]; @@ -1254,14 +1407,44 @@ static void CON_DrawInput(void) y = con_curlines - 12 * con_scalefactor; - for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + if (input_selection == -1) + { + for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + } + else + { + size_t selstart = min(input_cx, input_selection); + size_t selend = max(input_cx, input_selection); + + for (c = 0, x = charwidth; c < selstart && c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + + f |= V_YELLOWMAP; + for (; c < selend && c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + f &= ~V_YELLOWMAP; + + for (; c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + } + //for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) + //V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); // draw the blinking cursor // x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); if (con_tick < 4) - V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + { + if (inputlines[inputline][input_cx]) + //V_DrawCharacter(x - 2 * con_scalefactor, y, '|' | f, !cv_allcaps.value); + V_DrawCharacter(x, y + 2 * con_scalefactor, '_' | f, !cv_allcaps.value); + else + V_DrawCharacter(x, y, '_' | f, !cv_allcaps.value); + } + /*x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); + if (con_tick < 4) + V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);*/ } // draw the last lines of console text to the top of the screen diff --git a/src/hu_stuff.c b/src/hu_stuff.c index ec747305..9f1cea13 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -73,6 +73,9 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; +static size_t chat_pos; // position of the cursor in the chat +static INT32 chat_selection; // selection border in current input line, -1 if no selection +static boolean teamtalk = false; static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -106,6 +109,7 @@ static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics static void HU_DrawRankings(void); static void HU_DrawCoopOverlay(void); static void HU_DrawNetplayCoopOverlay(void); +static void HU_DeleteSelectedText(void); //====================================================================== // KEYBOARD LAYOUTS FOR ENTERING TEXT @@ -621,36 +625,183 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } #endif +// Deletes selected text, assuming there is, and resets selection. +// Also sets the cursor to the correct position. +// +static void HU_DeleteSelectedText(void) +{ + UINT32 i, j; + size_t selstart = min(chat_pos, chat_selection); + size_t selend = max(chat_pos, chat_selection); + + for (i = selstart, j = selend; w_chat[j]; ++i, ++j) + w_chat[i] = w_chat[j]; + while (w_chat[i]) + w_chat[i++] = 0; + + chat_pos = selstart; + chat_selection = -1; +} + // Handles key input and string input // -static inline boolean HU_keyInChatString(char *s, char ch) +static inline void HU_keyInChatString(char *s, UINT32 key, boolean shiftdown, boolean ctrldown) { - size_t l; - - if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART]) - || ch == ' ') // Allow spaces, of course + switch (key) { - l = strlen(s); - if (l < HU_MAXMSGLEN - 1) + case KEY_ESCAPE: + chat_on = false; + break; + case KEY_ENTER: + { + // send automatically the message (no more chat char) + char buf[2+256]; + size_t ci = 2; + char *cp = w_chat; + + while (*cp) { - s[l++] = ch; - s[l]=0; - return true; + if (*cp >= ' ' && !(*cp & 0x80)) + buf[ci++] = *cp; + cp++; } - return false; - } - else if (ch == KEY_BACKSPACE) - { - l = strlen(s); - if (l) - s[--l] = 0; - else - return false; - } - else if (ch != KEY_ENTER) - return false; // did not eat key + buf[ci] = 0; - return true; // ate the key + // last minute mute check + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + { + CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); + return; + } + + if (ci > 2) // don't send target+flags+empty message. + { + if (teamtalk) + buf[0] = -1; // target + else + buf[0] = 0; // target + buf[1] = 0; // flags + SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); + } + + chat_on = false; + break; + } + // cursor moving + case KEY_LEFTARROW: + case KEY_RIGHTARROW: + case KEY_HOME: + case KEY_END: + if (shiftdown) + { + if (chat_selection == -1) + chat_selection = chat_pos; + } + else + chat_selection = -1; + + switch (key) + { + case KEY_LEFTARROW: + // move cursor to previous word + if (ctrldown) + { + while (chat_pos > 0 && w_chat[chat_pos - 1] == ' ') + chat_pos--; + while (chat_pos > 0 && w_chat[chat_pos - 1] != ' ') + chat_pos--; + } + // move cursor left + else if (chat_pos > 0) + chat_pos--; + break; + case KEY_RIGHTARROW: + // move cursor to next word + if (ctrldown) + { + while (w_chat[chat_pos] && w_chat[chat_pos] != ' ') + chat_pos++; + while (w_chat[chat_pos] && w_chat[chat_pos] == ' ') + chat_pos++; + } + // move cursor right + else if (w_chat[chat_pos]) + chat_pos++; + break; + case KEY_HOME: + chat_pos = 0; + break; + case KEY_END: + chat_pos = strlen(w_chat); + } + + if (chat_pos == chat_selection) + chat_selection = -1; + break; + // backspace or delete selected text + case KEY_BACKSPACE: + if (chat_selection == -1) + { + if (chat_pos > 0) + { + UINT32 i, j; + for (i = chat_pos - 1, j = chat_pos; w_chat[j]; ++i, ++j) + w_chat[i] = w_chat[j]; + w_chat[i] = 0; + chat_pos--; + } + } + else + HU_DeleteSelectedText(); + break; + // delete character under cursor + case KEY_DEL: + if (chat_selection == -1) + { + UINT32 i, j; + + for (i = chat_pos, j = chat_pos + 1; w_chat[j]; ++i, ++j) + w_chat[i] = w_chat[j]; + w_chat[i] = 0; + } + else + HU_DeleteSelectedText(); + break; + default: + // allow people to use keypad in chat + if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) + { + XBOXSTATIC char keypad_translation[] = {'7','8','9','-', + '4','5','6','+', + '1','2','3', + '0','.'}; + + key = keypad_translation[key - KEY_KEYPAD7]; + } + else if (key == KEY_KPADSLASH) + key = '/'; + + // use console translations + if (shiftdown) + key = shiftxform[key]; + + if ((key >= HU_FONTSTART && key <= HU_FONTEND && hu_font[key-HU_FONTSTART]) + || key == ' ') // Allow spaces, of course + { + if (strlen(w_chat) < HU_MAXMSGLEN - 1) + { + UINT32 i, j; + + if (chat_selection != -1) + HU_DeleteSelectedText(); + + for (i = strlen(w_chat), j = i + 1; j > chat_pos; --i, --j) + w_chat[j] = w_chat[i]; + w_chat[chat_pos] = (char)key; + chat_pos++; + } + } + } } // @@ -669,86 +820,9 @@ void HU_Ticker(void) hu_showscores = false; } -#define QUEUESIZE 256 - -static boolean teamtalk = false; -static char chatchars[QUEUESIZE]; -static INT32 head = 0, tail = 0; - -// -// HU_dequeueChatChar -// -char HU_dequeueChatChar(void) -{ - char c; - - if (head != tail) - { - c = chatchars[tail]; - tail = (tail + 1) & (QUEUESIZE-1); - } - else - c = 0; - - return c; -} - -// -// -static void HU_queueChatChar(char c) -{ - // send automaticly the message (no more chat char) - if (c == KEY_ENTER) - { - char buf[2+256]; - size_t ci = 2; - - do { - c = HU_dequeueChatChar(); - if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. - buf[ci++]=c; - } while (c); - - // last minute mute check - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - { - CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); - return; - } - - if (ci > 3) // don't send target+flags+empty message. - { - if (teamtalk) - buf[0] = -1; // target - else - buf[0] = 0; // target - buf[1] = 0; // flags - SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); - } - return; - } - - if (((head + 1) & (QUEUESIZE-1)) == tail) - CONS_Printf(M_GetText("[Message unsent]\n")); // message not sent - else - { - if (c == KEY_BACKSPACE) - { - if (tail != head) - head = (head - 1) & (QUEUESIZE-1); - } - else - { - chatchars[head] = c; - head = (head + 1) & (QUEUESIZE-1); - } - } -} - +// REMOVE? Now this has become pretty useless IMO void HU_clearChatChars(void) { - while (tail != head) - HU_queueChatChar(KEY_BACKSPACE); chat_on = false; } @@ -758,13 +832,19 @@ void HU_clearChatChars(void) boolean HU_Responder(event_t *ev) { static boolean shiftdown = false; - UINT8 c; + static boolean ctrldown = false; + INT32 key = ev->data1; // only valid if ev->type is a key event - if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) + if (key == KEY_LSHIFT || key == KEY_RSHIFT) { shiftdown = (ev->type == ev_keydown); return chat_on; } + else if (key == KEY_LCTRL || key == KEY_RCTRL) + { + ctrldown = (ev->type == ev_keydown); + return chat_on; + } if (ev->type != ev_keydown) return false; @@ -774,42 +854,36 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { // enter chat mode - if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) + if ((key == gamecontrol[gc_talkkey][0] || key == gamecontrol[gc_talkkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - return false; + // we already checked for this two lines before... + //if (cv_mute.value && !(server || adminplayer == consoleplayer)) + //return false; chat_on = true; w_chat[0] = 0; + chat_pos = 0; + chat_selection = -1; teamtalk = false; return true; } - if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) + if ((key == gamecontrol[gc_teamkey][0] || key == gamecontrol[gc_teamkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - return false; + // we already checked for this two lines before... + //if (cv_mute.value && !(server || adminplayer == consoleplayer)) + //return false; chat_on = true; w_chat[0] = 0; + chat_pos = 0; + chat_selection = -1; teamtalk = true; return true; } } else // if chat_on { - c = (UINT8)ev->data1; - - // use console translations - if (shiftdown) - c = shiftxform[c]; - - if (HU_keyInChatString(w_chat,c)) - HU_queueChatChar(c); - if (c == KEY_ENTER) - chat_on = false; - else if (c == KEY_ESCAPE) - chat_on = false; - + HU_keyInChatString(w_chat, key, shiftdown, ctrldown); return true; } return false; @@ -826,7 +900,7 @@ boolean HU_Responder(event_t *ev) // static void HU_DrawChat(void) { - INT32 t = 0, c = 0, y = HU_INPUTY; + INT32 t = 0, f = 0, c = 0, y = HU_INPUTY; size_t i = 0; const char *ntalk = "Say: ", *ttalk = "Say-Team: "; const char *talk = ntalk; @@ -844,6 +918,8 @@ static void HU_DrawChat(void) #endif } + f = cv_constextsize.value | V_NOSCALESTART; + while (talk[i]) { if (talk[i] < HU_FONTSTART) @@ -854,36 +930,123 @@ static void HU_DrawChat(void) else { //charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | f, !cv_allcaps.value); } c += charwidth; } + f |= t; i = 0; - while (w_chat[i]) + if (chat_selection == -1) { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) + while (w_chat[i]) { - ++i; - //charwidth = 4 * con_scalefactor; + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } } - else + } + else + { + size_t selstart = min(chat_pos, chat_selection); + size_t selend = max(chat_pos, chat_selection); + + while (i < selstart) { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value); + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } } - c += charwidth; - if (c >= vid.width) + f &= ~t; + f |= V_YELLOWMAP; + while (i < selend) { - c = 0; - y += charheight; + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } + } + f &= ~V_YELLOWMAP; + f |= t; + + while (w_chat[i]) + { + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } } } if (hu_tick < 4) - V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value); + { + if (w_chat[chat_pos]) + { + i = (strlen(talk) + chat_pos) * charwidth; + c = i % vid.width; + y = HU_INPUTY + i / vid.width * charheight + 2 * con_scalefactor; + } + V_DrawCharacter(HU_INPUTX + c, y, '_' | f, !cv_allcaps.value); + } } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 7b22f33f..5dca1098 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -93,7 +93,6 @@ boolean HU_Responder(event_t *ev); void HU_Ticker(void); void HU_Drawer(void); -char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); From 8b72b553be7e28da023ee15298a40fa02755fbab Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 2 Nov 2016 20:10:08 +0100 Subject: [PATCH 071/207] Fixed warnings --- src/console.c | 16 ++++++++-------- src/hu_stuff.c | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/console.c b/src/console.c index 44819fb4..f4a1e4f8 100644 --- a/src/console.c +++ b/src/console.c @@ -628,8 +628,8 @@ static void CON_DeleteSelectedText(void) { UINT32 i, j; char *line = inputlines[inputline]; - size_t selstart = min(input_cx, input_selection); - size_t selend = max(input_cx, input_selection); + size_t selstart = min(input_cx, (size_t)input_selection); + size_t selend = max(input_cx, (size_t)input_selection); for (i = selstart, j = selend; line[j]; ++i, ++j) line[i] = line[j]; @@ -879,7 +879,7 @@ boolean CON_Responder(event_t *ev) else input_cx = 1; - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -899,7 +899,7 @@ boolean CON_Responder(event_t *ev) else input_cx = strlen(inputlines[inputline]); - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -991,7 +991,7 @@ boolean CON_Responder(event_t *ev) else if (input_cx > 1) input_cx--; - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -1021,7 +1021,7 @@ boolean CON_Responder(event_t *ev) else if (inputlines[inputline][input_cx]) input_cx++; - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -1414,8 +1414,8 @@ static void CON_DrawInput(void) } else { - size_t selstart = min(input_cx, input_selection); - size_t selend = max(input_cx, input_selection); + size_t selstart = min(input_cx, (size_t)input_selection); + size_t selend = max(input_cx, (size_t)input_selection); for (c = 0, x = charwidth; c < selstart && c < con_width-11; c++, x += charwidth) V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 9f1cea13..80e7cf71 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -631,8 +631,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) static void HU_DeleteSelectedText(void) { UINT32 i, j; - size_t selstart = min(chat_pos, chat_selection); - size_t selend = max(chat_pos, chat_selection); + size_t selstart = min(chat_pos, (size_t)chat_selection); + size_t selend = max(chat_pos, (size_t)chat_selection); for (i = selstart, j = selend; w_chat[j]; ++i, ++j) w_chat[i] = w_chat[j]; @@ -645,7 +645,7 @@ static void HU_DeleteSelectedText(void) // Handles key input and string input // -static inline void HU_keyInChatString(char *s, UINT32 key, boolean shiftdown, boolean ctrldown) +static void HU_keyInChatString(UINT32 key, boolean shiftdown, boolean ctrldown) { switch (key) { @@ -735,7 +735,7 @@ static inline void HU_keyInChatString(char *s, UINT32 key, boolean shiftdown, bo chat_pos = strlen(w_chat); } - if (chat_pos == chat_selection) + if ((INT32)chat_pos == chat_selection) chat_selection = -1; break; // backspace or delete selected text @@ -883,7 +883,7 @@ boolean HU_Responder(event_t *ev) } else // if chat_on { - HU_keyInChatString(w_chat, key, shiftdown, ctrldown); + HU_keyInChatString(key, shiftdown, ctrldown); return true; } return false; @@ -963,8 +963,8 @@ static void HU_DrawChat(void) } else { - size_t selstart = min(chat_pos, chat_selection); - size_t selend = max(chat_pos, chat_selection); + size_t selstart = min(chat_pos, (size_t)chat_selection); + size_t selend = max(chat_pos, (size_t)chat_selection); while (i < selstart) { From 81077656772cbd91ceee32e919fa7fb68f2dbc83 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 2 Nov 2016 14:26:35 -0700 Subject: [PATCH 072/207] make console back color use just one section of memory let's be honest, it's pretty dumb to have every single possible back colormap in memory when only one is being used at a time --- src/console.c | 99 +++++++++++++++++++++++++-------------------------- src/console.h | 7 ++-- src/p_setup.c | 2 +- src/v_video.c | 37 ++++++++----------- src/v_video.h | 2 +- 5 files changed, 68 insertions(+), 79 deletions(-) diff --git a/src/console.c b/src/console.c index 025bc1c1..3fa9b8a9 100644 --- a/src/console.c +++ b/src/console.c @@ -97,6 +97,7 @@ static void CON_InputInit(void); static void CON_RecalcSize(void); static void CONS_hudlines_Change(void); +static void CONS_backcolor_Change(void); static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth); //static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth); @@ -129,10 +130,11 @@ static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"} // whether to use console background picture, or translucent mode static consvar_t cons_backpic = {"con_backpic", "translucent", CV_SAVE, backpic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Orange"}, - {2, "Blue"}, {3, "Green"}, {4, "Gray"}, - {5, "Red"}, {0, NULL}}; -consvar_t cons_backcolor = {"con_backcolor", "3", CV_SAVE, backcolor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Gray"}, {2, "Brown"}, + {3, "Red"}, {4, "Orange"}, {5, "Yellow"}, + {6, "Green"}, {7, "Blue"}, {8, "Cyan"}, + {0, NULL}}; +consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; static void CON_Print(char *msg); @@ -219,8 +221,9 @@ static void CONS_Bind_f(void) // CONSOLE SETUP //====================================================================== -// Prepare a colormap for GREEN ONLY translucency over background -// +// Font colormap colors +// TODO: This could probably be improved somehow... +// These colormaps are 99% identical, with just a few changed bytes UINT8 *yellowmap; UINT8 *purplemap; UINT8 *lgreenmap; @@ -229,44 +232,49 @@ UINT8 *graymap; UINT8 *redmap; UINT8 *orangemap; -// Console BG colors -UINT8 *cwhitemap; -UINT8 *corangemap; -UINT8 *cbluemap; -UINT8 *cgreenmap; -UINT8 *cgraymap; -UINT8 *credmap; +// Console BG color +UINT8 *consolebgmap = NULL; -void CON_ReSetupBackColormap(UINT16 num) +void CON_SetupBackColormap(void) { - UINT16 i, j; - UINT8 k; - UINT8 *pal = W_CacheLumpName(R_GetPalname(num), PU_CACHE); + UINT16 i, palsum; + UINT8 j, palindex; + UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE); - // setup the green translucent background colormaps - for (i = 0, k = 0; i < 768; i += 3, k++) + if (!consolebgmap) + consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + + switch (cons_backcolor.value) { - j = pal[i] + pal[i+1] + pal[i+2]; - cwhitemap[k] = (UINT8)(15 - (j>>6)); - corangemap[k] = (UINT8)(95 - (j>>6)); - cbluemap[k] = (UINT8)(239 - (j>>6)); - cgreenmap[k] = (UINT8)(175 - (j>>6)); - cgraymap[k] = (UINT8)(31 - (j>>6)); - credmap[k] = (UINT8)(143 - (j>>6)); + case 0: palindex = 15; break; // White + case 1: palindex = 31; break; // Gray + case 2: palindex = 63; break; // Brown + case 3: palindex = 143; break; // Red + case 4: palindex = 95; break; // Orange + case 5: palindex = 111; break; // Yellow + case 6: palindex = 175; break; // Green + case 7: palindex = 239; break; // Blue + case 8: palindex = 219; break; // Cyan + // Default green + default: palindex = 175; break; +} + + // setup background colormap + for (i = 0, j = 0; i < 768; i += 3, j++) + { + palsum = (pal[i] + pal[i+1] + pal[i+2]) >> 6; + consolebgmap[j] = (UINT8)(palindex - palsum); } } -static void CON_SetupBackColormap(void) +static void CONS_backcolor_Change(void) { - INT32 i, j, k; - UINT8 *pal; + CON_SetupBackColormap(); +} - cwhitemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - corangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - cbluemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - cgreenmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - cgraymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - credmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); +static void CON_SetupColormaps(void) +{ + INT32 i; yellowmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); graymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); @@ -276,20 +284,6 @@ static void CON_SetupBackColormap(void) redmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); orangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - pal = W_CacheLumpName("PLAYPAL", PU_CACHE); - - // setup the green translucent background colormaps - for (i = 0, k = 0; i < 768; i += 3, k++) - { - j = pal[i] + pal[i+1] + pal[i+2]; - cwhitemap[k] = (UINT8)(15 - (j>>6)); - corangemap[k] = (UINT8)(95 - (j>>6)); - cbluemap[k] = (UINT8)(239 - (j>>6)); - cgreenmap[k] = (UINT8)(175 - (j>>6)); - cgraymap[k] = (UINT8)(31 - (j>>6)); - credmap[k] = (UINT8)(143 - (j>>6)); - } - // setup the other colormaps, for console text // these don't need to be aligned, unless you convert the @@ -320,6 +314,9 @@ static void CON_SetupBackColormap(void) redmap[9] = (UINT8)127; orangemap[3] = (UINT8)85; orangemap[9] = (UINT8)90; + + // Init back colormap + CON_SetupBackColormap(); } // Setup the console text buffer @@ -343,7 +340,7 @@ void CON_Init(void) con_width = 0; CON_RecalcSize(); - CON_SetupBackColormap(); + CON_SetupColormaps(); //note: CON_Ticker should always execute at least once before D_Display() con_clipviewtop = -1; // -1 does not clip @@ -1417,7 +1414,7 @@ static void CON_DrawConsole(void) { // inu: no more width (was always 0 and vid.width) if (rendermode != render_none) - V_DrawFadeConsBack(con_curlines, cons_backcolor.value); // translucent background + V_DrawFadeConsBack(con_curlines); // translucent background } // draw console text lines from top to bottom diff --git a/src/console.h b/src/console.h index 47af65e2..8cf6483f 100644 --- a/src/console.h +++ b/src/console.h @@ -40,11 +40,10 @@ extern consvar_t cons_backcolor; extern UINT8 *yellowmap, *purplemap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap; -// Console bg colors: -extern UINT8 *cwhitemap, *corangemap, *cbluemap, *cgreenmap, *cgraymap, - *credmap; +// Console bg color (auto updated to match) +extern UINT8 *consolebgmap; -void CON_ReSetupBackColormap(UINT16 num); +void CON_SetupBackColormap(void); void CON_ClearHUD(void); // clear heads up messages void CON_Ticker(void); diff --git a/src/p_setup.c b/src/p_setup.c index e56c44c7..111c717d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2585,7 +2585,7 @@ boolean P_SetupLevel(boolean skipprecip) lastloadedmaplumpnum = W_GetNumForName(maplumpname = G_BuildMapName(gamemap)); R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); - CON_ReSetupBackColormap(mapheaderinfo[gamemap-1]->palette); + CON_SetupBackColormap(); // now part of level loading since in future each level may have // its own anim texture sequences, switches etc. diff --git a/src/v_video.c b/src/v_video.c index 3cc6d195..43e3f018 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -968,45 +968,38 @@ void V_DrawFadeScreen(void) } // Simple translucency with one color, over a set number of lines starting from the top. -void V_DrawFadeConsBack(INT32 plines, INT32 pcolor) +void V_DrawFadeConsBack(INT32 plines) { - UINT8 *deststop, *colormap, *buf; + UINT8 *deststop, *buf; #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode != render_soft && rendermode != render_none) { UINT32 hwcolor; - switch (pcolor) + switch (cons_backcolor.value) { - case 0: hwcolor = 0xffffff00; break; //white - case 1: hwcolor = 0xff800000; break; //orange - case 2: hwcolor = 0x0000ff00; break; //blue - case 3: hwcolor = 0x00800000; break; //green - case 4: hwcolor = 0x80808000; break; //gray - case 5: hwcolor = 0xff000000; break; //red - default: hwcolor = 0x00800000; break; //green + case 0: hwcolor = 0xffffff00; break; // White + case 1: hwcolor = 0x80808000; break; // Gray + case 2: hwcolor = 0x40201000; break; // Brown + case 3: hwcolor = 0xff000000; break; // Red + case 4: hwcolor = 0xff800000; break; // Orange + case 5: hwcolor = 0x80800000; break; // Yellow + case 6: hwcolor = 0x00800000; break; // Green + case 7: hwcolor = 0x0000ff00; break; // Blue + case 8: hwcolor = 0x4080ff00; break; // Cyan + // Default green + default: hwcolor = 0x00800000; break; } HWR_DrawConsoleBack(hwcolor, plines); return; } #endif - switch (pcolor) - { - case 0: colormap = cwhitemap; break; - case 1: colormap = corangemap; break; - case 2: colormap = cbluemap; break; - case 3: colormap = cgreenmap; break; - case 4: colormap = cgraymap; break; - case 5: colormap = credmap; break; - default: colormap = cgreenmap; break; - } - // heavily simplified -- we don't need to know x or y position, // just the stop position deststop = screens[0] + vid.rowbytes * min(plines, vid.height); for (buf = screens[0]; buf < deststop; ++buf) - *buf = colormap[*buf]; + *buf = consolebgmap[*buf]; } // Gets string colormap, used for 0x80 color codes diff --git a/src/v_video.h b/src/v_video.h index 70255d0e..353f84c1 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -145,7 +145,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); // fade down the screen buffer before drawing the menu over void V_DrawFadeScreen(void); -void V_DrawFadeConsBack(INT32 plines, INT32 pcolor); +void V_DrawFadeConsBack(INT32 plines); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From c277125fe7bbf18639ae830b5b1b695179ac7f3b Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 2 Nov 2016 15:23:22 -0700 Subject: [PATCH 073/207] modifier key status made globally accessible now also properly handles L/R simultaneous presses --- src/console.c | 25 ++----------------------- src/d_main.c | 36 ++++++++++++++++++++++++++++++++++++ src/doomdef.h | 3 +++ src/hu_stuff.c | 7 ------- src/m_menu.c | 12 ------------ 5 files changed, 41 insertions(+), 42 deletions(-) diff --git a/src/console.c b/src/console.c index 3fa9b8a9..11aa5cd5 100644 --- a/src/console.c +++ b/src/console.c @@ -619,9 +619,7 @@ void CON_Ticker(void) // boolean CON_Responder(event_t *ev) { - static boolean consdown; - static boolean shiftdown; - static boolean ctrldown; + static UINT8 consdown = false; // console is treated differently due to rare usage // sequential completions a la 4dos static char completion[80]; @@ -636,13 +634,8 @@ boolean CON_Responder(event_t *ev) // let go keyup events, don't eat them if (ev->type != ev_keydown && ev->type != ev_console) { - if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) - shiftdown = false; - else if (ev->data1 == KEY_LCTRL || ev->data1 == KEY_RCTRL) - ctrldown = false; - else if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1]) + if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1]) consdown = false; - return false; } @@ -684,20 +677,6 @@ boolean CON_Responder(event_t *ev) } - // eat shift only if console active - if (key == KEY_LSHIFT || key == KEY_RSHIFT) - { - shiftdown = true; - return true; - } - - // same for ctrl - if (key == KEY_LCTRL || key == KEY_RCTRL) - { - ctrldown = true; - return true; - } - // command completion forward (tab) and backward (shift-tab) if (key == KEY_TAB) { diff --git a/src/d_main.c b/src/d_main.c index b61ec414..2caf5008 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -73,6 +73,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "dehacked.h" // Dehacked list test #include "m_cond.h" // condition initialization #include "fastcmp.h" +#include "keys.h" #ifdef CMAKECONFIG #include "config.h" @@ -176,6 +177,38 @@ void D_PostEvent(const event_t *ev) void D_PostEvent_end(void) {}; #endif +// modifier keys +UINT8 shiftdown = 0; // 0x1 left, 0x2 right +UINT8 ctrldown = 0; // 0x1 left, 0x2 right +UINT8 altdown = 0; // 0x1 left, 0x2 right +// +// D_ModifierKeyResponder +// Sets global shift/ctrl/alt variables, never actually eats events +// +static inline void D_ModifierKeyResponder(event_t *ev) +{ + if (ev->type == ev_keydown) switch (ev->data1) + { + case KEY_LSHIFT: shiftdown |= 0x1; return; + case KEY_RSHIFT: shiftdown |= 0x2; return; + case KEY_LCTRL: ctrldown |= 0x1; return; + case KEY_RCTRL: ctrldown |= 0x2; return; + case KEY_LALT: altdown |= 0x1; return; + case KEY_RALT: altdown |= 0x2; return; + default: return; + } + else if (ev->type == ev_keyup) switch (ev->data1) + { + case KEY_LSHIFT: shiftdown &= ~0x1; return; + case KEY_RSHIFT: shiftdown &= ~0x2; return; + case KEY_LCTRL: ctrldown &= ~0x1; return; + case KEY_RCTRL: ctrldown &= ~0x2; return; + case KEY_LALT: altdown &= ~0x1; return; + case KEY_RALT: altdown &= ~0x2; return; + default: return; + } +} + // // D_ProcessEvents // Send all the events of the given timestamp down the responder chain @@ -188,6 +221,9 @@ void D_ProcessEvents(void) { ev = &events[eventtail]; + // Set global shift/ctrl/alt down variables + D_ModifierKeyResponder(ev); // never eats events + // Screenshots over everything so that they can be taken anywhere. if (M_ScreenshotResponder(ev)) continue; // ate the event diff --git a/src/doomdef.h b/src/doomdef.h index fb8ab1ca..4b2d8c73 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -394,6 +394,9 @@ extern INT32 cv_debug; // Misc stuff for later... // ======================= +// Modifier key variables, accessible anywhere +extern UINT8 shiftdown, ctrldown, altdown; + // if we ever make our alloc stuff... #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index ec747305..e33a5430 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -757,15 +757,8 @@ void HU_clearChatChars(void) // boolean HU_Responder(event_t *ev) { - static boolean shiftdown = false; UINT8 c; - if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) - { - shiftdown = (ev->type == ev_keydown); - return chat_on; - } - if (ev->type != ev_keydown) return false; diff --git a/src/m_menu.c b/src/m_menu.c index 78c38127..d7b4d908 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -182,9 +182,6 @@ static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; -// what a headache. -static boolean shiftdown = false; - // // PROTOTYPES // @@ -2080,11 +2077,6 @@ boolean M_Responder(event_t *ev) || gamestate == GS_CREDITS || gamestate == GS_EVALUATION) return false; - if (ev->type == ev_keyup && (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT)) - { - shiftdown = false; - return false; - } if (noFurtherInput) { // Ignore input after enter/escape/other buttons @@ -2098,10 +2090,6 @@ boolean M_Responder(event_t *ev) // added 5-2-98 remap virtual keys (mouse & joystick buttons) switch (ch) { - case KEY_LSHIFT: - case KEY_RSHIFT: - shiftdown = true; - break; //return false; case KEY_MOUSE1: case KEY_JOY1: case KEY_JOY1 + 2: From b2c71944f6bedcf47462d852ba4bb23c14f655f5 Mon Sep 17 00:00:00 2001 From: STJrInuyasha Date: Thu, 3 Nov 2016 00:34:15 -0700 Subject: [PATCH 074/207] Revert "Chat and console improvements" --- src/console.c | 211 ++---------------------- src/hu_stuff.c | 437 ++++++++++++++++--------------------------------- src/hu_stuff.h | 1 + 3 files changed, 152 insertions(+), 497 deletions(-) diff --git a/src/console.c b/src/console.c index f4a1e4f8..025bc1c1 100644 --- a/src/console.c +++ b/src/console.c @@ -91,13 +91,11 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines static INT32 inputline; // current input line number static INT32 inputhist; // line number of history input line to restore static size_t input_cx; // position in current input line -static INT32 input_selection; // selection border in current input line, -1 if no selection // protos. static void CON_InputInit(void); static void CON_RecalcSize(void); -static void CON_DeleteSelectedText(void); static void CONS_hudlines_Change(void); static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth); //static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth); @@ -396,7 +394,6 @@ static void CON_InputInit(void) inputlines[i][0] = CON_PROMPTCHAR; inputline = 0; input_cx = 1; - input_selection = -1; } //====================================================================== @@ -621,25 +618,6 @@ void CON_Ticker(void) } } -// Deletes selected text, assuming there is, and resets selection. -// Also sets the cursor to the correct position. -// -static void CON_DeleteSelectedText(void) -{ - UINT32 i, j; - char *line = inputlines[inputline]; - size_t selstart = min(input_cx, (size_t)input_selection); - size_t selend = max(input_cx, (size_t)input_selection); - - for (i = selstart, j = selend; line[j]; ++i, ++j) - line[i] = line[j]; - while (line[i]) - line[i++] = 0; - - input_cx = selstart; - input_selection = -1; -} - // Handles console key input // boolean CON_Responder(event_t *ev) @@ -726,9 +704,6 @@ boolean CON_Responder(event_t *ev) // command completion forward (tab) and backward (shift-tab) if (key == KEY_TAB) { - input_cx = strlen(inputlines[inputline]); // make sure the cursor is at the end of the string, in case we were inserting - input_selection = -1; // make sure there is no text selected, it would look odd - // show all cvars/commands that match what we have inputted if (ctrldown) { @@ -864,51 +839,21 @@ boolean CON_Responder(event_t *ev) return true; } - if (key == KEY_HOME) + if (key == KEY_HOME) // oldest text in buffer { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; - } - else - input_selection = -1; - - if (ctrldown) - con_scrollup = (con_totallines-((con_curlines-16)>>3)); // oldest text in buffer - else - input_cx = 1; - - if ((INT32)input_cx == input_selection) - input_selection = -1; - + con_scrollup = (con_totallines-((con_curlines-16)>>3)); return true; } - else if (key == KEY_END) + else if (key == KEY_END) // most recent text in buffer { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; - } - else - input_selection = -1; - - if (ctrldown) - con_scrollup = 0; // most recent text in buffer - else - input_cx = strlen(inputlines[inputline]); - - if ((INT32)input_cx == input_selection) - input_selection = -1; - + con_scrollup = 0; return true; } // command enter if (key == KEY_ENTER) { - if (strlen(inputlines[inputline]) < 2) + if (input_cx < 2) return true; // push the command @@ -923,107 +868,18 @@ boolean CON_Responder(event_t *ev) memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); inputlines[inputline][0] = CON_PROMPTCHAR; input_cx = 1; - input_selection = -1; return true; } - // backspace command prompt or delete selected text + // backspace command prompt if (key == KEY_BACKSPACE) { - if (input_selection == -1) + if (input_cx > 1) { - if (input_cx > 1) - { - UINT32 i, j; - char *line = inputlines[inputline]; - - for (i = input_cx - 1, j = input_cx; line[j]; ++i, ++j) - line[i] = line[j]; - line[i] = 0; - input_cx--; - } - } - else - CON_DeleteSelectedText(); - return true; - } - - // delete character under cursor or selected text - if (key == KEY_DEL) - { - if (input_selection == -1) - { - UINT32 i, j; - char *line = inputlines[inputline]; - - for (i = input_cx, j = input_cx + 1; line[j]; ++i, ++j) - line[i] = line[j]; - line[i] = 0; - } - else - CON_DeleteSelectedText(); - - return true; - } - - if (key == KEY_LEFTARROW) - { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; - } - else - input_selection = -1; - - // move cursor to previous word - if (ctrldown) - { - char *line = inputlines[inputline]; - - while (input_cx > 1 && line[input_cx - 1] == ' ') - input_cx--; - while (input_cx > 1 && line[input_cx - 1] != ' ') - input_cx--; - } - // move cursor left - else if (input_cx > 1) input_cx--; - - if ((INT32)input_cx == input_selection) - input_selection = -1; - - return true; - } - - if (key == KEY_RIGHTARROW) - { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; + inputlines[inputline][input_cx] = 0; } - else - input_selection = -1; - - // move cursor to next word - if (ctrldown) - { - char *line = inputlines[inputline]; - - while (line[input_cx] && line[input_cx] != ' ') - input_cx++; - while (line[input_cx] && line[input_cx] == ' ') - input_cx++; - } - // move cursor right - else if (inputlines[inputline][input_cx]) - input_cx++; - - if ((INT32)input_cx == input_selection) - input_selection = -1; - return true; } @@ -1094,21 +950,13 @@ boolean CON_Responder(event_t *ev) return false; // add key to cmd line here - if (strlen(inputlines[inputline]) < CON_MAXPROMPTCHARS - 1) + if (input_cx < CON_MAXPROMPTCHARS) { - INT32 i, j; - char *line = inputlines[inputline]; - if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers key = key + 'a' - 'A'; - if (input_selection != -1) - CON_DeleteSelectedText(); - - for (i = strlen(line), j = i + 1; j > (INT32)input_cx; --i, --j) - line[j] = line[i]; - - line[input_cx] = (char)key; + inputlines[inputline][input_cx] = (char)key; + inputlines[inputline][input_cx + 1] = 0; input_cx++; } @@ -1398,7 +1246,6 @@ static void CON_DrawInput(void) size_t c; INT32 x, y; INT32 charwidth = (INT32)con_scalefactor << 3; - INT32 f = cv_constextsize.value | V_NOSCALESTART; // input line scrolls left if it gets too long p = inputlines[inputline]; @@ -1407,44 +1254,14 @@ static void CON_DrawInput(void) y = con_curlines - 12 * con_scalefactor; - if (input_selection == -1) - { - for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - } - else - { - size_t selstart = min(input_cx, (size_t)input_selection); - size_t selend = max(input_cx, (size_t)input_selection); - - for (c = 0, x = charwidth; c < selstart && c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - - f |= V_YELLOWMAP; - for (; c < selend && c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - f &= ~V_YELLOWMAP; - - for (; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - } - //for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - //V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); // draw the blinking cursor // x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); if (con_tick < 4) - { - if (inputlines[inputline][input_cx]) - //V_DrawCharacter(x - 2 * con_scalefactor, y, '|' | f, !cv_allcaps.value); - V_DrawCharacter(x, y + 2 * con_scalefactor, '_' | f, !cv_allcaps.value); - else - V_DrawCharacter(x, y, '_' | f, !cv_allcaps.value); - } - /*x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); - if (con_tick < 4) - V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);*/ + V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); } // draw the last lines of console text to the top of the screen diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 80e7cf71..ec747305 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -73,9 +73,6 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; -static size_t chat_pos; // position of the cursor in the chat -static INT32 chat_selection; // selection border in current input line, -1 if no selection -static boolean teamtalk = false; static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -109,7 +106,6 @@ static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics static void HU_DrawRankings(void); static void HU_DrawCoopOverlay(void); static void HU_DrawNetplayCoopOverlay(void); -static void HU_DeleteSelectedText(void); //====================================================================== // KEYBOARD LAYOUTS FOR ENTERING TEXT @@ -625,183 +621,36 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } #endif -// Deletes selected text, assuming there is, and resets selection. -// Also sets the cursor to the correct position. -// -static void HU_DeleteSelectedText(void) -{ - UINT32 i, j; - size_t selstart = min(chat_pos, (size_t)chat_selection); - size_t selend = max(chat_pos, (size_t)chat_selection); - - for (i = selstart, j = selend; w_chat[j]; ++i, ++j) - w_chat[i] = w_chat[j]; - while (w_chat[i]) - w_chat[i++] = 0; - - chat_pos = selstart; - chat_selection = -1; -} - // Handles key input and string input // -static void HU_keyInChatString(UINT32 key, boolean shiftdown, boolean ctrldown) +static inline boolean HU_keyInChatString(char *s, char ch) { - switch (key) + size_t l; + + if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART]) + || ch == ' ') // Allow spaces, of course { - case KEY_ESCAPE: - chat_on = false; - break; - case KEY_ENTER: + l = strlen(s); + if (l < HU_MAXMSGLEN - 1) + { + s[l++] = ch; + s[l]=0; + return true; + } + return false; + } + else if (ch == KEY_BACKSPACE) { - // send automatically the message (no more chat char) - char buf[2+256]; - size_t ci = 2; - char *cp = w_chat; - - while (*cp) - { - if (*cp >= ' ' && !(*cp & 0x80)) - buf[ci++] = *cp; - cp++; - } - buf[ci] = 0; - - // last minute mute check - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - { - CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); - return; - } - - if (ci > 2) // don't send target+flags+empty message. - { - if (teamtalk) - buf[0] = -1; // target - else - buf[0] = 0; // target - buf[1] = 0; // flags - SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); - } - - chat_on = false; - break; + l = strlen(s); + if (l) + s[--l] = 0; + else + return false; } - // cursor moving - case KEY_LEFTARROW: - case KEY_RIGHTARROW: - case KEY_HOME: - case KEY_END: - if (shiftdown) - { - if (chat_selection == -1) - chat_selection = chat_pos; - } - else - chat_selection = -1; + else if (ch != KEY_ENTER) + return false; // did not eat key - switch (key) - { - case KEY_LEFTARROW: - // move cursor to previous word - if (ctrldown) - { - while (chat_pos > 0 && w_chat[chat_pos - 1] == ' ') - chat_pos--; - while (chat_pos > 0 && w_chat[chat_pos - 1] != ' ') - chat_pos--; - } - // move cursor left - else if (chat_pos > 0) - chat_pos--; - break; - case KEY_RIGHTARROW: - // move cursor to next word - if (ctrldown) - { - while (w_chat[chat_pos] && w_chat[chat_pos] != ' ') - chat_pos++; - while (w_chat[chat_pos] && w_chat[chat_pos] == ' ') - chat_pos++; - } - // move cursor right - else if (w_chat[chat_pos]) - chat_pos++; - break; - case KEY_HOME: - chat_pos = 0; - break; - case KEY_END: - chat_pos = strlen(w_chat); - } - - if ((INT32)chat_pos == chat_selection) - chat_selection = -1; - break; - // backspace or delete selected text - case KEY_BACKSPACE: - if (chat_selection == -1) - { - if (chat_pos > 0) - { - UINT32 i, j; - for (i = chat_pos - 1, j = chat_pos; w_chat[j]; ++i, ++j) - w_chat[i] = w_chat[j]; - w_chat[i] = 0; - chat_pos--; - } - } - else - HU_DeleteSelectedText(); - break; - // delete character under cursor - case KEY_DEL: - if (chat_selection == -1) - { - UINT32 i, j; - - for (i = chat_pos, j = chat_pos + 1; w_chat[j]; ++i, ++j) - w_chat[i] = w_chat[j]; - w_chat[i] = 0; - } - else - HU_DeleteSelectedText(); - break; - default: - // allow people to use keypad in chat - if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) - { - XBOXSTATIC char keypad_translation[] = {'7','8','9','-', - '4','5','6','+', - '1','2','3', - '0','.'}; - - key = keypad_translation[key - KEY_KEYPAD7]; - } - else if (key == KEY_KPADSLASH) - key = '/'; - - // use console translations - if (shiftdown) - key = shiftxform[key]; - - if ((key >= HU_FONTSTART && key <= HU_FONTEND && hu_font[key-HU_FONTSTART]) - || key == ' ') // Allow spaces, of course - { - if (strlen(w_chat) < HU_MAXMSGLEN - 1) - { - UINT32 i, j; - - if (chat_selection != -1) - HU_DeleteSelectedText(); - - for (i = strlen(w_chat), j = i + 1; j > chat_pos; --i, --j) - w_chat[j] = w_chat[i]; - w_chat[chat_pos] = (char)key; - chat_pos++; - } - } - } + return true; // ate the key } // @@ -820,9 +669,86 @@ void HU_Ticker(void) hu_showscores = false; } -// REMOVE? Now this has become pretty useless IMO +#define QUEUESIZE 256 + +static boolean teamtalk = false; +static char chatchars[QUEUESIZE]; +static INT32 head = 0, tail = 0; + +// +// HU_dequeueChatChar +// +char HU_dequeueChatChar(void) +{ + char c; + + if (head != tail) + { + c = chatchars[tail]; + tail = (tail + 1) & (QUEUESIZE-1); + } + else + c = 0; + + return c; +} + +// +// +static void HU_queueChatChar(char c) +{ + // send automaticly the message (no more chat char) + if (c == KEY_ENTER) + { + char buf[2+256]; + size_t ci = 2; + + do { + c = HU_dequeueChatChar(); + if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. + buf[ci++]=c; + } while (c); + + // last minute mute check + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + { + CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); + return; + } + + if (ci > 3) // don't send target+flags+empty message. + { + if (teamtalk) + buf[0] = -1; // target + else + buf[0] = 0; // target + buf[1] = 0; // flags + SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); + } + return; + } + + if (((head + 1) & (QUEUESIZE-1)) == tail) + CONS_Printf(M_GetText("[Message unsent]\n")); // message not sent + else + { + if (c == KEY_BACKSPACE) + { + if (tail != head) + head = (head - 1) & (QUEUESIZE-1); + } + else + { + chatchars[head] = c; + head = (head + 1) & (QUEUESIZE-1); + } + } +} + void HU_clearChatChars(void) { + while (tail != head) + HU_queueChatChar(KEY_BACKSPACE); chat_on = false; } @@ -832,19 +758,13 @@ void HU_clearChatChars(void) boolean HU_Responder(event_t *ev) { static boolean shiftdown = false; - static boolean ctrldown = false; - INT32 key = ev->data1; // only valid if ev->type is a key event + UINT8 c; - if (key == KEY_LSHIFT || key == KEY_RSHIFT) + if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) { shiftdown = (ev->type == ev_keydown); return chat_on; } - else if (key == KEY_LCTRL || key == KEY_RCTRL) - { - ctrldown = (ev->type == ev_keydown); - return chat_on; - } if (ev->type != ev_keydown) return false; @@ -854,36 +774,42 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { // enter chat mode - if ((key == gamecontrol[gc_talkkey][0] || key == gamecontrol[gc_talkkey][1]) + if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - // we already checked for this two lines before... - //if (cv_mute.value && !(server || adminplayer == consoleplayer)) - //return false; + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + return false; chat_on = true; w_chat[0] = 0; - chat_pos = 0; - chat_selection = -1; teamtalk = false; return true; } - if ((key == gamecontrol[gc_teamkey][0] || key == gamecontrol[gc_teamkey][1]) + if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - // we already checked for this two lines before... - //if (cv_mute.value && !(server || adminplayer == consoleplayer)) - //return false; + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + return false; chat_on = true; w_chat[0] = 0; - chat_pos = 0; - chat_selection = -1; teamtalk = true; return true; } } else // if chat_on { - HU_keyInChatString(key, shiftdown, ctrldown); + c = (UINT8)ev->data1; + + // use console translations + if (shiftdown) + c = shiftxform[c]; + + if (HU_keyInChatString(w_chat,c)) + HU_queueChatChar(c); + if (c == KEY_ENTER) + chat_on = false; + else if (c == KEY_ESCAPE) + chat_on = false; + return true; } return false; @@ -900,7 +826,7 @@ boolean HU_Responder(event_t *ev) // static void HU_DrawChat(void) { - INT32 t = 0, f = 0, c = 0, y = HU_INPUTY; + INT32 t = 0, c = 0, y = HU_INPUTY; size_t i = 0; const char *ntalk = "Say: ", *ttalk = "Say-Team: "; const char *talk = ntalk; @@ -918,8 +844,6 @@ static void HU_DrawChat(void) #endif } - f = cv_constextsize.value | V_NOSCALESTART; - while (talk[i]) { if (talk[i] < HU_FONTSTART) @@ -930,123 +854,36 @@ static void HU_DrawChat(void) else { //charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | f, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); } c += charwidth; } - f |= t; i = 0; - if (chat_selection == -1) + while (w_chat[i]) { - while (w_chat[i]) + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } + ++i; + //charwidth = 4 * con_scalefactor; } - } - else - { - size_t selstart = min(chat_pos, (size_t)chat_selection); - size_t selend = max(chat_pos, (size_t)chat_selection); - - while (i < selstart) + else { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value); } - f &= ~t; - f |= V_YELLOWMAP; - while (i < selend) + c += charwidth; + if (c >= vid.width) { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } - } - f &= ~V_YELLOWMAP; - f |= t; - - while (w_chat[i]) - { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } + c = 0; + y += charheight; } } if (hu_tick < 4) - { - if (w_chat[chat_pos]) - { - i = (strlen(talk) + chat_pos) * charwidth; - c = i % vid.width; - y = HU_INPUTY + i / vid.width * charheight + 2 * con_scalefactor; - } - V_DrawCharacter(HU_INPUTX + c, y, '_' | f, !cv_allcaps.value); - } + V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value); } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 5dca1098..7b22f33f 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -93,6 +93,7 @@ boolean HU_Responder(event_t *ev); void HU_Ticker(void); void HU_Drawer(void); +char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); From bb20cfd6beb341c0774c473150ebb9e1d889cbfe Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Thu, 3 Nov 2016 01:43:57 -0700 Subject: [PATCH 075/207] Clipboard copy/paste testing (unfinished, but basics work) --- src/android/i_system.c | 12 +++++ src/console.c | 108 ++++++++++++++++++------------------- src/djgppdos/i_system.c | 12 +++++ src/dummy/i_system.c | 12 +++++ src/i_system.h | 8 +++ src/nds/i_system.c | 12 +++++ src/sdl/i_system.c | 115 ++++++++++++++++++++++++++++++++++++++++ src/sdl/ogl_sdl.h | 1 - src/sdl/sdlmain.h | 3 ++ src/sdl12/i_system.c | 12 +++++ src/win32/win_sys.c | 12 +++++ src/win32ce/win_sys.c | 12 +++++ 12 files changed, 264 insertions(+), 55 deletions(-) diff --git a/src/android/i_system.c b/src/android/i_system.c index 150cbd50..58fca7c1 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -258,6 +258,18 @@ INT32 I_PutEnv(char *variable) return -1; } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + void I_RegisterSysCommands(void) {} #include "../sdl/dosstr.c" diff --git a/src/console.c b/src/console.c index 11aa5cd5..02324ada 100644 --- a/src/console.c +++ b/src/console.c @@ -641,6 +641,12 @@ boolean CON_Responder(event_t *ev) key = ev->data1; + // Always eat ctrl/shift/alt, so the menu doesn't get ideas + if (key == KEY_LSHIFT || key == KEY_RSHIFT + || key == KEY_LCTRL || key == KEY_RCTRL + || key == KEY_LALT || key == KEY_RALT) + return true; + // check for console toggle key if (ev->type != ev_console) { @@ -677,67 +683,70 @@ boolean CON_Responder(event_t *ev) } - // command completion forward (tab) and backward (shift-tab) - if (key == KEY_TAB) + // ctrl modifier -- changes behavior, adds shortcuts + if (ctrldown) { // show all cvars/commands that match what we have inputted - if (ctrldown) + if (key == KEY_TAB) { - UINT32 i; - size_t stop = input_cx - 1; - char nameremainder[255]; + size_t i, len = strlen(inputlines[inputline]+1); - if (input_cx < 2 || strlen(inputlines[inputline]+1) >= 80) + if (input_cx < 2 || len >= 80 || strchr(inputlines[inputline]+1, ' ')) return true; strcpy(completion, inputlines[inputline]+1); - // trimming: stop at the first newline - for (i = 0; i < input_cx - 1; ++i) - { - if (completion[i] == ' ') - { - completion[i] = '\0'; - stop = i; - break; - } - } - - i = 0; - //first check commands CONS_Printf("\nCommands:\n"); - - for (cmd = COM_CompleteCommand(completion, i); cmd; cmd = COM_CompleteCommand(completion, i)) - { - strncpy(nameremainder, cmd+(stop), strlen(cmd)-(stop)); - nameremainder[strlen(cmd)-(stop)] = '\0'; - - CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, nameremainder); - ++i; - } - if (i == 0) - CONS_Printf(" (none)\n"); - - i = 0; + for (i = 0, cmd = COM_CompleteCommand(completion, i); cmd; cmd = COM_CompleteCommand(completion, ++i)) + CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, cmd+len); + if (i == 0) CONS_Printf(" (none)\n"); //now we move on to CVARs CONS_Printf("Variables:\n"); - - for (cmd = CV_CompleteVar(completion, i); cmd; cmd = CV_CompleteVar(completion, i)) - { - strncpy(nameremainder, cmd+(stop), strlen(cmd)-(stop)); - nameremainder[strlen(cmd)-(stop)] = '\0'; - - CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, nameremainder); - ++i; - } - if (i == 0) - CONS_Printf(" (none)\n"); + for (i = 0, cmd = CV_CompleteVar(completion, i); cmd; cmd = CV_CompleteVar(completion, ++i)) + CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, cmd+len); + if (i == 0) CONS_Printf(" (none)\n"); return true; } + // --- + if (key == KEY_HOME) // oldest text in buffer + { + con_scrollup = (con_totallines-((con_curlines-16)>>3)); + return true; + } + else if (key == KEY_END) // most recent text in buffer + { + con_scrollup = 0; + return true; + } + + if (key == 'x' || key == 'X') + { + CONS_Printf("Cut\n"); + return true; + } + else if (key == 'c' || key == 'C') + { + CONS_Printf("Copy\n"); + I_ClipboardCopy(inputlines[inputline]+1, strlen(inputlines[inputline]+1)); + return true; + } + else if (key == 'v' || key == 'V') + { + CONS_Printf("Paste: %s\n", I_ClipboardPaste()); + return true; + } + + // don't eat the key + return false; + } + + // command completion forward (tab) and backward (shift-tab) + if (key == KEY_TAB) + { // sequential command completion forward and backward // remember typing for several completions (a-la-4dos) @@ -815,16 +824,7 @@ boolean CON_Responder(event_t *ev) return true; } - if (key == KEY_HOME) // oldest text in buffer - { - con_scrollup = (con_totallines-((con_curlines-16)>>3)); - return true; - } - else if (key == KEY_END) // most recent text in buffer - { - con_scrollup = 0; - return true; - } + // command enter if (key == KEY_ENTER) diff --git a/src/djgppdos/i_system.c b/src/djgppdos/i_system.c index 854d68f4..dae9ed16 100644 --- a/src/djgppdos/i_system.c +++ b/src/djgppdos/i_system.c @@ -1721,6 +1721,18 @@ INT32 I_PutEnv(char *variable) return putenv(variable); } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + const CPUInfoFlags *I_CPUInfo(void) { static CPUInfoFlags DOS_CPUInfo; diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index c1e48b60..a3fe3077 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -162,6 +162,18 @@ INT32 I_PutEnv(char *variable) return -1; } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + void I_RegisterSysCommands(void) {} #include "../sdl/dosstr.c" diff --git a/src/i_system.h b/src/i_system.h index c161851e..d61f2d16 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -296,6 +296,14 @@ char *I_GetEnv(const char *name); INT32 I_PutEnv(char *variable); +/** \brief Put data in system clipboard +*/ +INT32 I_ClipboardCopy(const char *data, size_t size); + +/** \brief Retrieve data from system clipboard +*/ +const char *I_ClipboardPaste(void); + void I_RegisterSysCommands(void); #endif diff --git a/src/nds/i_system.c b/src/nds/i_system.c index 0ed58029..3e5c4b8c 100644 --- a/src/nds/i_system.c +++ b/src/nds/i_system.c @@ -269,6 +269,18 @@ INT32 I_PutEnv(char *variable) return -1; } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + void I_RegisterSysCommands(void) {} #include "../sdl/dosstr.c" diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index ea8ade8c..8c4331aa 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -260,6 +260,18 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif +// FAKE_CLIPBOARD simulates system clipboard, but is just local to our app +#ifndef FAKE_CLIPBOARD +#include "SDL_syswm.h" + +#if defined (_WIN32) && !defined (_XBOX) +#include +#endif + +// TODO: clipboard support for other OSes + +#endif + /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2647,6 +2659,109 @@ INT32 I_PutEnv(char *variable) #endif } +#ifdef FAKE_CLIPBOARD +static char __clipboard[512] = ""; +#endif + +INT32 I_ClipboardCopy(const char *data, size_t size) +{ +#ifdef FAKE_CLIPBOARD + if (size >= 512) size = 511; + memcpy(__clipboard, data, size); + __clipboard[size] = 0; + return 0; +#else // !FAKE_CLIPBOARD + +#if defined(_WIN32) && !defined(_XBOX) + SDL_SysWMinfo syswm; + HGLOBAL *storage_ptr; + char *storage_raw; + + SDL_VERSION(&syswm.version); + + // Get window (HWND) information, use that to open the clipboard + if (!SDL_GetWindowWMInfo(window, &syswm) || !(OpenClipboard(syswm.info.win.window))) + return -1; + + // Erase clipboard contents -- if we have nothing to copy, just leave them blank + EmptyClipboard(); + if (size == 0) + goto clipboardend; + + // Allocate movable global memory to store our text. + if (!(storage_ptr = GlobalAlloc(GMEM_MOVEABLE, size+1)) + || !(storage_raw = (char *)GlobalLock(storage_ptr))) // Lock our pointer (gives us access to its data) + goto clipboardfail; + memcpy(storage_raw, data, size); + storage_raw[size] = 0; + GlobalUnlock(storage_ptr); // Unlock it before sending it off + if (!SetClipboardData(CF_TEXT, storage_ptr)) // NOTE: this removes our permissions from the pointer + goto clipboardfail; + +clipboardend: + CloseClipboard(); + return 0; //OpenClipboard(); +clipboardfail: + CloseClipboard(); // Don't leave me hanging + return -1; +#else + (void)data; + (void)size; + return -1; +#endif + +#endif // FAKE_CLIPBOARD +} + +const char *I_ClipboardPaste(void) +{ +#ifdef FAKE_CLIPBOARD + return (const char *)&__clipboard; +#else // !FAKE_CLIPBOARD + +#if defined(_WIN32) && !defined(_XBOX) + HGLOBAL *clipboard_ptr; + const char *clipboard_raw; + static char clipboard_contents[512]; + char *i = clipboard_contents; + + if (!IsClipboardFormatAvailable(CF_TEXT)) + return NULL; // Data either unavailable, or in wrong format + OpenClipboard(NULL); // NOTE: Don't need window pointer to get, only to set + if (!(clipboard_ptr = GetClipboardData(CF_TEXT))) // Get global pointer + return NULL; + if (!(clipboard_raw = (const char *)GlobalLock(clipboard_ptr))) // Lock access -- gives us direct ptr to data + { + CloseClipboard(); // Don't leave me hanging if we fail + return NULL; + } + memcpy(clipboard_contents, clipboard_raw, 511); + GlobalUnlock(clipboard_ptr); // Unlock for other apps + CloseClipboard(); // And make sure to close the clipboard for other apps too + clipboard_contents[511] = 0; // Done after unlock to cause as little interference as possible + + while (*i) + { + if (*i == '\n' || *i == '\r') + { // End on newline + *i = 0; + break; + } + else if (*i == '\t') + *i = ' '; // Tabs become spaces + else if (*i < 32 || (unsigned)*i > 127) + *i = '?'; // Nonprintable chars become question marks + ++i; + } + + return (const char *)&clipboard_contents; +#else + return NULL; +#endif + +#endif // FAKE_CLIPBOARD +} + /** \brief The isWadPathOk function \param path string path to check diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index 7e144644..2d6209f2 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -24,7 +24,6 @@ boolean OglSdlSurface(INT32 w, INT32 h); void OglSdlFinishUpdate(boolean vidwait); -extern SDL_Window *window; extern SDL_Renderer *renderer; extern SDL_GLContext sdlglcontext; extern Uint16 realwidth; diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index 7ac32f4b..fea1e164 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -71,4 +71,7 @@ void I_GetConsoleEvents(void); void SDLforceUngrabMouse(void); +// Needed for some WIN32 functions +extern SDL_Window *window; + #endif diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c index 888a6a50..ed0db653 100644 --- a/src/sdl12/i_system.c +++ b/src/sdl12/i_system.c @@ -2666,6 +2666,18 @@ INT32 I_PutEnv(char *variable) #endif } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + /** \brief The isWadPathOk function \param path string path to check diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index 0331080c..eec04380 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -3598,6 +3598,18 @@ INT32 I_PutEnv(char *variable) return putenv(variable); } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + typedef BOOL (WINAPI *p_IsProcessorFeaturePresent) (DWORD); const CPUInfoFlags *I_CPUInfo(void) diff --git a/src/win32ce/win_sys.c b/src/win32ce/win_sys.c index 88764ef7..3b6a4725 100644 --- a/src/win32ce/win_sys.c +++ b/src/win32ce/win_sys.c @@ -3470,6 +3470,18 @@ INT32 I_PutEnv(char *variable) return putenv(variable); } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + typedef BOOL (WINAPI *MyFunc3) (DWORD); const CPUInfoFlags *I_CPUInfo(void) From 8040a68fa087f4c09f60c5663fd08077830b8707 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 3 Nov 2016 14:29:51 -0400 Subject: [PATCH 076/207] Clipboard: remove Win32 code for SDL Clipboard API --- src/sdl/i_system.c | 107 ++------------------------------------------- 1 file changed, 4 insertions(+), 103 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 8c4331aa..97746b6b 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -260,18 +260,6 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif -// FAKE_CLIPBOARD simulates system clipboard, but is just local to our app -#ifndef FAKE_CLIPBOARD -#include "SDL_syswm.h" - -#if defined (_WIN32) && !defined (_XBOX) -#include -#endif - -// TODO: clipboard support for other OSes - -#endif - /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2659,107 +2647,20 @@ INT32 I_PutEnv(char *variable) #endif } -#ifdef FAKE_CLIPBOARD -static char __clipboard[512] = ""; -#endif INT32 I_ClipboardCopy(const char *data, size_t size) { -#ifdef FAKE_CLIPBOARD - if (size >= 512) size = 511; - memcpy(__clipboard, data, size); - __clipboard[size] = 0; - return 0; -#else // !FAKE_CLIPBOARD - -#if defined(_WIN32) && !defined(_XBOX) - SDL_SysWMinfo syswm; - HGLOBAL *storage_ptr; - char *storage_raw; - - SDL_VERSION(&syswm.version); - - // Get window (HWND) information, use that to open the clipboard - if (!SDL_GetWindowWMInfo(window, &syswm) || !(OpenClipboard(syswm.info.win.window))) - return -1; - - // Erase clipboard contents -- if we have nothing to copy, just leave them blank - EmptyClipboard(); - if (size == 0) - goto clipboardend; - - // Allocate movable global memory to store our text. - if (!(storage_ptr = GlobalAlloc(GMEM_MOVEABLE, size+1)) - || !(storage_raw = (char *)GlobalLock(storage_ptr))) // Lock our pointer (gives us access to its data) - goto clipboardfail; - memcpy(storage_raw, data, size); - storage_raw[size] = 0; - GlobalUnlock(storage_ptr); // Unlock it before sending it off - if (!SetClipboardData(CF_TEXT, storage_ptr)) // NOTE: this removes our permissions from the pointer - goto clipboardfail; - -clipboardend: - CloseClipboard(); - return 0; //OpenClipboard(); -clipboardfail: - CloseClipboard(); // Don't leave me hanging - return -1; -#else - (void)data; (void)size; + if (SDL_SetClipboardText(data) == 0) + return 0; return -1; -#endif - -#endif // FAKE_CLIPBOARD } const char *I_ClipboardPaste(void) { -#ifdef FAKE_CLIPBOARD - return (const char *)&__clipboard; -#else // !FAKE_CLIPBOARD - -#if defined(_WIN32) && !defined(_XBOX) - HGLOBAL *clipboard_ptr; - const char *clipboard_raw; - static char clipboard_contents[512]; - char *i = clipboard_contents; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return NULL; // Data either unavailable, or in wrong format - OpenClipboard(NULL); // NOTE: Don't need window pointer to get, only to set - if (!(clipboard_ptr = GetClipboardData(CF_TEXT))) // Get global pointer - return NULL; - if (!(clipboard_raw = (const char *)GlobalLock(clipboard_ptr))) // Lock access -- gives us direct ptr to data - { - CloseClipboard(); // Don't leave me hanging if we fail - return NULL; - } - memcpy(clipboard_contents, clipboard_raw, 511); - GlobalUnlock(clipboard_ptr); // Unlock for other apps - CloseClipboard(); // And make sure to close the clipboard for other apps too - clipboard_contents[511] = 0; // Done after unlock to cause as little interference as possible - - while (*i) - { - if (*i == '\n' || *i == '\r') - { // End on newline - *i = 0; - break; - } - else if (*i == '\t') - *i = ' '; // Tabs become spaces - else if (*i < 32 || (unsigned)*i > 127) - *i = '?'; // Nonprintable chars become question marks - ++i; - } - - return (const char *)&clipboard_contents; -#else + if (SDL_HasClipboardText()) + return SDL_GetClipboardText(); return NULL; -#endif - -#endif // FAKE_CLIPBOARD } /** \brief The isWadPathOk function From 1f6388a2e0089c6004825fa7ef66c54c0800de73 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 3 Nov 2016 14:35:32 -0400 Subject: [PATCH 077/207] Fix up Win32 interface code misdeclaration of I_ClipboardPaste() --- src/win32/win_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index eec04380..80b89a6e 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -3605,7 +3605,7 @@ INT32 I_ClipboardCopy(const char *data, size_t size) return -1; } -char *I_ClipboardPaste(void) +const char *I_ClipboardPaste(void) { return NULL; } From 2ec972af54fe9c8c241e89387f3516ebd4b68c3b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 3 Nov 2016 20:40:17 +0000 Subject: [PATCH 078/207] check numVertices, bail out and print error message if there are too many I added similar checks for the other num* but it seems some MD2s break the other limits without knowing anyway ...so I've commented these checks out for now, unless we have further discussion regarding them later on --- src/hardware/hw_md2.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8e48ec11..8e2b9a5b 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -308,6 +308,23 @@ static md2_model_t *md2_readModel(const char *filename) model->header.numSkins = 1; +#define MD2LIMITCHECK(field, max, msgname) \ + if (field >= max) \ + { \ + CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \ + md2_freeModel (model); \ + return 0; \ + } + + // Uncomment if these are actually needed +// MD2LIMITCHECK(model->header.numSkins, MD2_MAX_SKINS, "skins") +// MD2LIMITCHECK(model->header.numTexCoords, MD2_MAX_TEXCOORDS, "texture coordinates") +// MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles") +// MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames") + MD2LIMITCHECK(model->header.numVertices, MD2_MAX_VERTICES, "vertices") + +#undef MD2LIMITCHECK + // read skins fseek(file, model->header.offsetSkins, SEEK_SET); if (model->header.numSkins > 0) @@ -319,8 +336,6 @@ static md2_model_t *md2_readModel(const char *filename) md2_freeModel (model); return 0; } - - ; } // read texture coordinates @@ -334,8 +349,6 @@ static md2_model_t *md2_readModel(const char *filename) md2_freeModel (model); return 0; } - - } // read triangles From 561a0fe76880455a97079a4a171c1cefad7fc70c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 3 Nov 2016 21:06:23 +0000 Subject: [PATCH 079/207] Attempt loading of an MD2 only once; if we failed then don't bother again This keeps my new error messages from flooding the console and log.txt --- src/hardware/hw_md2.c | 5 +++++ src/hardware/hw_md2.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8e2b9a5b..2fcf252d 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -782,6 +782,7 @@ void HWR_InitMD2(void) md2_playermodels[s].grpatch = NULL; md2_playermodels[s].skin = -1; md2_playermodels[s].notfound = true; + md2_playermodels[s].error = false; } for (i = 0; i < NUMSPRITES; i++) { @@ -790,6 +791,7 @@ void HWR_InitMD2(void) md2_models[i].grpatch = NULL; md2_models[i].skin = -1; md2_models[i].notfound = true; + md2_models[s].error = false; } // read the md2.dat file @@ -1282,6 +1284,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else md2 = &md2_models[spr->mobj->sprite]; + if (md2->error) + return; // we already failed loading this before :( if (!md2->model) { //CONS_Debug(DBG_RENDER, "Loading MD2... (%s)", sprnames[spr->mobj->sprite]); @@ -1295,6 +1299,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { //CONS_Debug(DBG_RENDER, " FAILED\n"); + md2->error = true; // prevent endless fail return; } } diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 36078268..5a7e6d2b 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -123,6 +123,7 @@ typedef struct void *blendgrpatch; boolean notfound; INT32 skin; + boolean error; } md2_t; extern md2_t md2_models[NUMSPRITES]; From efe02e2a42b380003c07433d4a837e3011e732d7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 3 Nov 2016 22:53:49 +0000 Subject: [PATCH 080/207] allow triangle/frame limits too --- src/hardware/hw_md2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 2fcf252d..a578e6b7 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -319,8 +319,8 @@ static md2_model_t *md2_readModel(const char *filename) // Uncomment if these are actually needed // MD2LIMITCHECK(model->header.numSkins, MD2_MAX_SKINS, "skins") // MD2LIMITCHECK(model->header.numTexCoords, MD2_MAX_TEXCOORDS, "texture coordinates") -// MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles") -// MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames") + MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles") + MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames") MD2LIMITCHECK(model->header.numVertices, MD2_MAX_VERTICES, "vertices") #undef MD2LIMITCHECK From e245cdfcbf41fed6667565c4f4fd3568eed297cd Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Thu, 3 Nov 2016 17:30:30 -0700 Subject: [PATCH 081/207] Console with moving cursor, selections, etc --- src/console.c | 355 +++++++++++++++++++++++++++++++++------------ src/sdl/i_system.c | 104 ++----------- src/v_video.c | 76 +++++----- 3 files changed, 322 insertions(+), 213 deletions(-) diff --git a/src/console.c b/src/console.c index 02324ada..ea5999c0 100644 --- a/src/console.c +++ b/src/console.c @@ -84,13 +84,16 @@ UINT32 con_scalefactor; // text size scale factor // hold 32 last lines of input for history #define CON_MAXPROMPTCHARS 256 -#define CON_PROMPTCHAR '>' +#define CON_PROMPTCHAR '$' static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines static INT32 inputline; // current input line number static INT32 inputhist; // line number of history input line to restore -static size_t input_cx; // position in current input line +static size_t input_cur; // position of cursor in line +static size_t input_sel; // position of selection marker (I.E.: anything between this and input_cur is "selected") +static size_t input_len; // length of current line, used to bound cursor and such +// notice: input does NOT include the "$" at the start of the line. - 11/3/16 // protos. static void CON_InputInit(void); @@ -383,14 +386,10 @@ void CON_Init(void) // static void CON_InputInit(void) { - INT32 i; - // prepare the first prompt line memset(inputlines, 0, sizeof (inputlines)); - for (i = 0; i < 32; i++) - inputlines[i][0] = CON_PROMPTCHAR; inputline = 0; - input_cx = 1; + input_cur = input_sel = input_len = 0; } //====================================================================== @@ -615,6 +614,86 @@ void CON_Ticker(void) } } +// +// ---- +// +// Shortcuts for adding and deleting characters, strings, and sections +// Necessary due to moving cursor +// + +static inline void CON_InputClear(void) +{ + memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); + input_cur = input_sel = input_len = 0; +} + +static inline void CON_InputSetString(const char *c) +{ + memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); + strcpy(inputlines[inputline], c); + input_cur = input_sel = input_len = strlen(c); +} + +static inline void CON_InputAddString(const char *c) +{ + size_t csize = strlen(c); + if (input_len + csize > CON_MAXPROMPTCHARS-1) + return; + if (input_cur != input_len) + memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur); + memcpy(&inputlines[inputline][input_cur], c, csize); + input_len += csize; + input_sel = (input_cur += csize); +} + +static inline void CON_InputDelSelection(void) +{ + size_t start, end, len; + if (input_cur > input_sel) + { + start = input_sel; + end = input_cur; + } + else + { + start = input_cur; + end = input_sel; + } + len = (end - start); + + if (end != input_len) + memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-input_cur); + memset(&inputlines[inputline][input_len - len], 0, len); + + input_len -= len; + input_sel = input_cur = start; +} + +static inline void CON_InputAddChar(char c) +{ + if (input_len >= CON_MAXPROMPTCHARS-1) + return; + if (input_cur != input_len) + memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur); + inputlines[inputline][input_cur++] = c; + inputlines[inputline][++input_len] = 0; + input_sel = input_cur; +} + +static inline void CON_InputDelChar(void) +{ + if (!input_cur) + return; + if (input_cur != input_len) + memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur); + inputlines[inputline][--input_len] = 0; + input_sel = --input_cur; +} + +// +// ---- +// + // Handles console key input // boolean CON_Responder(event_t *ev) @@ -689,12 +768,16 @@ boolean CON_Responder(event_t *ev) // show all cvars/commands that match what we have inputted if (key == KEY_TAB) { - size_t i, len = strlen(inputlines[inputline]+1); + size_t i, len; - if (input_cx < 2 || len >= 80 || strchr(inputlines[inputline]+1, ' ')) - return true; - - strcpy(completion, inputlines[inputline]+1); + if (!completion[0]) + { + if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' ')) + return true; + strcpy(completion, inputlines[inputline]); + comskips = varskips = 0; + } + len = strlen(completion); //first check commands CONS_Printf("\nCommands:\n"); @@ -725,18 +808,38 @@ boolean CON_Responder(event_t *ev) if (key == 'x' || key == 'X') { - CONS_Printf("Cut\n"); + if (input_sel > input_cur) + I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); + else + I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); + CON_InputDelSelection(); + completion[0] = 0; return true; } else if (key == 'c' || key == 'C') { - CONS_Printf("Copy\n"); - I_ClipboardCopy(inputlines[inputline]+1, strlen(inputlines[inputline]+1)); + if (input_sel > input_cur) + I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); + else + I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); return true; } else if (key == 'v' || key == 'V') { - CONS_Printf("Paste: %s\n", I_ClipboardPaste()); + const char *paste = I_ClipboardPaste(); + if (input_sel != input_cur) + CON_InputDelSelection(); + if (paste != NULL) + CON_InputAddString(paste); + completion[0] = 0; + return true; + } + + // Select all + if (key == 'a' || key == 'A') + { + input_sel = 0; + input_cur = input_len; return true; } @@ -750,13 +853,11 @@ boolean CON_Responder(event_t *ev) // sequential command completion forward and backward // remember typing for several completions (a-la-4dos) - if (inputlines[inputline][input_cx-1] != ' ') + if (!completion[0]) { - if (strlen(inputlines[inputline]+1) < 80) - strcpy(completion, inputlines[inputline]+1); - else - completion[0] = 0; - + if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' ')) + return true; + strcpy(completion, inputlines[inputline]); comskips = varskips = 0; } else @@ -768,37 +869,26 @@ boolean CON_Responder(event_t *ev) if (--varskips < 0) comskips = -comskips - 2; } - else if (comskips > 0) - comskips--; + else if (comskips > 0) comskips--; } else { - if (comskips < 0) - varskips++; - else - comskips++; + if (comskips < 0) varskips++; + else comskips++; } } if (comskips >= 0) { cmd = COM_CompleteCommand(completion, comskips); - if (!cmd) - // dirty: make sure if comskips is zero, to have a neg value + if (!cmd) // dirty: make sure if comskips is zero, to have a neg value comskips = -comskips - 1; } if (comskips < 0) cmd = CV_CompleteVar(completion, varskips); if (cmd) - { - memset(inputlines[inputline]+1, 0, CON_MAXPROMPTCHARS-1); - strcpy(inputlines[inputline]+1, cmd); - input_cx = strlen(cmd) + 1; - inputlines[inputline][input_cx] = ' '; - input_cx++; - inputlines[inputline][input_cx] = 0; - } + CON_InputSetString(va("%s ", cmd)); else { if (comskips > 0) @@ -824,38 +914,80 @@ boolean CON_Responder(event_t *ev) return true; } + if (key == KEY_LEFTARROW) + { + if (input_cur != 0) + --input_cur; + if (!shiftdown) + input_sel = input_cur; + return true; + } + else if (key == KEY_RIGHTARROW) + { + if (input_cur < input_len) + ++input_cur; + if (!shiftdown) + input_sel = input_cur; + return true; + } + else if (key == KEY_HOME) + { + input_cur = 0; + if (!shiftdown) + input_sel = input_cur; + return true; + } + else if (key == KEY_END) + { + input_cur = input_len; + if (!shiftdown) + input_sel = input_cur; + return true; + } + // At this point we're messing with input + // Clear completion + completion[0] = 0; // command enter if (key == KEY_ENTER) { - if (input_cx < 2) + if (!input_len) return true; // push the command - COM_BufAddText(inputlines[inputline]+1); + COM_BufAddText(inputlines[inputline]); COM_BufAddText("\n"); - CONS_Printf("%s\n", inputlines[inputline]); + CONS_Printf("\x86""%c""\x80""%s\n", CON_PROMPTCHAR, inputlines[inputline]); inputline = (inputline+1) & 31; inputhist = inputline; - - memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); - inputlines[inputline][0] = CON_PROMPTCHAR; - input_cx = 1; + CON_InputClear(); return true; } - // backspace command prompt - if (key == KEY_BACKSPACE) + // backspace and delete command prompt + if (input_sel != input_cur) { - if (input_cx > 1) + if (key == KEY_BACKSPACE || key == KEY_DEL) { - input_cx--; - inputlines[inputline][input_cx] = 0; + CON_InputDelSelection(); + return true; } + } + else if (key == KEY_BACKSPACE) + { + CON_InputDelChar(); + return true; + } + else if (key == KEY_DEL) + { + if (input_cur == input_len) + return true; + ++input_cur; + CON_InputDelChar(); return true; } @@ -864,18 +996,15 @@ boolean CON_Responder(event_t *ev) { // copy one of the previous inputlines to the current do - { inputhist = (inputhist - 1) & 31; // cycle back - } while (inputhist != inputline && !inputlines[inputhist][1]); + while (inputhist != inputline && !inputlines[inputhist][0]); // stop at the last history input line, which is the // current line + 1 because we cycle through the 32 input lines if (inputhist == inputline) inputhist = (inputline + 1) & 31; - M_Memcpy(inputlines[inputline], inputlines[inputhist], CON_MAXPROMPTCHARS); - input_cx = strlen(inputlines[inputline]); - + CON_InputSetString(inputlines[inputhist]); return true; } @@ -885,23 +1014,14 @@ boolean CON_Responder(event_t *ev) if (inputhist == inputline) return true; do - { inputhist = (inputhist + 1) & 31; - } while (inputhist != inputline && !inputlines[inputhist][1]); - - memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); + while (inputhist != inputline && !inputlines[inputhist][0]); // back to currentline if (inputhist == inputline) - { - inputlines[inputline][0] = CON_PROMPTCHAR; - input_cx = 1; - } + CON_InputClear(); else - { - strcpy(inputlines[inputline], inputlines[inputhist]); - input_cx = strlen(inputlines[inputline]); - } + CON_InputSetString(inputlines[inputhist]); return true; } @@ -926,15 +1046,12 @@ boolean CON_Responder(event_t *ev) return false; // add key to cmd line here - if (input_cx < CON_MAXPROMPTCHARS) - { - if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers - key = key + 'a' - 'A'; + if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers + key = key + 'a' - 'A'; - inputlines[inputline][input_cx] = (char)key; - inputlines[inputline][input_cx + 1] = 0; - input_cx++; - } + if (input_sel != input_cur) + CON_InputDelSelection(); + CON_InputAddChar(key); return true; } @@ -1218,26 +1335,84 @@ void CONS_Error(const char *msg) // static void CON_DrawInput(void) { - char *p; - size_t c; - INT32 x, y; INT32 charwidth = (INT32)con_scalefactor << 3; - - // input line scrolls left if it gets too long - p = inputlines[inputline]; - if (input_cx >= con_width-11) - p += input_cx - (con_width-11) + 1; + const char *p = inputlines[inputline]; + size_t c, clen, cend; + UINT8 lellip = 0, rellip = 0; + INT32 x, y, i; y = con_curlines - 12 * con_scalefactor; + x = charwidth*2; - for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + clen = con_width-12; - // draw the blinking cursor - // - x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); - if (con_tick < 4) - V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + if (input_len <= clen) + { + c = 0; + clen = input_len; + } + else // input line scrolls left if it gets too long + { + clen -= 2; // There will always be some extra truncation -- but where is what we'll find out + + if (input_cur <= clen/2) + { + // Close enough to right edge to show all + c = 0; + // Always will truncate right side from this position, so always draw right ellipsis + rellip = 1; + } + else + { + // Cursor in the middle (or right side) of input + // Move over for the ellipsis + c = input_cur - (clen/2) + 2; + x += charwidth*2; + lellip = 1; + + if (c + clen >= input_len) + { + // Cursor in the right side of input + // We were too far over, so move back + c = input_len - clen; + } + else + { + // Cursor in the middle -- ellipses on both sides + clen -= 2; + rellip = 1; + } + } + } + + if (lellip) + { + for (i = 0, x -= charwidth*3; i < 3; ++i, x += charwidth) + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + } + else + V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + + for (cend = c + clen; c < cend; ++c, x += charwidth) + { + if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c)) + { + V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 107 | V_NOSCALESTART); + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value); + } + else + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + + if (c == input_cur && con_tick >= 4) + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + } + if (cend == input_cur && con_tick >= 4) + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + if (rellip) + { + for (i = 0; i < 3; ++i, x += charwidth) + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + } } // draw the last lines of console text to the top of the screen diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 8c4331aa..71ee3f79 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -260,18 +260,6 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif -// FAKE_CLIPBOARD simulates system clipboard, but is just local to our app -#ifndef FAKE_CLIPBOARD -#include "SDL_syswm.h" - -#if defined (_WIN32) && !defined (_XBOX) -#include -#endif - -// TODO: clipboard support for other OSes - -#endif - /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2659,86 +2647,30 @@ INT32 I_PutEnv(char *variable) #endif } -#ifdef FAKE_CLIPBOARD -static char __clipboard[512] = ""; -#endif - INT32 I_ClipboardCopy(const char *data, size_t size) { -#ifdef FAKE_CLIPBOARD - if (size >= 512) size = 511; - memcpy(__clipboard, data, size); - __clipboard[size] = 0; - return 0; -#else // !FAKE_CLIPBOARD + char storage[256]; + if (size > 255) + size = 255; + memcpy(storage, data, size); + storage[size] = 0; -#if defined(_WIN32) && !defined(_XBOX) - SDL_SysWMinfo syswm; - HGLOBAL *storage_ptr; - char *storage_raw; - - SDL_VERSION(&syswm.version); - - // Get window (HWND) information, use that to open the clipboard - if (!SDL_GetWindowWMInfo(window, &syswm) || !(OpenClipboard(syswm.info.win.window))) - return -1; - - // Erase clipboard contents -- if we have nothing to copy, just leave them blank - EmptyClipboard(); - if (size == 0) - goto clipboardend; - - // Allocate movable global memory to store our text. - if (!(storage_ptr = GlobalAlloc(GMEM_MOVEABLE, size+1)) - || !(storage_raw = (char *)GlobalLock(storage_ptr))) // Lock our pointer (gives us access to its data) - goto clipboardfail; - memcpy(storage_raw, data, size); - storage_raw[size] = 0; - GlobalUnlock(storage_ptr); // Unlock it before sending it off - if (!SetClipboardData(CF_TEXT, storage_ptr)) // NOTE: this removes our permissions from the pointer - goto clipboardfail; - -clipboardend: - CloseClipboard(); - return 0; //OpenClipboard(); -clipboardfail: - CloseClipboard(); // Don't leave me hanging + if (SDL_SetClipboardText(storage)) + return 0; return -1; -#else - (void)data; - (void)size; - return -1; -#endif - -#endif // FAKE_CLIPBOARD } const char *I_ClipboardPaste(void) { -#ifdef FAKE_CLIPBOARD - return (const char *)&__clipboard; -#else // !FAKE_CLIPBOARD + static char clipboard_modified[256]; + char *clipboard_contents, *i = clipboard_modified; -#if defined(_WIN32) && !defined(_XBOX) - HGLOBAL *clipboard_ptr; - const char *clipboard_raw; - static char clipboard_contents[512]; - char *i = clipboard_contents; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return NULL; // Data either unavailable, or in wrong format - OpenClipboard(NULL); // NOTE: Don't need window pointer to get, only to set - if (!(clipboard_ptr = GetClipboardData(CF_TEXT))) // Get global pointer + if (!SDL_HasClipboardText()) return NULL; - if (!(clipboard_raw = (const char *)GlobalLock(clipboard_ptr))) // Lock access -- gives us direct ptr to data - { - CloseClipboard(); // Don't leave me hanging if we fail - return NULL; - } - memcpy(clipboard_contents, clipboard_raw, 511); - GlobalUnlock(clipboard_ptr); // Unlock for other apps - CloseClipboard(); // And make sure to close the clipboard for other apps too - clipboard_contents[511] = 0; // Done after unlock to cause as little interference as possible + clipboard_contents = SDL_GetClipboardText(); + memcpy(clipboard_modified, clipboard_contents, 255); + SDL_free(clipboard_contents); + clipboard_modified[255] = 0; while (*i) { @@ -2753,13 +2685,7 @@ const char *I_ClipboardPaste(void) *i = '?'; // Nonprintable chars become question marks ++i; } - - return (const char *)&clipboard_contents; -#else - return NULL; -#endif - -#endif // FAKE_CLIPBOARD + return (const char *)&clipboard_modified; } /** \brief The isWadPathOk function diff --git a/src/v_video.c b/src/v_video.c index 43e3f018..f6a966e6 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -774,43 +774,51 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) if (!screens[0]) return; - if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) - { // Clear the entire screen, from dest to deststop. Yes, this really works. - memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); - return; - } - - dest = screens[0] + y*dupy*vid.width + x*dupx; - deststop = screens[0] + vid.rowbytes * vid.height; - - if (w == BASEVIDWIDTH) - w = vid.width; - else - w *= dupx; - if (h == BASEVIDHEIGHT) - h = vid.height; - else - h *= dupy; - - if (x && y && x + w < vid.width && y + h < vid.height) + if (c & V_NOSCALESTART) { - // Center it if necessary - if (vid.width != BASEVIDWIDTH * dupx) - { - // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, - // so center this imaginary screen - if (c & V_SNAPTORIGHT) - dest += (vid.width - (BASEVIDWIDTH * dupx)); - else if (!(c & V_SNAPTOLEFT)) - dest += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + dest = screens[0] + y*vid.width + x; + deststop = screens[0] + vid.rowbytes * vid.height; + } + else + { + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { // Clear the entire screen, from dest to deststop. Yes, this really works. + memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); + return; } - if (vid.height != BASEVIDHEIGHT * dupy) + + dest = screens[0] + y*dupy*vid.width + x*dupx; + deststop = screens[0] + vid.rowbytes * vid.height; + + if (w == BASEVIDWIDTH) + w = vid.width; + else + w *= dupx; + if (h == BASEVIDHEIGHT) + h = vid.height; + else + h *= dupy; + + if (x && y && x + w < vid.width && y + h < vid.height) { - // same thing here - if (c & V_SNAPTOBOTTOM) - dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; - else if (!(c & V_SNAPTOTOP)) - dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; + // Center it if necessary + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (c & V_SNAPTORIGHT) + dest += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(c & V_SNAPTOLEFT)) + dest += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (c & V_SNAPTOBOTTOM) + dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; + else if (!(c & V_SNAPTOTOP)) + dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; + } } } From 010c52aed2ad0e4ee0f38a1fcfa42b6a6bf671f0 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Thu, 3 Nov 2016 19:36:43 -0700 Subject: [PATCH 082/207] show highlight BG over ellipses if highlight extends offscreen + bug fixes --- src/console.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/console.c b/src/console.c index ea5999c0..e0619097 100644 --- a/src/console.c +++ b/src/console.c @@ -662,7 +662,7 @@ static inline void CON_InputDelSelection(void) len = (end - start); if (end != input_len) - memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-input_cur); + memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-end); memset(&inputlines[inputline][input_len - len], 0, len); input_len -= len; @@ -720,12 +720,6 @@ boolean CON_Responder(event_t *ev) key = ev->data1; - // Always eat ctrl/shift/alt, so the menu doesn't get ideas - if (key == KEY_LSHIFT || key == KEY_RSHIFT - || key == KEY_LCTRL || key == KEY_RCTRL - || key == KEY_LALT || key == KEY_RALT) - return true; - // check for console toggle key if (ev->type != ev_console) { @@ -759,9 +753,14 @@ boolean CON_Responder(event_t *ev) consoletoggle = true; return true; } - } + // Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas + if (key == KEY_LSHIFT || key == KEY_RSHIFT + || key == KEY_LCTRL || key == KEY_RCTRL + || key == KEY_LALT || key == KEY_RALT) + return true; + // ctrl modifier -- changes behavior, adds shortcuts if (ctrldown) { @@ -1344,7 +1343,7 @@ static void CON_DrawInput(void) y = con_curlines - 12 * con_scalefactor; x = charwidth*2; - clen = con_width-12; + clen = con_width-13; if (input_len <= clen) { @@ -1387,7 +1386,10 @@ static void CON_DrawInput(void) if (lellip) { - for (i = 0, x -= charwidth*3; i < 3; ++i, x += charwidth) + x -= charwidth*3; + if (input_sel < c) + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); + for (i = 0; i < 3; ++i, x += charwidth) V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); } else @@ -1410,6 +1412,8 @@ static void CON_DrawInput(void) V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); if (rellip) { + if (input_sel > cend) + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); } From 55400a262d3cb0f29cdb51d1c4d2a7da93a91da8 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Fri, 4 Nov 2016 02:02:26 -0700 Subject: [PATCH 083/207] go fuck yourself stupid compiler ...your guesses should not be treated as errors. --- src/console.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/console.c b/src/console.c index e0619097..70f8ab6f 100644 --- a/src/console.c +++ b/src/console.c @@ -621,20 +621,20 @@ void CON_Ticker(void) // Necessary due to moving cursor // -static inline void CON_InputClear(void) +static void CON_InputClear(void) { memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); input_cur = input_sel = input_len = 0; } -static inline void CON_InputSetString(const char *c) +static void CON_InputSetString(const char *c) { memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); strcpy(inputlines[inputline], c); input_cur = input_sel = input_len = strlen(c); } -static inline void CON_InputAddString(const char *c) +static void CON_InputAddString(const char *c) { size_t csize = strlen(c); if (input_len + csize > CON_MAXPROMPTCHARS-1) @@ -646,7 +646,7 @@ static inline void CON_InputAddString(const char *c) input_sel = (input_cur += csize); } -static inline void CON_InputDelSelection(void) +static void CON_InputDelSelection(void) { size_t start, end, len; if (input_cur > input_sel) @@ -669,7 +669,7 @@ static inline void CON_InputDelSelection(void) input_sel = input_cur = start; } -static inline void CON_InputAddChar(char c) +static void CON_InputAddChar(char c) { if (input_len >= CON_MAXPROMPTCHARS-1) return; @@ -680,7 +680,7 @@ static inline void CON_InputAddChar(char c) input_sel = input_cur; } -static inline void CON_InputDelChar(void) +static void CON_InputDelChar(void) { if (!input_cur) return; From 6f4699fb7766a21d729b9af5a0f812694a16c4e3 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 4 Nov 2016 18:56:25 +0100 Subject: [PATCH 084/207] MobjThinker, MobjCollide and MobjMoveCollide hooks are now directly linked to the mobjtype they belong to, so you no longer iterate through all existing hooks. --- src/lua_hooklib.c | 118 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 16 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1b965257..5d9c5062 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -74,12 +74,21 @@ typedef struct hook_s* hook_p; #define FMT_HOOKID "hook_%d" +// For each mobj type, a linked list to its thinker and collision hooks. +// That way, we don't have to iterate through all the hooks. +// We could do that with all other mobj hooks, but it would probably just be +// a waste of memory since they are only called occasionally. Probably... +static hook_p mobjthinkerhooks[NUMMOBJTYPES]; +static hook_p mobjcollidehooks[NUMMOBJTYPES]; + +// For other hooks, a unique linked list hook_p roothook; // Takes hook, function, and additional arguments (mobj type to act on, etc.) static int lib_addHook(lua_State *L) { static struct hook_s hook = {NULL, 0, 0, {0}, false}; + static UINT32 nextid; hook_p hookp, *lastp; hook.type = luaL_checkoption(L, 1, NULL, hookNames); @@ -109,6 +118,7 @@ static int lib_addHook(lua_State *L) hook.s.mt = MT_NULL; if (lua_isnumber(L, 2)) hook.s.mt = lua_tonumber(L, 2); + luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t"); break; case hook_BotAI: hook.s.skinname = NULL; @@ -141,18 +151,21 @@ static int lib_addHook(lua_State *L) hooksAvailable[hook.type/8] |= 1<<(hook.type%8); - // iterate the hook metadata structs // set hook.id to the highest id + 1 - // set lastp to the last hook struct's "next" pointer. - lastp = &roothook; - hook.id = 0; - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->id >= hook.id) - hook.id = hookp->id+1; - lastp = &hookp->next; - } + hook.id = nextid++; + // Special cases for mobj thinker and collision hooks (see the comments above mobjthinkerhooks declaration) + if (hook.type == hook_MobjThinker) + lastp = &mobjthinkerhooks[hook.s.mt]; + else if (hook.type == hook_MobjCollide || hook.type == hook_MobjMoveCollide) + lastp = &mobjcollidehooks[hook.s.mt]; + else + lastp = &roothook; + + // iterate the hook metadata structs + // set lastp to the last hook struct's "next" pointer. + for (hookp = *lastp; hookp; hookp = hookp->next) + lastp = &hookp->next; // allocate a permanent memory struct to stuff hook. hookp = ZZ_Alloc(sizeof(struct hook_s)); memcpy(hookp, &hook, sizeof(struct hook_s)); @@ -183,9 +196,9 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == which - && (hookp->s.mt == MT_NULL || hookp->s.mt == mo->type)) + if (which == hook_MobjThinker) // Alternate list for mobj thinkers + { + for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) { if (lua_gettop(gL) == 0) LUA_PushUserdata(gL, mo, META_MOBJ); @@ -204,6 +217,50 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) lua_pop(gL, 1); } + // Look for all generic mobj thinker hooks + for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) + { + if (lua_gettop(gL) == 0) + LUA_PushUserdata(gL, mo, META_MOBJ); + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + } + else + { + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == which + && (hookp->s.mt == MT_NULL || hookp->s.mt == mo->type)) + { + if (lua_gettop(gL) == 0) + LUA_PushUserdata(gL, mo, META_MOBJ); + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + } + lua_settop(gL, 0); return hooked; } @@ -338,9 +395,38 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == which - && (hookp->s.mt == MT_NULL || hookp->s.mt == thing1->type)) + for (hookp = mobjcollidehooks[thing1->type]; hookp; hookp = hookp->next) + if (hookp->type == which) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, thing1, META_MOBJ); + LUA_PushUserdata(gL, thing2, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { // if nil, leave shouldCollide = 0. + if (lua_toboolean(gL, -1)) + shouldCollide = 1; // Force yes + else + shouldCollide = 2; // Force no + } + lua_pop(gL, 1); + } + + // Look for all generic mobj collision hooks + for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == which) { if (lua_gettop(gL) == 0) { From 8909b7c27b16b49bba54e74f3a90ea7e3ce08205 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 5 Nov 2016 17:38:36 +0000 Subject: [PATCH 085/207] Change >= to >, I THINK having exactly 4096 vertices is safe? --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index a578e6b7..ca24b76d 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -309,7 +309,7 @@ static md2_model_t *md2_readModel(const char *filename) model->header.numSkins = 1; #define MD2LIMITCHECK(field, max, msgname) \ - if (field >= max) \ + if (field > max) \ { \ CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \ md2_freeModel (model); \ From 2dfb841c381ded5f5da6fcdc495fce4b16ae25e0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 6 Nov 2016 17:50:04 +0000 Subject: [PATCH 086/207] Correcting slight mistake I made --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index ca24b76d..4ec2e346 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -791,7 +791,7 @@ void HWR_InitMD2(void) md2_models[i].grpatch = NULL; md2_models[i].skin = -1; md2_models[i].notfound = true; - md2_models[s].error = false; + md2_models[i].error = false; } // read the md2.dat file From 93c9841360c38c5cee4665aa418a34e5cdabf642 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 6 Nov 2016 15:11:02 -0500 Subject: [PATCH 087/207] move Windows zlib options out of PNG to ZLIB --- src/win32/Makefile.cfg | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index f309f7db..99b8bc9b 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -85,13 +85,21 @@ endif OBJS=$(OBJDIR)/dx_error.o $(OBJDIR)/fabdxlib.o $(OBJDIR)/win_vid.o $(OBJDIR)/win_dll.o endif + +ZLIB_CFLAGS?=-I../libs/zlib +ifdef MINGW64 +ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz64 +else +ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz32 +endif + ifndef NOPNG ifndef PNG_CONFIG - PNG_CFLAGS?=-I../libs/libpng-src -I../libs/zlib + PNG_CFLAGS?=-I../libs/libpng-src ifdef MINGW64 - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng64 -L../libs/zlib/win32 -lz64 + PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng64 else - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng32 -L../libs/zlib/win32 -lz32 + PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng32 endif #MINGW64 endif #PNG_CONFIG endif #NOPNG From b9b5d203003ee2301f0ed2fc3919437cac4ef1b3 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 13 Nov 2016 17:34:53 -0500 Subject: [PATCH 088/207] Makefile: move ZLIB flags outside of GME check --- src/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index b83b201e..49379682 100644 --- a/src/Makefile +++ b/src/Makefile @@ -318,9 +318,6 @@ LIBS+=$(PNG_LDFLAGS) CFLAGS+=$(PNG_CFLAGS) endif -ifdef HAVE_LIBGME -OPTS+=-DHAVE_LIBGME - ZLIB_PKGCONFIG?=zlib ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) @@ -328,6 +325,9 @@ ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) LIBS+=$(ZLIB_LDFLAGS) CFLAGS+=$(ZLIB_CFLAGS) +ifdef HAVE_LIBGME +OPTS+=-DHAVE_LIBGME + LIBGME_PKGCONFIG?=libgme LIBGME_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --cflags) LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs) From 0726dbe0185e573335c7d4f280361093165021b7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 15 Nov 2016 20:33:07 +0000 Subject: [PATCH 089/207] Started work on making HWR_DrawFill support V_NOSCALESTART properly ...so far I've got the console text select highlight in the right place outside of 320x200 (and 320x200 is still fine), but for whatever reason it's too large in width and height Oh well, we're part of the way there, anyway --- src/hardware/hw_draw.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 60183b58..c2d8dfdb 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -656,6 +656,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { FOutVector v[4]; FSurfaceInfo Surf; + float sdupx, sdupy, pdupx, pdupy; if (w < 0 || h < 0) return; // consistency w/ software @@ -664,10 +665,18 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) // | /| // |/ | // 0--1 - v[0].x = v[3].x = (x - 160.0f)/160.0f; - v[2].x = v[1].x = ((x+w) - 160.0f)/160.0f; - v[0].y = v[1].y = -(y - 100.0f)/100.0f; - v[2].y = v[3].y = -((y+h) - 100.0f)/100.0f; + sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; + sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; + pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; + pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; + + if (color & V_NOSCALESTART) + sdupx = sdupy = 2.0f; + + v[0].x = v[3].x = (x*sdupx)/vid.width - 1; + v[2].x = v[1].x = (x*sdupx + w*pdupx)/vid.width - 1; + v[0].y = v[1].y = 1-(y*sdupy)/vid.height; + v[2].y = v[3].y = 1-(y*sdupy + h*pdupy)/vid.height; //Hurdler: do we still use this argb color? if not, we should remove it v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; From 42f985cda537d769bbee6331aa2879daa3095e02 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 16 Nov 2016 12:10:56 +0000 Subject: [PATCH 090/207] Remove pdupx/y and just use sdupx/y for everything, thanks Inuyasha --- src/hardware/hw_draw.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c2d8dfdb..f23753ee 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -656,7 +656,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { FOutVector v[4]; FSurfaceInfo Surf; - float sdupx, sdupy, pdupx, pdupy; + float sdupx, sdupy; if (w < 0 || h < 0) return; // consistency w/ software @@ -667,16 +667,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) // 0--1 sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; - pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; if (color & V_NOSCALESTART) sdupx = sdupy = 2.0f; v[0].x = v[3].x = (x*sdupx)/vid.width - 1; - v[2].x = v[1].x = (x*sdupx + w*pdupx)/vid.width - 1; + v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; v[0].y = v[1].y = 1-(y*sdupy)/vid.height; - v[2].y = v[3].y = 1-(y*sdupy + h*pdupy)/vid.height; + v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height; //Hurdler: do we still use this argb color? if not, we should remove it v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; From f5f25428499698d70adaa2f31ff8a471216e1e3f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 16 Nov 2016 17:50:44 +0000 Subject: [PATCH 091/207] Go through all the polyobjects to find leftover polyobj planes to add to the draw nodes list I'm convinced there's going to be some stupid side effects from doing this, but it's the quickest way I can fix the polyobj planes not all appearing anyway --- src/r_things.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index ed1ddeab..927217c5 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1760,6 +1760,29 @@ static void R_CreateDrawNodes(void) } } +#ifdef POLYOBJECTS_PLANES + // find all the remaining polyobject planes and add them on the end of the list + // probably this is a terrible idea if we wanted them to be sorted properly + // but it works getting them in for now + for (i = 0; i < numPolyObjects; i++) + { + if (!PolyObjects[i].visplane) + continue; + plane = PolyObjects[i].visplane; + R_PlaneBounds(plane); + + if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low) + { + PolyObjects[i].visplane = NULL; + continue; + } + entry = R_CreateDrawNode(&nodehead); + entry->plane = plane; + // note: no seg is set, for what should be obvious reasons + PolyObjects[i].visplane = NULL; + } +#endif + if (visspritecount == 0) return; @@ -1816,13 +1839,16 @@ static void R_CreateDrawNodes(void) if (x1 < r2->plane->minx) x1 = r2->plane->minx; if (x2 > r2->plane->maxx) x2 = r2->plane->maxx; - for (i = x1; i <= x2; i++) + if (r2->seg) // if no seg set, assume the whole thing is in front or something stupid { - if (r2->seg->frontscale[i] > rover->scale) - break; + for (i = x1; i <= x2; i++) + { + if (r2->seg->frontscale[i] > rover->scale) + break; + } + if (i > x2) + continue; } - if (i > x2) - continue; entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; From f4705b01f4be780d877314a170f661c26ad327d8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 21 Nov 2016 19:42:39 +0000 Subject: [PATCH 092/207] Don't call SDLESSet Turns out sdl12's version of this function only did stuff for DC/GP2X ports; support for them have been cut out for SDL2, so for now let's just not use the function at all --- src/sdl/i_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 71baca51..95d2a0ab 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1494,10 +1494,12 @@ void VID_PrepareModeList(void) #endif } +#if 0 static inline void SDLESSet(void) { SDL2STUB(); } +#endif INT32 VID_SetMode(INT32 modeNum) { @@ -1718,7 +1720,7 @@ void I_StartupGraphics(void) borderlesswindow = M_CheckParm("-borderless"); //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); - SDLESSet(); + //SDLESSet(); // unused VID_Command_ModeList_f(); #ifdef HWRENDER if (M_CheckParm("-opengl") || rendermode == render_opengl) From 168f8d5c5eb9d2ff517169632289265bbbb29a70 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 21 Nov 2016 20:40:02 +0000 Subject: [PATCH 093/207] Un-stub Surfaceinfo and just print the parts that still work in SDL2 This means the console command vid_info also works properly too now (well, it does nothing in OpenGL mind) --- src/sdl/i_video.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 95d2a0ab..70396e0c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -434,13 +434,8 @@ static void VID_Command_NumModes_f (void) static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) { -#if 1 - (void)infoSurface; - (void)SurfaceText; - SDL2STUB(); -#else INT32 vfBPP; - const SDL_Surface *VidSur = SDL_GetVideoSurface(); + //const SDL_Surface *VidSur = SDL_GetVideoSurface(); // SDL2 doesn't have this if (!infoSurface) return; @@ -453,15 +448,16 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) CONS_Printf("\x82" "%s\n", SurfaceText); CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP); + /* if (infoSurface->flags&SDL_HWSURFACE) CONS_Printf("%s", M_GetText(" Stored in video memory\n")); else if (infoSurface->flags&SDL_OPENGL) CONS_Printf("%s", M_GetText(" Stored in an OpenGL context\n")); - else if (infoSurface->flags&SDL_PREALLOC) + else */if (infoSurface->flags&SDL_PREALLOC) CONS_Printf("%s", M_GetText(" Uses preallocated memory\n")); else CONS_Printf("%s", M_GetText(" Stored in system memory\n")); - +/* if (infoSurface->flags&SDL_ASYNCBLIT) CONS_Printf("%s", M_GetText(" Uses asynchronous blits if possible\n")); else @@ -491,11 +487,13 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) CONS_Printf("%s", M_GetText(" Uses hardware acceleration blit\n")); if (infoSurface->flags&SDL_SRCCOLORKEY) CONS_Printf("%s", M_GetText(" Use colorkey blitting\n")); +*/ if (infoSurface->flags&SDL_RLEACCEL) CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); +/* if (infoSurface->flags&SDL_SRCALPHA) CONS_Printf("%s", M_GetText(" Use alpha blending acceleration blit\n")); -#endif +*/ } static void VID_Command_Info_f (void) From 208546165baf2b28803ff0114f22f676c806ddfc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 21 Nov 2016 20:59:44 +0000 Subject: [PATCH 094/207] Comment out SDL2STUB from Impl_SetWindowIcon --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 70396e0c..6ddfc391 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1620,7 +1620,7 @@ static void Impl_SetWindowIcon(void) { return; } - SDL2STUB(); + //SDL2STUB(); // Monster Iestyn: why is this stubbed? SDL_SetWindowIcon(window, icoSurface); } From 1606a45b186d340b7d800322dcd83a1e0531e433 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 21 Nov 2016 22:07:05 +0000 Subject: [PATCH 095/207] Some cleanup/reorganisation in SDLSetMode and Impl_CreateWindow --- src/sdl/i_video.c | 67 +++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 6ddfc391..791d0752 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -189,14 +189,14 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) wasfullscreen = SDL_TRUE; SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); } - else if (!fullscreen && wasfullscreen) + else if (wasfullscreen) { wasfullscreen = SDL_FALSE; SDL_SetWindowFullscreen(window, 0); SDL_SetWindowSize(window, width, height); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1)); } - else if (!wasfullscreen) + else { // Reposition window only in windowed mode SDL_SetWindowSize(window, width, height); @@ -1550,6 +1550,12 @@ INT32 VID_SetMode(INT32 modeNum) static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) { int flags = 0; + + if (rendermode == render_none) // dedicated + { + return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh + } + if (window != NULL) { return SDL_FALSE; @@ -1568,38 +1574,43 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #ifdef HWRENDER if (rendermode == render_opengl) { - window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - realwidth, realheight, flags | SDL_WINDOW_OPENGL); - if (window != NULL) - { - sdlglcontext = SDL_GL_CreateContext(window); - if (sdlglcontext == NULL) - { - SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); - } - else - { - SDL_GL_MakeCurrent(window, sdlglcontext); - } - } - else return SDL_FALSE; + flags |= SDL_WINDOW_OPENGL; } #endif + + // Create a window + window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + realwidth, realheight, flags); + + if (window == NULL) + { + CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError()); + return SDL_FALSE; + } + + // Renderer-specific stuff +#ifdef HWRENDER + if (rendermode == render_opengl) + { + sdlglcontext = SDL_GL_CreateContext(window); + if (sdlglcontext == NULL) + { + SDL_DestroyWindow(window); + I_Error("Failed to create a GL context: %s\n", SDL_GetError()); + } + SDL_GL_MakeCurrent(window, sdlglcontext); + } + else +#endif if (rendermode == render_soft) { - window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - realwidth, realheight, flags); - if (window != NULL) + renderer = SDL_CreateRenderer(window, -1, (usesdl2soft ? SDL_RENDERER_SOFTWARE : 0) | (cv_vidwait.value && !usesdl2soft ? SDL_RENDERER_PRESENTVSYNC : 0)); + if (renderer == NULL) { - renderer = SDL_CreateRenderer(window, -1, (usesdl2soft ? SDL_RENDERER_SOFTWARE : 0) | (cv_vidwait.value && !usesdl2soft ? SDL_RENDERER_PRESENTVSYNC : 0)); - if (renderer != NULL) - { - SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); - } - else return SDL_FALSE; + CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); + return SDL_FALSE; } - else return SDL_FALSE; + SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); } return SDL_TRUE; From 153ba39f1983a20cc3ae17e5828e7702be321e34 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 22 Nov 2016 22:41:02 +0000 Subject: [PATCH 096/207] Remove remnants of SDLK_ stuff, we use scancodes now not keycodes (Apparently SDLK_LMETA/SDLK_RMETA don't exist anymore in SDL2 anyway?) --- src/sdl/i_video.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 791d0752..a7a6ed15 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -33,14 +33,6 @@ #pragma warning(default : 4214 4244) #endif -#if SDL_VERSION_ATLEAST(1,3,0) -#define SDLK_EQUALS SDLK_KP_EQUALSAS400 -#define SDLK_LMETA SDLK_LGUI -#define SDLK_RMETA SDLK_RGUI -#else -#define HAVE_SDLMETAKEYS -#endif - #ifdef HAVE_TTF #include "i_ttf.h" #endif From 5cf4767aed86e25ec401e33cc7a35e6f5a10148b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 23 Nov 2016 16:51:37 +0000 Subject: [PATCH 097/207] Clearing away lots of disabled code (some of it would no longer work on SDL2 anyway) --- src/sdl/i_video.c | 281 +--------------------------------------------- 1 file changed, 2 insertions(+), 279 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index a7a6ed15..5b83a881 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -424,10 +424,10 @@ static void VID_Command_NumModes_f (void) CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); } +// SDL2 doesn't have SDL_GetVideoSurface or a lot of the SDL_Surface flags that SDL 1.2 had static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) { INT32 vfBPP; - //const SDL_Surface *VidSur = SDL_GetVideoSurface(); // SDL2 doesn't have this if (!infoSurface) return; @@ -440,52 +440,12 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) CONS_Printf("\x82" "%s\n", SurfaceText); CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP); - /* - if (infoSurface->flags&SDL_HWSURFACE) - CONS_Printf("%s", M_GetText(" Stored in video memory\n")); - else if (infoSurface->flags&SDL_OPENGL) - CONS_Printf("%s", M_GetText(" Stored in an OpenGL context\n")); - else */if (infoSurface->flags&SDL_PREALLOC) + if (infoSurface->flags&SDL_PREALLOC) CONS_Printf("%s", M_GetText(" Uses preallocated memory\n")); else CONS_Printf("%s", M_GetText(" Stored in system memory\n")); -/* - if (infoSurface->flags&SDL_ASYNCBLIT) - CONS_Printf("%s", M_GetText(" Uses asynchronous blits if possible\n")); - else - CONS_Printf("%s", M_GetText(" Uses synchronous blits if possible\n")); - - if (infoSurface->flags&SDL_ANYFORMAT) - CONS_Printf("%s", M_GetText(" Allows any pixel-format\n")); - - if (infoSurface->flags&SDL_HWPALETTE) - CONS_Printf("%s", M_GetText(" Has exclusive palette access\n")); - else if (VidSur == infoSurface) - CONS_Printf("%s", M_GetText(" Has nonexclusive palette access\n")); - - if (infoSurface->flags&SDL_DOUBLEBUF) - CONS_Printf("%s", M_GetText(" Double buffered\n")); - else if (VidSur == infoSurface) - CONS_Printf("%s", M_GetText(" No hardware flipping\n")); - - if (infoSurface->flags&SDL_FULLSCREEN) - CONS_Printf("%s", M_GetText(" Full screen\n")); - else if (infoSurface->flags&SDL_RESIZABLE) - CONS_Printf("%s", M_GetText(" Resizable window\n")); - else if (VidSur == infoSurface) - CONS_Printf("%s", M_GetText(" Nonresizable window\n")); - - if (infoSurface->flags&SDL_HWACCEL) - CONS_Printf("%s", M_GetText(" Uses hardware acceleration blit\n")); - if (infoSurface->flags&SDL_SRCCOLORKEY) - CONS_Printf("%s", M_GetText(" Use colorkey blitting\n")); -*/ if (infoSurface->flags&SDL_RLEACCEL) CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); -/* - if (infoSurface->flags&SDL_SRCALPHA) - CONS_Printf("%s", M_GetText(" Use alpha blending acceleration blit\n")); -*/ } static void VID_Command_Info_f (void) @@ -569,23 +529,6 @@ static void VID_Command_Mode_f (void) setmodeneeded = modenum+1; // request vid mode change } -#if 0 -#if defined(RPC_NO_WINDOWS_H) -static VOID MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - UNREFERENCED_PARAMETER(hWnd); - UNREFERENCED_PARAMETER(message); - UNREFERENCED_PARAMETER(wParam); - switch (message) - { - case WM_SETTEXT: - COM_BufAddText((LPCSTR)lParam); - break; - } -} -#endif -#endif - static inline void SDLJoyRemap(event_t *event) { (void)event; @@ -944,218 +887,6 @@ void I_GetEvent(void) // In order to make wheels act like buttons, we have to set their state to Up. // This is because wheel messages don't have an up/down state. gamekeydown[KEY_MOUSEWHEELDOWN] = gamekeydown[KEY_MOUSEWHEELUP] = 0; - -#if 0 - SDL_Event inputEvent; - static SDL_bool sdlquit = SDL_FALSE; //Alam: once, just once - event_t event; - - if (!graphics_started) - return; - - memset(&inputEvent, 0x00, sizeof(inputEvent)); - while (SDL_PollEvent(&inputEvent)) - { - memset(&event,0x00,sizeof (event_t)); - switch (inputEvent.type) - { - case SDL_ACTIVEEVENT: - if (inputEvent.active.state & (SDL_APPACTIVE|SDL_APPINPUTFOCUS)) - { - // pause music when alt-tab - if (inputEvent.active.gain /*&& !paused */) - { - static SDL_bool firsttimeonmouse = SDL_TRUE; - if (!firsttimeonmouse) - { - if (cv_usemouse.value) I_StartupMouse(); - } - else firsttimeonmouse = SDL_FALSE; - //if (!netgame && !con_destlines) paused = false; - if (gamestate == GS_LEVEL) - if (!paused) I_ResumeSong(0); //resume it - } - else /*if (!paused)*/ - { - if (!disable_mouse) - SDLforceUngrabMouse(); - if (!netgame && gamestate == GS_LEVEL) paused = true; - memset(gamekeydown, 0, NUMKEYS); - //S_PauseSound(); - if (gamestate == GS_LEVEL) - I_PauseSong(0); //pause it - } - } - if (MOUSE_MENU) - { - SDLdoUngrabMouse(); - break; - } - if ((SDL_APPMOUSEFOCUS&inputEvent.active.state) && USE_MOUSEINPUT && inputEvent.active.gain) - HalfWarpMouse(realwidth, realheight); - break; - case SDL_KEYDOWN: - case SDL_KEYUP: - /// \todo inputEvent.key.which? - if (inputEvent.type == SDL_KEYUP) - event.type = ev_keyup; - else if (inputEvent.type == SDL_KEYDOWN) - event.type = ev_keydown; - else break; - event.data1 = SDLatekey(inputEvent.key.keysym.sym); - if (event.data1) D_PostEvent(&event); - break; - case SDL_MOUSEMOTION: - /// \todo inputEvent.motion.which - if (MOUSE_MENU) - { - SDLdoUngrabMouse(); - break; - } - //if (USE_MOUSEINPUT) TODO SDL2 stub - { - // If the event is from warping the pointer back to middle - // of the screen then ignore it. - if ((inputEvent.motion.x == realwidth/2) && - (inputEvent.motion.y == realheight/2)) - { - break; - } - else - { - event.data2 = +inputEvent.motion.xrel; - event.data3 = -inputEvent.motion.yrel; - } - event.type = ev_mouse; - D_PostEvent(&event); - // Warp the pointer back to the middle of the window - // or we cannot move any further if it's at a border. - if ((inputEvent.motion.x < (realwidth/2 )-(realwidth/4 )) || - (inputEvent.motion.y < (realheight/2)-(realheight/4)) || - (inputEvent.motion.x > (realwidth/2 )+(realwidth/4 )) || - (inputEvent.motion.y > (realheight/2)+(realheight/4) ) ) - { - //if (SDL_GRAB_ON == SDL_WM_GrabInput(SDL_GRAB_QUERY) || !mousegrabok) - HalfWarpMouse(realwidth, realheight); - } - } - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - /// \todo inputEvent.button.which - if (USE_MOUSEINPUT) - { - if (inputEvent.type == SDL_MOUSEBUTTONUP) - event.type = ev_keyup; - else if (inputEvent.type == SDL_MOUSEBUTTONDOWN) - event.type = ev_keydown; - else break; - if (inputEvent.button.button==SDL_BUTTON_WHEELUP || inputEvent.button.button==SDL_BUTTON_WHEELDOWN) - { - if (inputEvent.type == SDL_MOUSEBUTTONUP) - event.data1 = 0; //Alam: dumb! this could be a real button with some mice - else - event.data1 = KEY_MOUSEWHEELUP + inputEvent.button.button - SDL_BUTTON_WHEELUP; - } - else if (inputEvent.button.button == SDL_BUTTON_MIDDLE) - event.data1 = KEY_MOUSE1+2; - else if (inputEvent.button.button == SDL_BUTTON_RIGHT) - event.data1 = KEY_MOUSE1+1; - else if (inputEvent.button.button <= MOUSEBUTTONS) - event.data1 = KEY_MOUSE1 + inputEvent.button.button - SDL_BUTTON_LEFT; - if (event.data1) D_PostEvent(&event); - } - break; - case SDL_JOYAXISMOTION: - inputEvent.jaxis.which++; - inputEvent.jaxis.axis++; - event.data1 = event.data2 = event.data3 = INT32_MAX; - if (cv_usejoystick.value == inputEvent.jaxis.which) - { - event.type = ev_joystick; - } - else if (cv_usejoystick.value == inputEvent.jaxis.which) - { - event.type = ev_joystick2; - } - else break; - //axis - if (inputEvent.jaxis.axis > JOYAXISSET*2) - break; - //vaule - if (inputEvent.jaxis.axis%2) - { - event.data1 = inputEvent.jaxis.axis / 2; - event.data2 = SDLJoyAxis(inputEvent.jaxis.value, event.type); - } - else - { - inputEvent.jaxis.axis--; - event.data1 = inputEvent.jaxis.axis / 2; - event.data3 = SDLJoyAxis(inputEvent.jaxis.value, event.type); - } - D_PostEvent(&event); - break; - case SDL_JOYBALLMOTION: - case SDL_JOYHATMOTION: - break; //NONE - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - inputEvent.jbutton.which++; - if (cv_usejoystick.value == inputEvent.jbutton.which) - event.data1 = KEY_JOY1; - else if (cv_usejoystick.value == inputEvent.jbutton.which) - event.data1 = KEY_2JOY1; - else break; - if (inputEvent.type == SDL_JOYBUTTONUP) - event.type = ev_keyup; - else if (inputEvent.type == SDL_JOYBUTTONDOWN) - event.type = ev_keydown; - else break; - if (inputEvent.jbutton.button < JOYBUTTONS) - event.data1 += inputEvent.jbutton.button; - else - break; - SDLJoyRemap(&event); - if (event.type != ev_console) D_PostEvent(&event); - break; - case SDL_QUIT: - if (!sdlquit) - { - sdlquit = SDL_TRUE; - M_QuitResponse('y'); - } - break; -#if defined(RPC_NO_WINDOWS_H) - case SDL_SYSWMEVENT: - MainWndproc(inputEvent.syswm.msg->hwnd, - inputEvent.syswm.msg->msg, - inputEvent.syswm.msg->wParam, - inputEvent.syswm.msg->lParam); - break; -#endif - case SDL_VIDEORESIZE: - if (gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN || gamestate == GS_EVALUATION) - setmodeneeded = VID_GetModeForSize(inputEvent.resize.w,inputEvent.resize.h)+1; - if (render_soft == rendermode) - { - SDLSetMode(realwidth, realheight, vid.bpp*8, surfaceFlagsW); - if (vidSurface) SDL_SetColors(vidSurface, localPalette, 0, 256); - } - else - SDLSetMode(realwidth, realheight, vid.bpp*8, surfaceFlagsW); - if (!vidSurface) - I_Error("Could not reset vidmode: %s\n",SDL_GetError()); - break; - case SDL_VIDEOEXPOSE: - exposevideo = SDL_TRUE; - break; - default: - break; - } - } - //reset wheel like in win32, I don't understand it but works -#endif } void I_StartupMouse(void) @@ -1484,13 +1215,6 @@ void VID_PrepareModeList(void) #endif } -#if 0 -static inline void SDLESSet(void) -{ - SDL2STUB(); -} -#endif - INT32 VID_SetMode(INT32 modeNum) { SDLdoUngrabMouse(); @@ -1721,7 +1445,6 @@ void I_StartupGraphics(void) borderlesswindow = M_CheckParm("-borderless"); //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); - //SDLESSet(); // unused VID_Command_ModeList_f(); #ifdef HWRENDER if (M_CheckParm("-opengl") || rendermode == render_opengl) From 8bbbeff2a9910fb5b57750a35a65d8e24b1cc387 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 23 Nov 2016 17:08:37 +0000 Subject: [PATCH 098/207] Make Impl_SDL_Scancode_To_Keycode look a bit neater This way it's easier by eye to see from the list which SDL scancode maps to which SRB2 key code --- src/sdl/i_video.c | 181 ++++++++++++++++------------------------------ 1 file changed, 61 insertions(+), 120 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5b83a881..aa572e6e 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -274,129 +274,70 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) } switch (code) { - case SDL_SCANCODE_F11: // F11 and F12 are - return KEY_F11; // separated from the - case SDL_SCANCODE_F12: // rest of the function - return KEY_F12; // keys + // F11 and F12 are separated from the rest of the function keys + case SDL_SCANCODE_F11: return KEY_F11; + case SDL_SCANCODE_F12: return KEY_F12; - case SDL_SCANCODE_KP_0: - return KEY_KEYPAD0; - case SDL_SCANCODE_KP_1: - return KEY_KEYPAD1; - case SDL_SCANCODE_KP_2: - return KEY_KEYPAD2; - case SDL_SCANCODE_KP_3: - return KEY_KEYPAD3; - case SDL_SCANCODE_KP_4: - return KEY_KEYPAD4; - case SDL_SCANCODE_KP_5: - return KEY_KEYPAD5; - case SDL_SCANCODE_KP_6: - return KEY_KEYPAD6; - case SDL_SCANCODE_KP_7: - return KEY_KEYPAD7; - case SDL_SCANCODE_KP_8: - return KEY_KEYPAD8; - case SDL_SCANCODE_KP_9: - return KEY_KEYPAD9; + case SDL_SCANCODE_KP_0: return KEY_KEYPAD0; + case SDL_SCANCODE_KP_1: return KEY_KEYPAD1; + case SDL_SCANCODE_KP_2: return KEY_KEYPAD2; + case SDL_SCANCODE_KP_3: return KEY_KEYPAD3; + case SDL_SCANCODE_KP_4: return KEY_KEYPAD4; + case SDL_SCANCODE_KP_5: return KEY_KEYPAD5; + case SDL_SCANCODE_KP_6: return KEY_KEYPAD6; + case SDL_SCANCODE_KP_7: return KEY_KEYPAD7; + case SDL_SCANCODE_KP_8: return KEY_KEYPAD8; + case SDL_SCANCODE_KP_9: return KEY_KEYPAD9; - case SDL_SCANCODE_RETURN: - return KEY_ENTER; - case SDL_SCANCODE_ESCAPE: - return KEY_ESCAPE; - case SDL_SCANCODE_BACKSPACE: - return KEY_BACKSPACE; - case SDL_SCANCODE_TAB: - return KEY_TAB; - case SDL_SCANCODE_SPACE: - return KEY_SPACE; - case SDL_SCANCODE_MINUS: - return KEY_MINUS; - case SDL_SCANCODE_EQUALS: - return KEY_EQUALS; - case SDL_SCANCODE_LEFTBRACKET: - return '['; - case SDL_SCANCODE_RIGHTBRACKET: - return ']'; - case SDL_SCANCODE_BACKSLASH: - return '\\'; - case SDL_SCANCODE_NONUSHASH: - return '#'; - case SDL_SCANCODE_SEMICOLON: - return ';'; - case SDL_SCANCODE_APOSTROPHE: - return '\''; - case SDL_SCANCODE_GRAVE: - return '`'; - case SDL_SCANCODE_COMMA: - return ','; - case SDL_SCANCODE_PERIOD: - return '.'; - case SDL_SCANCODE_SLASH: - return '/'; - case SDL_SCANCODE_CAPSLOCK: - return KEY_CAPSLOCK; - case SDL_SCANCODE_PRINTSCREEN: - return 0; // undefined? - case SDL_SCANCODE_SCROLLLOCK: - return KEY_SCROLLLOCK; - case SDL_SCANCODE_PAUSE: - return KEY_PAUSE; - case SDL_SCANCODE_INSERT: - return KEY_INS; - case SDL_SCANCODE_HOME: - return KEY_HOME; - case SDL_SCANCODE_PAGEUP: - return KEY_PGUP; - case SDL_SCANCODE_DELETE: - return KEY_DEL; - case SDL_SCANCODE_END: - return KEY_END; - case SDL_SCANCODE_PAGEDOWN: - return KEY_PGDN; - case SDL_SCANCODE_RIGHT: - return KEY_RIGHTARROW; - case SDL_SCANCODE_LEFT: - return KEY_LEFTARROW; - case SDL_SCANCODE_DOWN: - return KEY_DOWNARROW; - case SDL_SCANCODE_UP: - return KEY_UPARROW; - case SDL_SCANCODE_NUMLOCKCLEAR: - return KEY_NUMLOCK; - case SDL_SCANCODE_KP_DIVIDE: - return KEY_KPADSLASH; - case SDL_SCANCODE_KP_MULTIPLY: - return '*'; // undefined? - case SDL_SCANCODE_KP_MINUS: - return KEY_MINUSPAD; - case SDL_SCANCODE_KP_PLUS: - return KEY_PLUSPAD; - case SDL_SCANCODE_KP_ENTER: - return KEY_ENTER; - case SDL_SCANCODE_KP_PERIOD: - return KEY_KPADDEL; - case SDL_SCANCODE_NONUSBACKSLASH: - return '\\'; + case SDL_SCANCODE_RETURN: return KEY_ENTER; + case SDL_SCANCODE_ESCAPE: return KEY_ESCAPE; + case SDL_SCANCODE_BACKSPACE: return KEY_BACKSPACE; + case SDL_SCANCODE_TAB: return KEY_TAB; + case SDL_SCANCODE_SPACE: return KEY_SPACE; + case SDL_SCANCODE_MINUS: return KEY_MINUS; + case SDL_SCANCODE_EQUALS: return KEY_EQUALS; + case SDL_SCANCODE_LEFTBRACKET: return '['; + case SDL_SCANCODE_RIGHTBRACKET: return ']'; + case SDL_SCANCODE_BACKSLASH: return '\\'; + case SDL_SCANCODE_NONUSHASH: return '#'; + case SDL_SCANCODE_SEMICOLON: return ';'; + case SDL_SCANCODE_APOSTROPHE: return '\''; + case SDL_SCANCODE_GRAVE: return '`'; + case SDL_SCANCODE_COMMA: return ','; + case SDL_SCANCODE_PERIOD: return '.'; + case SDL_SCANCODE_SLASH: return '/'; + case SDL_SCANCODE_CAPSLOCK: return KEY_CAPSLOCK; + case SDL_SCANCODE_PRINTSCREEN: return 0; // undefined? + case SDL_SCANCODE_SCROLLLOCK: return KEY_SCROLLLOCK; + case SDL_SCANCODE_PAUSE: return KEY_PAUSE; + case SDL_SCANCODE_INSERT: return KEY_INS; + case SDL_SCANCODE_HOME: return KEY_HOME; + case SDL_SCANCODE_PAGEUP: return KEY_PGUP; + case SDL_SCANCODE_DELETE: return KEY_DEL; + case SDL_SCANCODE_END: return KEY_END; + case SDL_SCANCODE_PAGEDOWN: return KEY_PGDN; + case SDL_SCANCODE_RIGHT: return KEY_RIGHTARROW; + case SDL_SCANCODE_LEFT: return KEY_LEFTARROW; + case SDL_SCANCODE_DOWN: return KEY_DOWNARROW; + case SDL_SCANCODE_UP: return KEY_UPARROW; + case SDL_SCANCODE_NUMLOCKCLEAR: return KEY_NUMLOCK; + case SDL_SCANCODE_KP_DIVIDE: return KEY_KPADSLASH; + case SDL_SCANCODE_KP_MULTIPLY: return '*'; // undefined? + case SDL_SCANCODE_KP_MINUS: return KEY_MINUSPAD; + case SDL_SCANCODE_KP_PLUS: return KEY_PLUSPAD; + case SDL_SCANCODE_KP_ENTER: return KEY_ENTER; + case SDL_SCANCODE_KP_PERIOD: return KEY_KPADDEL; + case SDL_SCANCODE_NONUSBACKSLASH: return '\\'; - case SDL_SCANCODE_LSHIFT: - return KEY_LSHIFT; - case SDL_SCANCODE_RSHIFT: - return KEY_RSHIFT; - case SDL_SCANCODE_LCTRL: - return KEY_LCTRL; - case SDL_SCANCODE_RCTRL: - return KEY_RCTRL; - case SDL_SCANCODE_LALT: - return KEY_LALT; - case SDL_SCANCODE_RALT: - return KEY_RALT; - case SDL_SCANCODE_LGUI: - return KEY_LEFTWIN; - case SDL_SCANCODE_RGUI: - return KEY_RIGHTWIN; - default: - break; + case SDL_SCANCODE_LSHIFT: return KEY_LSHIFT; + case SDL_SCANCODE_RSHIFT: return KEY_RSHIFT; + case SDL_SCANCODE_LCTRL: return KEY_LCTRL; + case SDL_SCANCODE_RCTRL: return KEY_RCTRL; + case SDL_SCANCODE_LALT: return KEY_LALT; + case SDL_SCANCODE_RALT: return KEY_RALT; + case SDL_SCANCODE_LGUI: return KEY_LEFTWIN; + case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN; + default: break; } #ifdef HWRENDER DBG_Printf("Unknown incoming scancode: %d, represented %c\n", From 347b5318811db5a57108f0a1cca9addc6a046910 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 25 Nov 2016 21:13:39 +0000 Subject: [PATCH 099/207] (Messiness warning) attempt to start using SDL_SetRelativeMouseMode instead of the old hacks of making the mouse do movement without leaving the window and be hidden Seems to work so far though --- src/sdl/i_video.c | 66 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index aa572e6e..b0b3d256 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -527,7 +527,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which) static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { - static SDL_bool firsttimeonmouse = SDL_TRUE; + //static SDL_bool firsttimeonmouse = SDL_TRUE; static SDL_bool mousefocus = SDL_TRUE; static SDL_bool kbfocus = SDL_TRUE; @@ -535,17 +535,21 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { case SDL_WINDOWEVENT_ENTER: mousefocus = SDL_TRUE; + //CONS_Printf("Window gained mouse focus!\n"); break; case SDL_WINDOWEVENT_LEAVE: mousefocus = SDL_FALSE; + //CONS_Printf("Window lost mouse focus!\n"); break; case SDL_WINDOWEVENT_FOCUS_GAINED: kbfocus = SDL_TRUE; mousefocus = SDL_TRUE; + //CONS_Printf("Window gained keyboard focus!\n"); break; case SDL_WINDOWEVENT_FOCUS_LOST: kbfocus = SDL_FALSE; mousefocus = SDL_FALSE; + //CONS_Printf("Window lost keyboard focus!\n"); break; case SDL_WINDOWEVENT_MAXIMIZED: break; @@ -558,11 +562,14 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) if (!paused) I_ResumeSong(0); //resume it - if (!firsttimeonmouse) + /*if (!firsttimeonmouse) { if (cv_usemouse.value) I_StartupMouse(); } //else firsttimeonmouse = SDL_FALSE; + + if (!disable_mouse && cv_usemouse.value) + SDL_SetRelativeMouseMode(SDL_TRUE);*/ } else if (!mousefocus && !kbfocus) { @@ -570,15 +577,34 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) window_notinfocus = true; I_PauseSong(0); - if (!disable_mouse) + /*if (!disable_mouse) { SDLforceUngrabMouse(); - } + SDL_SetRelativeMouseMode(SDL_FALSE); + HalfWarpMouse(realwidth, realheight); // warp to center + }*/ memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset - if (MOUSE_MENU) + /*if (MOUSE_MENU) { SDLdoUngrabMouse(); + }*/ + } + + if (!disable_mouse) + { + if (mousefocus) + { + //if (cv_usemouse.value) + //SDL_SetRelativeMouseMode(SDL_TRUE); + } + else + { + if (SDL_GetRelativeMouseMode() == SDL_TRUE) + { + SDL_SetRelativeMouseMode(SDL_FALSE); + HalfWarpMouse(realwidth, realheight); // warp to center + } } } @@ -614,15 +640,15 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window)) { - SDLdoUngrabMouse(); + //SDLdoUngrabMouse(); return; } - if ((evt.x == realwidth/2) && (evt.y == realheight/2)) + /*if ((evt.x == realwidth/2) && (evt.y == realheight/2)) { return; } - else + else*/ { event.data2 = (INT32)lround((evt.xrel) * ((float)wwidth / (float)realwidth)); event.data3 = (INT32)lround(-evt.yrel * ((float)wheight / (float)realheight)); @@ -632,9 +658,13 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window) { - D_PostEvent(&event); - SDL_SetWindowGrab(window, SDL_TRUE); - HalfWarpMouse(wwidth, wheight); + if (SDL_GetRelativeMouseMode() == SDL_FALSE) + SDL_SetRelativeMouseMode(SDL_TRUE); + else + D_PostEvent(&event); + //SDL_SetRelativeMouseMode(SDL_TRUE); + //SDL_SetWindowGrab(window, SDL_TRUE); + //HalfWarpMouse(wwidth, wheight); } } } @@ -832,11 +862,18 @@ void I_GetEvent(void) void I_StartupMouse(void) { - static SDL_bool firsttimeonmouse = SDL_TRUE; + //static SDL_bool firsttimeonmouse = SDL_TRUE; if (disable_mouse) return; - + if (cv_usemouse.value) + SDL_SetRelativeMouseMode(SDL_TRUE); + else if (SDL_GetRelativeMouseMode() == SDL_TRUE) { + SDLdoUngrabMouse(); + SDL_SetRelativeMouseMode(SDL_FALSE); + HalfWarpMouse(realwidth, realheight); // warp to center + } +/* if (!firsttimeonmouse) HalfWarpMouse(realwidth, realheight); // warp to center else @@ -845,6 +882,7 @@ void I_StartupMouse(void) return; else SDLdoUngrabMouse(); +*/ } // @@ -1470,7 +1508,7 @@ void I_StartupGraphics(void) realheight = (Uint16)vid.height; VID_Command_Info_f(); - if (!disable_mouse) SDL_ShowCursor(SDL_DISABLE); + if (!disable_mouse) SDL_SetRelativeMouseMode(SDL_TRUE); SDLdoUngrabMouse(); graphics_started = true; From ae3e11369e828acc3ae352cfab10bb068274f8ce Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 30 Nov 2016 17:21:28 +0000 Subject: [PATCH 100/207] Revert "(Messiness warning) attempt to start using SDL_SetRelativeMouseMode instead of the old hacks of making the mouse do movement without leaving the window and be hidden" This reverts commit 347b5318811db5a57108f0a1cca9addc6a046910. (Too experimental, may end up adding new bugs; let's just keep it to clean up for now) --- src/sdl/i_video.c | 66 ++++++++++------------------------------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b0b3d256..aa572e6e 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -527,7 +527,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which) static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { - //static SDL_bool firsttimeonmouse = SDL_TRUE; + static SDL_bool firsttimeonmouse = SDL_TRUE; static SDL_bool mousefocus = SDL_TRUE; static SDL_bool kbfocus = SDL_TRUE; @@ -535,21 +535,17 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { case SDL_WINDOWEVENT_ENTER: mousefocus = SDL_TRUE; - //CONS_Printf("Window gained mouse focus!\n"); break; case SDL_WINDOWEVENT_LEAVE: mousefocus = SDL_FALSE; - //CONS_Printf("Window lost mouse focus!\n"); break; case SDL_WINDOWEVENT_FOCUS_GAINED: kbfocus = SDL_TRUE; mousefocus = SDL_TRUE; - //CONS_Printf("Window gained keyboard focus!\n"); break; case SDL_WINDOWEVENT_FOCUS_LOST: kbfocus = SDL_FALSE; mousefocus = SDL_FALSE; - //CONS_Printf("Window lost keyboard focus!\n"); break; case SDL_WINDOWEVENT_MAXIMIZED: break; @@ -562,14 +558,11 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) if (!paused) I_ResumeSong(0); //resume it - /*if (!firsttimeonmouse) + if (!firsttimeonmouse) { if (cv_usemouse.value) I_StartupMouse(); } //else firsttimeonmouse = SDL_FALSE; - - if (!disable_mouse && cv_usemouse.value) - SDL_SetRelativeMouseMode(SDL_TRUE);*/ } else if (!mousefocus && !kbfocus) { @@ -577,34 +570,15 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) window_notinfocus = true; I_PauseSong(0); - /*if (!disable_mouse) + if (!disable_mouse) { SDLforceUngrabMouse(); - SDL_SetRelativeMouseMode(SDL_FALSE); - HalfWarpMouse(realwidth, realheight); // warp to center - }*/ + } memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset - /*if (MOUSE_MENU) + if (MOUSE_MENU) { SDLdoUngrabMouse(); - }*/ - } - - if (!disable_mouse) - { - if (mousefocus) - { - //if (cv_usemouse.value) - //SDL_SetRelativeMouseMode(SDL_TRUE); - } - else - { - if (SDL_GetRelativeMouseMode() == SDL_TRUE) - { - SDL_SetRelativeMouseMode(SDL_FALSE); - HalfWarpMouse(realwidth, realheight); // warp to center - } } } @@ -640,15 +614,15 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window)) { - //SDLdoUngrabMouse(); + SDLdoUngrabMouse(); return; } - /*if ((evt.x == realwidth/2) && (evt.y == realheight/2)) + if ((evt.x == realwidth/2) && (evt.y == realheight/2)) { return; } - else*/ + else { event.data2 = (INT32)lround((evt.xrel) * ((float)wwidth / (float)realwidth)); event.data3 = (INT32)lround(-evt.yrel * ((float)wheight / (float)realheight)); @@ -658,13 +632,9 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window) { - if (SDL_GetRelativeMouseMode() == SDL_FALSE) - SDL_SetRelativeMouseMode(SDL_TRUE); - else - D_PostEvent(&event); - //SDL_SetRelativeMouseMode(SDL_TRUE); - //SDL_SetWindowGrab(window, SDL_TRUE); - //HalfWarpMouse(wwidth, wheight); + D_PostEvent(&event); + SDL_SetWindowGrab(window, SDL_TRUE); + HalfWarpMouse(wwidth, wheight); } } } @@ -862,18 +832,11 @@ void I_GetEvent(void) void I_StartupMouse(void) { - //static SDL_bool firsttimeonmouse = SDL_TRUE; + static SDL_bool firsttimeonmouse = SDL_TRUE; if (disable_mouse) return; - if (cv_usemouse.value) - SDL_SetRelativeMouseMode(SDL_TRUE); - else if (SDL_GetRelativeMouseMode() == SDL_TRUE) { - SDLdoUngrabMouse(); - SDL_SetRelativeMouseMode(SDL_FALSE); - HalfWarpMouse(realwidth, realheight); // warp to center - } -/* + if (!firsttimeonmouse) HalfWarpMouse(realwidth, realheight); // warp to center else @@ -882,7 +845,6 @@ void I_StartupMouse(void) return; else SDLdoUngrabMouse(); -*/ } // @@ -1508,7 +1470,7 @@ void I_StartupGraphics(void) realheight = (Uint16)vid.height; VID_Command_Info_f(); - if (!disable_mouse) SDL_SetRelativeMouseMode(SDL_TRUE); + if (!disable_mouse) SDL_ShowCursor(SDL_DISABLE); SDLdoUngrabMouse(); graphics_started = true; From 02d78b355bf9dacd3e740d3535921541d9c6b70d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 1 Dec 2016 14:33:44 +0000 Subject: [PATCH 101/207] Smoother ropes and zoom tubes ported from internal. --- src/p_user.c | 82 ++++++++++++++++++++-------------------------------- 1 file changed, 31 insertions(+), 51 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index f8dc942c..cb523585 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7057,7 +7057,6 @@ static void P_DoZoomTube(player_t *player) mobj_t *waypoint = NULL; fixed_t dist; boolean reverse; - fixed_t speedx,speedy,speedz; player->mo->height = P_GetPlayerSpinHeight(player); @@ -7078,17 +7077,17 @@ static void P_DoZoomTube(player_t *player) if (dist < 1) dist = 1; - speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); - speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); - speedz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); + player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); + player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); + player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); // Calculate the distance between the player and the waypoint // 'dist' already equals this. - // Will the player be FURTHER away if the momx/momy/momz is added to - // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - player->mo->z - speedz)>>FRACBITS) + // Will the player go past the waypoint? + if (speed > dist) { + speed -= dist; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; @@ -7128,14 +7127,9 @@ static void P_DoZoomTube(player_t *player) { CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); - // calculate MOMX/MOMY/MOMZ for next waypoint - // change angle - player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y); + P_SetTarget(&player->mo->tracer, waypoint); - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + // calculate MOMX/MOMY/MOMZ for next waypoint // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); @@ -7146,22 +7140,14 @@ static void P_DoZoomTube(player_t *player) player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); - - P_SetTarget(&player->mo->tracer, waypoint); } else { - P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly. + P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly. CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n"); } } - else - { - player->mo->momx = speedx; - player->mo->momy = speedy; - player->mo->momz = speedz; - } // change angle if (player->mo->tracer) @@ -7189,24 +7175,10 @@ static void P_DoRopeHang(player_t *player) mobj_t *mo2; mobj_t *waypoint = NULL; fixed_t dist; - fixed_t speedx,speedy,speedz; fixed_t playerz; player->mo->height = P_GetPlayerHeight(player); - if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope - { - P_SetTarget(&player->mo->tracer, NULL); - - player->pflags |= PF_JUMPED; - player->pflags &= ~PF_ROPEHANG; - - if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) - && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - return; - } - // Play the 'clink' sound only if the player is moving. if (!(leveltime & 7) && player->speed) S_StartSound(player->mo, sfx_s3k55); @@ -7223,9 +7195,22 @@ static void P_DoRopeHang(player_t *player) if (dist < 1) dist = 1; - speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); - speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); - speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); + player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); + player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); + player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); + + if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope + { + P_SetTarget(&player->mo->tracer, NULL); + + player->pflags |= PF_JUMPED; + player->pflags &= ~PF_ROPEHANG; + + if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) + && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) + P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + return; + } // If not allowed to move, we're done here. if (!speed) @@ -7234,15 +7219,16 @@ static void P_DoRopeHang(player_t *player) // Calculate the distance between the player and the waypoint // 'dist' already equals this. - // Will the player be FURTHER away if the momx/momy/momz is added to - // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - playerz - speedz)>>FRACBITS) + // Will the player go past the waypoint? + if (speed > dist) { + speed -= dist; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; player->mo->y = player->mo->tracer->y; player->mo->z = player->mo->tracer->z - player->mo->height; + playerz = player->mo->tracer->z; P_SetThingPosition(player->mo); CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); @@ -7298,6 +7284,8 @@ static void P_DoRopeHang(player_t *player) { CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); + P_SetTarget(&player->mo->tracer, waypoint); + // calculate MOMX/MOMY/MOMZ for next waypoint // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); @@ -7308,8 +7296,6 @@ static void P_DoRopeHang(player_t *player) player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); - - P_SetTarget(&player->mo->tracer, waypoint); } else { @@ -7328,12 +7314,6 @@ static void P_DoRopeHang(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n"); } } - else - { - player->mo->momx = speedx; - player->mo->momy = speedy; - player->mo->momz = speedz; - } } #if 0 From 7c07f39019723c0784a6bea2f8df61f5e7432c47 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Dec 2016 22:07:16 +0000 Subject: [PATCH 102/207] Make sure flipped things placed directly on ceiling get MFE_ONGROUND This fixes ceiling springs apparently flying down with you in various scenarios --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index e7ec2f8b..6a3ac9ee 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7685,6 +7685,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) if (mobj->type == MT_UNIDUS) mobj->z -= FixedMul(mobj->info->mass, mobj->scale); + + // defaults onground + if (mobj->z + mobj->height == mobj->ceilingz) + mobj->eflags |= MFE_ONGROUND; } else mobj->z = z; From d294c9d15c3d91354edb9ea7db27b52fc6d3ede0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Dec 2016 21:45:25 +0000 Subject: [PATCH 103/207] P_NetUnArchiveWorld now uses P_AddLevelFlatRuntime instead of P_AddLevelFlat. Also created P_CheckLevelFlat to just return the flat # from a name, since that's all P_NetArchiveWorld really needed from P_AddLevelFlat anyway --- src/lua_maplib.c | 40 ------------------------------ src/p_saveg.c | 9 +++---- src/p_setup.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ src/p_setup.h | 2 ++ 4 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index c512bf3c..54614c4e 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -400,46 +400,6 @@ static int sector_get(lua_State *L) return 0; } -// help function for P_LoadSectors, find a flat in the active wad files, -// allocate an id for it, and set the levelflat (to speedup search) -// -static INT32 P_AddLevelFlatRuntime(const char *flatname) -{ - size_t i; - levelflat_t *levelflat = levelflats; - - // - // first scan through the already found flats - // - for (i = 0; i < numlevelflats; i++, levelflat++) - if (strnicmp(levelflat->name,flatname,8)==0) - break; - - // that flat was already found in the level, return the id - if (i == numlevelflats) - { - // allocate new flat memory - levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL); - levelflat = levelflats+i; - - // store the name - strlcpy(levelflat->name, flatname, sizeof (levelflat->name)); - strupr(levelflat->name); - - // store the flat lump number - levelflat->lumpnum = R_GetFlatNumForName(flatname); - -#ifndef ZDEBUG - CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); -#endif - - numlevelflats++; - } - - // level flat id - return (INT32)i; -} - static int sector_set(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); diff --git a/src/p_saveg.c b/src/p_saveg.c index 5e457ca3..2144a3f9 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -509,10 +509,9 @@ static void P_NetArchiveWorld(void) // // flats // - // P_AddLevelFlat should not add but just return the number - if (ss->floorpic != P_AddLevelFlat(ms->floorpic, levelflats)) + if (ss->floorpic != P_CheckLevelFlat(ms->floorpic)) diff |= SD_FLOORPIC; - if (ss->ceilingpic != P_AddLevelFlat(ms->ceilingpic, levelflats)) + if (ss->ceilingpic != P_CheckLevelFlat(ms->ceilingpic)) diff |= SD_CEILPIC; if (ss->lightlevel != SHORT(ms->lightlevel)) @@ -752,12 +751,12 @@ static void P_NetUnArchiveWorld(void) sectors[i].ceilingheight = READFIXED(get); if (diff & SD_FLOORPIC) { - sectors[i].floorpic = P_AddLevelFlat((char *)get, levelflats); + sectors[i].floorpic = P_AddLevelFlatRuntime((char *)get); get += 8; } if (diff & SD_CEILPIC) { - sectors[i].ceilingpic = P_AddLevelFlat((char *)get, levelflats); + sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)get); get += 8; } if (diff & SD_LIGHT) diff --git a/src/p_setup.c b/src/p_setup.c index d6563735..ae6aa153 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -574,6 +574,69 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) return (INT32)i; } +// help function for Lua and $$$.sav reading +// same as P_AddLevelFlat, except this is not setup so we must realloc levelflats to fit in the new flat +// no longer a static func in lua_maplib.c because p_saveg.c also needs it +// +INT32 P_AddLevelFlatRuntime(const char *flatname) +{ + size_t i; + levelflat_t *levelflat = levelflats; + + // + // first scan through the already found flats + // + for (i = 0; i < numlevelflats; i++, levelflat++) + if (strnicmp(levelflat->name,flatname,8)==0) + break; + + // that flat was already found in the level, return the id + if (i == numlevelflats) + { + // allocate new flat memory + levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL); + levelflat = levelflats+i; + + // store the name + strlcpy(levelflat->name, flatname, sizeof (levelflat->name)); + strupr(levelflat->name); + + // store the flat lump number + levelflat->lumpnum = R_GetFlatNumForName(flatname); + +#ifndef ZDEBUG + CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); +#endif + + numlevelflats++; + } + + // level flat id + return (INT32)i; +} + +// help function for $$$.sav checking +// this simply returns the flat # for the name given +// +INT32 P_CheckLevelFlat(const char *flatname) +{ + size_t i; + levelflat_t *levelflat = levelflats; + + // + // scan through the already found flats + // + for (i = 0; i < numlevelflats; i++, levelflat++) + if (strnicmp(levelflat->name,flatname,8)==0) + break; + + if (i == numlevelflats) + return 0; // ??? flat was not found, this should not happen! + + // level flat id + return (INT32)i; +} + static void P_LoadSectors(lumpnum_t lumpnum) { UINT8 *data; diff --git a/src/p_setup.h b/src/p_setup.h index 0d735fd7..3bca1104 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -47,6 +47,8 @@ typedef struct extern size_t numlevelflats; extern levelflat_t *levelflats; INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat); +INT32 P_AddLevelFlatRuntime(const char *flatname); +INT32 P_CheckLevelFlat(const char *flatname); extern size_t nummapthings; extern mapthing_t *mapthings; From ab423f99c6abf7cddb88e4e2dbf5475d7545d114 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 9 Dec 2016 21:18:06 +0000 Subject: [PATCH 104/207] Optimising retrieval of sector_floorpic/ceilingpic As LJSonic has pointed out, there's no need for a for loop in either case; just use sector->floorpic/ceilingpic as a levelflats index directly (Besides, if that was to stop any out-of-bounds indexes being used, that's hardly the way to do it anyway) --- src/lua_maplib.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 54614c4e..208aebe3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -348,22 +348,12 @@ static int sector_get(lua_State *L) case sector_ceilingheight: lua_pushfixed(L, sector->ceilingheight); return 1; - case sector_floorpic: { // floorpic - levelflat_t *levelflat; - INT16 i; - for (i = 0, levelflat = levelflats; i != sector->floorpic; i++, levelflat++) - ; - lua_pushlstring(L, levelflat->name, 8); + case sector_floorpic: // floorpic + lua_pushlstring(L, levelflats[sector->floorpic].name, 8); return 1; - } - case sector_ceilingpic: { // ceilingpic - levelflat_t *levelflat; - INT16 i; - for (i = 0, levelflat = levelflats; i != sector->ceilingpic; i++, levelflat++) - ; - lua_pushlstring(L, levelflat->name, 8); + case sector_ceilingpic: // ceilingpic + lua_pushlstring(L, levelflats[sector->ceilingpic].name, 8); return 1; - } case sector_lightlevel: lua_pushinteger(L, sector->lightlevel); return 1; From 93901847d3e6d35577e97d2d7026e8ae586cefb5 Mon Sep 17 00:00:00 2001 From: Sryder Date: Mon, 12 Dec 2016 00:06:48 +0000 Subject: [PATCH 105/207] Fix the Fixed Rounding functions --- src/m_fixed.h | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/m_fixed.h b/src/m_fixed.h index 70402f27..d7db9bf2 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -283,9 +283,16 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedFloor(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< 0) + return x-f; + else + return x-(FRACUNIT-f); + } return INT32_MIN; } @@ -301,7 +308,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedTrunc(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< 0) @@ -324,11 +331,18 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedCeil(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< 0) + return x+(FRACUNIT-f); + else + return x+f; + } return INT32_MAX; } @@ -344,7 +358,9 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) { const fixed_t a = abs(x); //absolute of x const fixed_t i = (a>>FRACBITS)< Date: Wed, 14 Dec 2016 15:07:48 -0500 Subject: [PATCH 106/207] readme.txt dupilcated, also incorrect readme.txt should be README.md --- debian/docs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/debian/docs b/debian/docs index f3d4ef20..b43bf86b 100644 --- a/debian/docs +++ b/debian/docs @@ -1,2 +1 @@ -readme.txt -readme.txt +README.md From db20bfb3c302b3b4e3dfb8486d8c8ac284bc529b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 15 Dec 2016 21:05:54 +0100 Subject: [PATCH 107/207] Generic mobj hooks are now run before mobjtype-specific mobj hooks, and player/linedef executor hooks now have their own lists --- src/lua_hook.h | 2 +- src/lua_hooklib.c | 280 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 229 insertions(+), 53 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 804d99e1..53e0a7d8 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -60,7 +60,7 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which); #define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type -#define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type +boolean LUAh_MobjThinker(mobj_t *mo); // Hook for P_MobjThinker or P_SceneryThinker by mobj type #define LUAh_BossThinker(mo) LUAh_MobjHook(mo, hook_BossThinker) // Hook for P_GenericBossThinker by mobj type UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 5d9c5062..a24473ba 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -81,6 +81,15 @@ typedef struct hook_s* hook_p; static hook_p mobjthinkerhooks[NUMMOBJTYPES]; static hook_p mobjcollidehooks[NUMMOBJTYPES]; +// For each mobj type, a linked list for other mobj hooks +static hook_p mobjhooks[NUMMOBJTYPES]; + +// A linked list for player hooks +static hook_p playerhooks; + +// A linked list for linedef executor hooks +static hook_p linedefexecutorhooks; + // For other hooks, a unique linked list hook_p roothook; @@ -154,13 +163,41 @@ static int lib_addHook(lua_State *L) // set hook.id to the highest id + 1 hook.id = nextid++; - // Special cases for mobj thinker and collision hooks (see the comments above mobjthinkerhooks declaration) - if (hook.type == hook_MobjThinker) + // Special cases for some hook types (see the comments above mobjthinkerhooks declaration) + switch(hook.type) + { + case hook_MobjThinker: lastp = &mobjthinkerhooks[hook.s.mt]; - else if (hook.type == hook_MobjCollide || hook.type == hook_MobjMoveCollide) + break; + case hook_MobjCollide: + case hook_MobjMoveCollide: lastp = &mobjcollidehooks[hook.s.mt]; - else + break; + case hook_MobjSpawn: + case hook_TouchSpecial: + case hook_MobjFuse: + case hook_BossThinker: + case hook_ShouldDamage: + case hook_MobjDamage: + case hook_MobjDeath: + case hook_BossDeath: + case hook_MobjRemoved: + lastp = &mobjhooks[hook.s.mt]; + break; + case hook_JumpSpecial: + case hook_AbilitySpecial: + case hook_SpinSpecial: + case hook_JumpSpinSpecial: + case hook_PlayerSpawn: + lastp = &playerhooks; + break; + case hook_LinedefExecute: + lastp = &linedefexecutorhooks; + break; + default: lastp = &roothook; + break; + } // iterate the hook metadata structs // set lastp to the last hook struct's "next" pointer. @@ -196,9 +233,9 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) lua_settop(gL, 0); - if (which == hook_MobjThinker) // Alternate list for mobj thinkers - { - for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) + // Look for all generic mobj hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == which) { if (lua_gettop(gL) == 0) LUA_PushUserdata(gL, mo, META_MOBJ); @@ -217,8 +254,8 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) lua_pop(gL, 1); } - // Look for all generic mobj thinker hooks - for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) + for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next) + if (hookp->type == which) { if (lua_gettop(gL) == 0) LUA_PushUserdata(gL, mo, META_MOBJ); @@ -236,30 +273,6 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) hooked = true; lua_pop(gL, 1); } - } - else - { - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == which - && (hookp->s.mt == MT_NULL || hookp->s.mt == mo->type)) - { - if (lua_gettop(gL) == 0) - LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 0)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - } lua_settop(gL, 0); return hooked; @@ -274,7 +287,7 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which) lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) + for (hookp = playerhooks; hookp; hookp = hookp->next) if (hookp->type == which) { if (lua_gettop(gL) == 0) @@ -395,7 +408,8 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) lua_settop(gL, 0); - for (hookp = mobjcollidehooks[thing1->type]; hookp; hookp = hookp->next) + // Look for all generic mobj collision hooks + for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == which) { if (lua_gettop(gL) == 0) @@ -424,8 +438,7 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) lua_pop(gL, 1); } - // Look for all generic mobj collision hooks - for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) + for (hookp = mobjcollidehooks[thing1->type]; hookp; hookp = hookp->next) if (hookp->type == which) { if (lua_gettop(gL) == 0) @@ -458,6 +471,59 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) return shouldCollide; } +// Hook for mobj thinkers +boolean LUAh_MobjThinker(mobj_t *mo) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_MobjThinker/8] & (1<<(hook_MobjThinker%8)))) + return false; + + lua_settop(gL, 0); + + // Look for all generic mobj thinker hooks + for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) + { + if (lua_gettop(gL) == 0) + LUA_PushUserdata(gL, mo, META_MOBJ); + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) + { + if (lua_gettop(gL) == 0) + LUA_PushUserdata(gL, mo, META_MOBJ); + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + // Hook for P_TouchSpecialThing by mobj type boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) { @@ -468,9 +534,33 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == hook_TouchSpecial - && (hookp->s.mt == MT_NULL || hookp->s.mt == special->type)) + // Look for all generic touch special hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == hook_TouchSpecial) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, special, META_MOBJ); + LUA_PushUserdata(gL, toucher, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + for (hookp = mobjhooks[special->type]; hookp; hookp = hookp->next) + if (hookp->type == hook_TouchSpecial) { if (lua_gettop(gL) == 0) { @@ -507,9 +597,42 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == hook_ShouldDamage - && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type)) + // Look for all generic should damage hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == hook_ShouldDamage) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, target, META_MOBJ); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damage); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { + if (lua_toboolean(gL, -1)) + shouldDamage = 1; // Force yes + else + shouldDamage = 2; // Force no + } + lua_pop(gL, 1); + } + + for (hookp = mobjhooks[target->type]; hookp; hookp = hookp->next) + if (hookp->type == hook_ShouldDamage) { if (lua_gettop(gL) == 0) { @@ -555,9 +678,37 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == hook_MobjDamage - && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type)) + // Look for all generic mobj damage hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == hook_MobjDamage) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, target, META_MOBJ); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damage); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + for (hookp = mobjhooks[target->type]; hookp; hookp = hookp->next) + if (hookp->type == hook_MobjDamage) { if (lua_gettop(gL) == 0) { @@ -598,9 +749,35 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == hook_MobjDeath - && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type)) + // Look for all generic mobj death hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == hook_MobjDeath) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, target, META_MOBJ); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + for (hookp = mobjhooks[target->type]; hookp; hookp = hookp->next) + if (hookp->type == hook_MobjDeath) { if (lua_gettop(gL) == 0) { @@ -738,9 +915,8 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) lua_settop(gL, 0); - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == hook_LinedefExecute - && !strcmp(hookp->s.funcname, line->text)) + for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) + if (!strcmp(hookp->s.funcname, line->text)) { if (lua_gettop(gL) == 0) { From a9cfd12e049ddaaee3fc6646fa8234418e8352cb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 16 Dec 2016 21:38:53 +0000 Subject: [PATCH 108/207] Created R_GetTextureNum to make sure top/bottom/midtexture texture ids are always valid in rendering code for both software and OpenGL (and also for the Solid Midtexture effect physics code) --- src/hardware/hw_main.c | 36 ++++++++------ src/p_maputl.c | 77 +++++++++++++++-------------- src/r_data.c | 14 ++++++ src/r_data.h | 2 + src/r_segs.c | 108 ++++++++++++++++------------------------- 5 files changed, 118 insertions(+), 119 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5251e0b3..948965db 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1558,6 +1558,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (gr_backsector) { + INT32 gr_toptexture, gr_bottomtexture; // two sided line if (gr_backsector->heightsec != -1) { @@ -1608,19 +1609,22 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif } + gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); + gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); + // check TOP TEXTURE if (( #ifdef ESLOPE worldhighslope < worldtopslope || #endif worldhigh < worldtop - ) && texturetranslation[gr_sidedef->toptexture]) + ) && gr_toptexture) { if (drawtextured) { fixed_t texturevpegtop; // top - grTex = HWR_GetTexture(texturetranslation[gr_sidedef->toptexture]); + grTex = HWR_GetTexture(gr_toptexture); // PEGGING if (gr_linedef->flags & ML_DONTPEGTOP) @@ -1638,7 +1642,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) texturevpegtop += gr_sidedef->rowoffset; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpegtop %= SHORT(textures[texturetranslation[gr_sidedef->toptexture]]->height)<height)<scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gr_frontsector->ceilingheight - gr_backsector->ceilingheight) * grTex->scaleY; @@ -1683,9 +1687,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->toptexture], &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, &Surf, FF_CUTSOLIDS); else if (grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->toptexture], PF_Environment, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } @@ -1695,13 +1699,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #ifdef ESLOPE worldlowslope > worldbottomslope || #endif - worldlow > worldbottom) && texturetranslation[gr_sidedef->bottomtexture]) //only if VISIBLE!!! + worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!! { if (drawtextured) { fixed_t texturevpegbottom = 0; // bottom - grTex = HWR_GetTexture(texturetranslation[gr_sidedef->bottomtexture]); + grTex = HWR_GetTexture(gr_bottomtexture); // PEGGING #ifdef ESLOPE @@ -1721,7 +1725,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) texturevpegbottom += gr_sidedef->rowoffset; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpegbottom %= SHORT(textures[texturetranslation[gr_sidedef->bottomtexture]]->height)<height)<scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gr_backsector->floorheight - gr_frontsector->floorheight) * grTex->scaleY; @@ -1766,13 +1770,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->bottomtexture], &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, &Surf, FF_CUTSOLIDS); else if (grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->bottomtexture], PF_Environment, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } - gr_midtexture = texturetranslation[gr_sidedef->midtexture]; + gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); if (gr_midtexture) { FBITFIELD blendmode; @@ -2134,7 +2138,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else { // Single sided line... Deal only with the middletexture (if one exists) - gr_midtexture = texturetranslation[gr_sidedef->midtexture]; + gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); if (gr_midtexture) { if (drawtextured) @@ -2232,13 +2236,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (*rover->topheight < lowcut || *rover->bottomheight > highcut) continue; - texnum = texturetranslation[sides[rover->master->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); if (rover->master->flags & ML_TFERLINE) { size_t linenum = gr_curline->linedef-gr_backsector->lines[0]; newline = rover->master->frontsector->lines[0] + linenum; - texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } #ifdef ESLOPE @@ -2366,13 +2370,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (*rover->topheight < lowcut || *rover->bottomheight > highcut) continue; - texnum = texturetranslation[sides[rover->master->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); if (rover->master->flags & ML_TFERLINE) { size_t linenum = gr_curline->linedef-gr_backsector->lines[0]; newline = rover->master->frontsector->lines[0] + linenum; - texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } #ifdef ESLOPE //backsides h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; diff --git a/src/p_maputl.c b/src/p_maputl.c index fea8530a..46b03338 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -572,51 +572,54 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) side_t *side = &sides[linedef->sidenum[0]]; fixed_t textop, texbottom, texheight; fixed_t texmid, delta1, delta2; + INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid - // Get the midtexture's height - texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS; + if (texnum) { + // Get the midtexture's height + texheight = textures[texnum]->height << FRACBITS; - // Set texbottom and textop to the Z coordinates of the texture's boundaries + // Set texbottom and textop to the Z coordinates of the texture's boundaries #if 0 // #ifdef POLYOBJECTS - // don't remove this code unless solid midtextures - // on non-solid polyobjects should NEVER happen in the future - if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { - if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat - texbottom = back->floorheight + side->rowoffset; - textop = back->ceilingheight + side->rowoffset; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - texbottom = back->floorheight + side->rowoffset; - textop = texbottom + texheight*(side->repeatcnt+1); - } else { - textop = back->ceilingheight + side->rowoffset; - texbottom = textop - texheight*(side->repeatcnt+1); - } - } else + // don't remove this code unless solid midtextures + // on non-solid polyobjects should NEVER happen in the future + if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { + if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + texbottom = back->floorheight + side->rowoffset; + textop = back->ceilingheight + side->rowoffset; + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + texbottom = back->floorheight + side->rowoffset; + textop = texbottom + texheight*(side->repeatcnt+1); + } else { + textop = back->ceilingheight + side->rowoffset; + texbottom = textop - texheight*(side->repeatcnt+1); + } + } else #endif - { - if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat - texbottom = openbottom + side->rowoffset; - textop = opentop + side->rowoffset; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - texbottom = openbottom + side->rowoffset; - textop = texbottom + texheight*(side->repeatcnt+1); - } else { - textop = opentop + side->rowoffset; - texbottom = textop - texheight*(side->repeatcnt+1); + { + if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + texbottom = openbottom + side->rowoffset; + textop = opentop + side->rowoffset; + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + texbottom = openbottom + side->rowoffset; + textop = texbottom + texheight*(side->repeatcnt+1); + } else { + textop = opentop + side->rowoffset; + texbottom = textop - texheight*(side->repeatcnt+1); + } } - } - texmid = texbottom+(textop-texbottom)/2; + texmid = texbottom+(textop-texbottom)/2; - delta1 = abs(mobj->z - texmid); - delta2 = abs(thingtop - texmid); + delta1 = abs(mobj->z - texmid); + delta2 = abs(thingtop - texmid); - if (delta1 > delta2) { // Below - if (opentop > texbottom) - opentop = texbottom; - } else { // Above - if (openbottom < textop) - openbottom = textop; + if (delta1 > delta2) { // Below + if (opentop > texbottom) + opentop = texbottom; + } else { // Above + if (openbottom < textop) + openbottom = textop; + } } } diff --git a/src/r_data.c b/src/r_data.c index cb5cf359..c24cca91 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -303,6 +303,20 @@ done: return blocktex; } +// +// R_GetTextureNum +// +// Returns the actual texture id that we should use. +// This can either be texnum, the current frame for texnum's anim (if animated), +// or 0 if not valid. +// +INT32 R_GetTextureNum(INT32 texnum) +{ + if (texnum < 0 || texnum >= numtextures) + return 0; + return texturetranslation[texnum]; +} + // // R_GetColumn // diff --git a/src/r_data.h b/src/r_data.h index 69a2882a..68af0325 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -65,6 +65,8 @@ extern CV_PossibleValue_t Color_cons_t[]; void R_LoadTextures(void); void R_FlushTextureCache(void); +INT32 R_GetTextureNum(INT32 texnum); + // Retrieve column data for span blitting. UINT8 *R_GetColumn(fixed_t tex, INT32 col); diff --git a/src/r_segs.c b/src/r_segs.c index cb78743b..e0a08137 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -300,7 +300,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) curline = ds->curline; frontsector = curline->frontsector; backsector = curline->backsector; - texnum = texturetranslation[curline->sidedef->midtexture]; + texnum = R_GetTextureNum(curline->sidedef->midtexture); windowbottom = windowtop = sprbotscreen = INT32_MAX; // hack translucent linedef types (900-909 for transtables 1-9) @@ -740,7 +740,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) curline = ds->curline; backsector = pfloor->target; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = texturetranslation[sides[pfloor->master->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); colfunc = wallcolfunc; @@ -748,7 +748,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { size_t linenum = curline->linedef-backsector->lines[0]; newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } if (pfloor->flags & FF_TRANSLUCENT) @@ -1878,14 +1878,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (!backsector) { + fixed_t texheight; // single sided line - midtexture = texturetranslation[sidedef->midtexture]; + midtexture = R_GetTextureNum(sidedef->midtexture); + texheight = textureheight[midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; #ifdef ESLOPE if (linedef->flags & ML_EFFECT2) { if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz; + rw_midtexturemid = frontsector->floorheight + texheight - viewz; else rw_midtexturemid = frontsector->ceilingheight - viewz; } @@ -1894,10 +1896,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (linedef->flags & ML_DONTPEGBOTTOM) { #ifdef ESLOPE - rw_midtexturemid = worldbottom + textureheight[sidedef->midtexture]; + rw_midtexturemid = worldbottom + texheight; rw_midtextureslide = floorfrontslide; #else - vtop = frontsector->floorheight + textureheight[sidedef->midtexture]; + vtop = frontsector->floorheight + texheight; // bottom of texture at bottom rw_midtexturemid = vtop - viewz; #endif @@ -2129,76 +2131,50 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif ) { + fixed_t texheight; // top texture if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) && linedef->sidenum[1] != 0xffff) { // Special case... use offsets from 2nd side but only if it has a texture. side_t *def = &sides[linedef->sidenum[1]]; - toptexture = texturetranslation[def->toptexture]; + toptexture = R_GetTextureNum(def->toptexture); if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = texturetranslation[sidedef->toptexture]; - -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; - else - rw_toptexturemid = backsector->ceilingheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw_toptexturemid = worldtop; -#ifdef ESLOPE - rw_toptextureslide = ceilingfrontslide; -#endif - } - else - { -#ifdef ESLOPE - rw_toptexturemid = worldhigh + textureheight[def->toptexture]; - rw_toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + textureheight[def->toptexture]; - // bottom of texture - rw_toptexturemid = vtop - viewz; -#endif - } + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; } else { - toptexture = texturetranslation[sidedef->toptexture]; - + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } #ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; - else - rw_toptexturemid = backsector->ceilingheight - viewz; - } else -#endif + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw_toptexturemid = worldtop; -#ifdef ESLOPE - rw_toptextureslide = ceilingfrontslide; -#endif - } + rw_toptexturemid = frontsector->ceilingheight - viewz; else - { -#ifdef ESLOPE - rw_toptexturemid = worldhigh + textureheight[sidedef->toptexture]; - rw_toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + textureheight[sidedef->toptexture]; - // bottom of texture - rw_toptexturemid = vtop - viewz; + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGTOP) + { + // top of texture at top + rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif + } + else + { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + texheight; + rw_toptextureslide = ceilingbackslide; +#else + vtop = backsector->ceilingheight + texheight; + // bottom of texture + rw_toptexturemid = vtop - viewz; #endif - } } } // check BOTTOM TEXTURE @@ -2209,7 +2185,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ) //seulement si VISIBLE!!! { // bottom texture - bottomtexture = texturetranslation[sidedef->bottomtexture]; + bottomtexture = R_GetTextureNum(sidedef->bottomtexture); #ifdef ESLOPE if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked @@ -2494,7 +2470,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->numthicksides = numthicksides = i; } - if (sidedef->midtexture) + if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) { // masked midtexture if (!ds_p->thicksidecol) @@ -3101,12 +3077,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) { ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = sidedef->midtexture ? INT32_MIN: INT32_MAX; + ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX; } if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) { ds_p->silhouette |= SIL_BOTTOM; - ds_p->bsilheight = sidedef->midtexture ? INT32_MAX: INT32_MIN; + ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; } ds_p++; } From 8e56582728e02176b32890c89fc105df2a0bd0f3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 17 Dec 2016 19:59:54 +0000 Subject: [PATCH 109/207] Created R_CheckTextureCache to make sure midtexture/FOF walls cache their textures before choosing colfunc_2s, for software mode --- src/r_data.c | 12 ++++++++++++ src/r_data.h | 1 + src/r_segs.c | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/src/r_data.c b/src/r_data.c index c24cca91..bb12f916 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -317,6 +317,18 @@ INT32 R_GetTextureNum(INT32 texnum) return texturetranslation[texnum]; } +// +// R_CheckTextureCache +// +// Use this if you need to make sure the texture is cached before R_GetColumn calls +// e.g.: midtextures and FOF walls +// +void R_CheckTextureCache(INT32 tex) +{ + if (!texturecache[tex]) + R_GenerateTexture(tex); +} + // // R_GetColumn // diff --git a/src/r_data.h b/src/r_data.h index 68af0325..1e9e0eb5 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -66,6 +66,7 @@ void R_LoadTextures(void); void R_FlushTextureCache(void); INT32 R_GetTextureNum(INT32 texnum); +void R_CheckTextureCache(INT32 tex); // Retrieve column data for span blitting. UINT8 *R_GetColumn(fixed_t tex, INT32 col); diff --git a/src/r_segs.c b/src/r_segs.c index e0a08137..ab501082 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -344,6 +344,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) @@ -968,6 +971,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_texturemid += offsetvalue; + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info anymore in Doom Legacy if (textures[texnum]->holes) From 5c295d5733e9fed37ecd8fe7d4815e5c2105f2d7 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 22 Dec 2016 18:59:18 -0500 Subject: [PATCH 110/207] Codeblock: fixup sdl2 to sdl --- SRB2.cbp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/SRB2.cbp b/SRB2.cbp index 99a71226..17ca0b56 100644 --- a/SRB2.cbp +++ b/SRB2.cbp @@ -4157,7 +4157,7 @@ HW3SOUND for 3D hardware sound support