diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index eeb4b895b..087364161 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -121,6 +121,7 @@ extern char lastpm16buf[156]; void getpoint(int32_t searchxe, int32_t searchye, int32_t *x, int32_t *y); int32_t getpointhighlight(int32_t xplc, int32_t yplc, int32_t point); +void update_highlight(); #ifdef _WIN32 #define DEFAULT_GAME_EXEC "eduke32.exe" diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index 0d0bf1b7b..e8e33b2dc 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -1367,7 +1367,7 @@ static void duplicate_selected_sprites() } } -static void update_highlight() +void update_highlight() { int32_t i; @@ -3507,6 +3507,8 @@ SKIP: wall[i].nextsector = -1; wall[i].nextwall = -1; } + + setfirstwall(k, suckwall+j); // restore old first wall } } else diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 4557a41c2..af64eedaf 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -10497,13 +10497,24 @@ void setfirstwall(int16_t sectnum, int16_t newfirstwall) { int32_t i, j, k, numwallsofloop; int32_t startwall, endwall, danumwalls, dagoalloop; + walltype *tmpwall; startwall = sector[sectnum].wallptr; danumwalls = sector[sectnum].wallnum; endwall = startwall+danumwalls; + if ((newfirstwall < startwall) || (newfirstwall >= startwall+danumwalls)) return; - for (i=0; i= danumwalls) k -= danumwalls; - Bmemcpy(&wall[startwall+i],&wall[numwalls+k],sizeof(walltype)); + Bmemcpy(&wall[startwall+i], &tmpwall[k], sizeof(walltype)); wall[startwall+i].point2 += danumwalls-startwall-j; if (wall[startwall+i].point2 >= danumwalls) @@ -10535,12 +10546,12 @@ void setfirstwall(int16_t sectnum, int16_t newfirstwall) } for (i=0; i= numwallsofloop) k -= numwallsofloop; - Bmemcpy(&wall[startwall+i],&wall[numwalls+k],sizeof(walltype)); + Bmemcpy(&wall[startwall+i], &tmpwall[k], sizeof(walltype)); wall[startwall+i].point2 += numwallsofloop-newfirstwall; if (wall[startwall+i].point2 >= numwallsofloop) @@ -10550,6 +10561,8 @@ void setfirstwall(int16_t sectnum, int16_t newfirstwall) for (i=startwall; i= 0) wall[wall[i].nextwall].nextwall = i; + + Bfree(tmpwall); } diff --git a/polymer/eduke32/build/src/polymer.c b/polymer/eduke32/build/src/polymer.c index 4eeef0cda..7680bdf0e 100644 --- a/polymer/eduke32/build/src/polymer.c +++ b/polymer/eduke32/build/src/polymer.c @@ -965,6 +965,20 @@ void polymer_drawmasks(void) bglDisable(GL_ALPHA_TEST); } +static inline GLfloat dot2f(GLfloat *v1, GLfloat *v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1]; +} +static inline GLfloat dot3f(GLfloat *v1, GLfloat *v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} +static inline void relvec2f(GLfloat *v1, GLfloat *v2, GLfloat *out) +{ + out[0] = v2[0]-v1[0]; + out[1] = v2[1]-v1[1]; +} + void polymer_editorpick(void) { GLubyte picked[3]; @@ -987,7 +1001,99 @@ void polymer_editorpick(void) case 1: // floor case 2: // ceiling searchsector = num; - searchwall = sector[num].wallptr; + + // Apologies to Plagman for littering here, but this feature is quite essential + { + GLdouble model[16]; + GLdouble proj[16]; + GLint view[4]; + + GLdouble x,y,z; + GLfloat scr[3], scrv[3]; + GLdouble scrx,scry,scrz; + GLfloat dadepth; + + int16_t k, bestk=0; + GLfloat bestwdistsq = 3.4e38, wdistsq; + GLfloat w1[2], w2[2], w21[2], pw1[2], pw2[2]; + GLfloat ptonline[2]; + GLfloat scrvxz[2]; + GLfloat scrvxznorm, scrvxzn[2], scrpxz[2]; + GLfloat w1d, w2d; + walltype *wal = &wall[sector[searchsector].wallptr]; + + GLfloat t, svcoeff, p[2]; + GLfloat *pl; + + bglGetDoublev(GL_MODELVIEW_MATRIX, model); + bglGetDoublev(GL_PROJECTION_MATRIX, proj); + bglGetIntegerv(GL_VIEWPORT, view); + + bglReadPixels(searchx, ydim-searchy, 1,1, GL_DEPTH_COMPONENT, GL_FLOAT, &dadepth); + bgluUnProject(searchx, ydim-searchy, dadepth, model, proj, view, &x, &y, &z); + bgluUnProject(searchx, ydim-searchy, 0.0, model, proj, view, &scrx, &scry, &scrz); + + scr[0]=scrx, scr[1]=scry, scr[2]=scrz; + + scrv[0] = x-scrx; + scrv[1] = y-scry; + scrv[2] = z-scrz; + + scrvxz[0] = x-scrx; + scrvxz[1] = z-scrz; + + if (searchstat==1) + pl = &prsectors[searchsector]->ceil.plane[0]; + else + pl = &prsectors[searchsector]->floor.plane[0]; + + t = dot3f(pl,scrv); + svcoeff = -(dot3f(pl,scr)+pl[3])/t; + + // point on plane (x and z) + p[0] = scrx + svcoeff*scrv[0]; + p[1] = scrz + svcoeff*scrv[2]; + + for (k=0; k + // if &16384, index&16383 is sprite index, else wall index + C_GetManyVars(3); + return 0; + case CON_ADDLOGVAR: // syntax: addlogvar // prints the line number in the log file. C_GetNextVar(); return 0; + case CON_UPDATEHIGHLIGHT: case CON_ADDLOG: // syntax: addlog // prints the line number in the log file. diff --git a/polymer/eduke32/source/m32def.h b/polymer/eduke32/source/m32def.h index 2ff367d1d..d73507c71 100644 --- a/polymer/eduke32/source/m32def.h +++ b/polymer/eduke32/source/m32def.h @@ -95,6 +95,7 @@ typedef struct { int32_t g_st; spritetype *g_sp; uint32_t flags; //g_errorFlag, g_returnFlag; + uint32_t updatehighlight; } vmstate_t; #define VMFLAG_RETURN 1 @@ -314,6 +315,8 @@ enum ScriptKeywords_t CON_ANDVARVAR, CON_ORVARVAR, CON_XORVARVAR, + CON_SHIFTVARVARL, + CON_SHIFTVARVARR, CON_SIN, CON_COS, @@ -377,6 +380,7 @@ enum ScriptKeywords_t // if* using current sprite CON_IFANGDIFFL, CON_IFSPRITEPAL, + CON_IFHIGHLIGHTED, CON_IFACTOR, CON_IFSOUND, CON_IFPDISTL, @@ -400,6 +404,7 @@ enum ScriptKeywords_t /// CON_IFINOUTERSPACE, /// CON_IFCANSEETARGET, CON_IFNOSOUNDS, + CON_IFIN3DMODE, CON_IFAIMINGSPRITE, CON_IFAIMINGWALL, CON_IFAIMINGSECTOR, @@ -443,6 +448,8 @@ enum ScriptKeywords_t CON_GETCLOSESTCOL, // stuff + CON_UPDATEHIGHLIGHT, + CON_SETHIGHLIGHT, CON_ADDLOGVAR, CON_ADDLOG, CON_DEBUG, diff --git a/polymer/eduke32/source/m32exec.c b/polymer/eduke32/source/m32exec.c index d160ae48f..2f85a9611 100644 --- a/polymer/eduke32/source/m32exec.c +++ b/polymer/eduke32/source/m32exec.c @@ -40,6 +40,7 @@ vmstate_t vm_default = -1, 0, NULL, + 0, 0 }; @@ -187,6 +188,12 @@ void VM_OnEvent(register int32_t iEventID, register int32_t iActor) message("ERROR executing %s. Event disabled.", label+(iEventID*MAXLABELLEN)); } + if (vm.updatehighlight) + { + update_highlight(); + vm.updatehighlight = 0; + } + // restore old values... Bmemcpy(&vm, &vm_backup, sizeof(vmstate_t)); insptr = oinsptr; @@ -855,12 +862,28 @@ skip_check: insptr += 2; continue; + case CON_SHIFTVARVARL: + insptr++; + { + int32_t j=*insptr++; + Gv_SetVarX(j, Gv_GetVarX(j) << Gv_GetVarX(*insptr++)); + } + continue; + case CON_SHIFTVARR: insptr++; Gv_SetVarX(*insptr, Gv_GetVarX(*insptr) >> *(insptr+1)); insptr += 2; continue; + case CON_SHIFTVARVARR: + insptr++; + { + int32_t j=*insptr++; + Gv_SetVarX(j, Gv_GetVarX(j) >> Gv_GetVarX(*insptr++)); + } + continue; + case CON_SIN: insptr++; Gv_SetVarX(*insptr, sintable[Gv_GetVarX(*(insptr+1))&2047]); @@ -1518,6 +1541,25 @@ badindex: VM_DoConditional(vm.g_sp->pal == Gv_GetVarX(*insptr)); continue; + case CON_IFHIGHLIGHTED: + insptr++; + { + int32_t id=*insptr++, index=Gv_GetVarX(*insptr); + + if (index<0 || (id==M32_SPRITE_VAR_ID && index>=MAXSPRITES) || (id==M32_WALL_VAR_ID && index>=numwalls)) + { + M32_PRINTERROR("%s index %d out of range!", id==M32_SPRITE_VAR_ID?"Sprite":"Wall", index); + vm.flags |= VMFLAG_ERROR; + continue; + } + + if (id==M32_SPRITE_VAR_ID) + VM_DoConditional(show2dsprite[index>>3]&(1<<(index&7))); + else + VM_DoConditional(show2dwall[index>>3]&(1<<(index&7))); + } + continue; + case CON_IFANGDIFFL: insptr++; { @@ -2133,7 +2175,50 @@ badindex: Gv_SetVarX(*insptr++, getclosestcol((r>>2)&63, (g>>2)&63, (b>>2)&63)); continue; } + // *** stuff + case CON_UPDATEHIGHLIGHT: + insptr++; + update_highlight(); + continue; + + case CON_SETHIGHLIGHT: + insptr++; + { + int32_t what=Gv_GetVarX(*insptr++), index=Gv_GetVarX(*insptr++), doset = Gv_GetVarX(*insptr++); + + if (what&16384) + { + index &= ~16384; + if (index < 0 || index>=MAXSPRITES || sprite[index].statnum==MAXSTATUS) + { + M32_PRINTERROR("Invalid sprite index %d", index); + vm.flags |= VMFLAG_ERROR; + continue; + } + + if (doset) + show2dsprite[index>>3] |= (1<<(index&7)); + else + show2dsprite[index>>3] &= ~(1<<(index&7)); + } + else if (index < 0 || index>=numwalls) + { + M32_PRINTERROR("Invalid wall index %d", index); + vm.flags |= VMFLAG_ERROR; + continue; + + if (doset) + show2dwall[index>>3] |= (1<<(index&7)); + else + show2dwall[index>>3] &= ~(1<<(index&7)); + } + + vm.updatehighlight = 1; + + continue; + } + case CON_GETTIMEDATE: insptr++; { @@ -2281,7 +2366,7 @@ badindex: if (max==0) max = INT_MAX; -OSD_Printf("max:%d, sign:%d\n", max, sign); +//OSD_Printf("max:%d, sign:%d\n", max, sign); if (tw==CON_GETNUMBER16) Gv_SetVarX(var, getnumber16(quotetext, Gv_GetVarX(var), max, sign)); else @@ -2837,6 +2922,10 @@ dodefault: } continue; + case CON_IFIN3DMODE: + VM_DoConditional(qsetmode==200); + continue; + // ifaimingsprite and -wall also work in 2d mode, but you must "and" with 16383 yourself case CON_IFAIMINGSPRITE: VM_DoConditional(AIMING_AT_SPRITE || (qsetmode!=200 && pointhighlight>=16384));