Mapster32: make sector keep old firstwall when adding inner loop, rewrite setfirstwall to use malloc'ed memory for temp storage instead of end of sector[], reintroduce correct searchwall determination in Polymer mouse picker (intersection of xy projection of aiming ray with wall); added commands to m32script: shiftvarvar[lr], ifhighlighted, ifin3dmode, updatehighlight, sethighlight; coded prototype terrain helper based on isolines and triangle strips.

git-svn-id: https://svn.eduke32.com/eduke32@1710 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2010-09-30 23:05:40 +00:00
parent bada760c56
commit 036a88736c
11 changed files with 381 additions and 56 deletions

View file

@ -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"

View file

@ -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

View file

@ -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; i++)
Bmemcpy(&wall[i+numwalls],&wall[i+startwall],sizeof(walltype));
tmpwall = Bmalloc(danumwalls * sizeof(walltype));
if (!tmpwall)
{
initprintf("setfirstwall: OUT OF MEMORY!\n");
return;
}
Bmemcpy(tmpwall, &wall[startwall], danumwalls*sizeof(walltype));
// for (i=0; i<danumwalls; i++)
// Bmemcpy(&wall[i+numwalls],&wall[i+startwall],sizeof(walltype));
numwallsofloop = 0;
i = newfirstwall;
@ -10523,7 +10534,7 @@ void setfirstwall(int16_t sectnum, int16_t newfirstwall)
for (i=0; i<danumwalls; i++)
{
k = i+j; if (k >= 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; i++)
Bmemcpy(&wall[i+numwalls],&wall[i+startwall],sizeof(walltype));
Bmemcpy(&tmpwall[i], &wall[i+startwall], sizeof(walltype));
for (i=0; i<numwallsofloop; i++)
{
k = i+newfirstwall-startwall;
if (k >= 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<endwall; i++)
if (wall[i].nextwall >= 0) wall[wall[i].nextwall].nextwall = i;
Bfree(tmpwall);
}

View file

@ -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<sector[searchsector].wallnum; k++)
{
w1[1] = -(float)wal[k].x;
w1[0] = (float)wal[k].y;
w2[1] = -(float)wall[wal[k].point2].x;
w2[0] = (float)wall[wal[k].point2].y;
scrvxznorm = sqrt(dot2f(scrvxz,scrvxz));
scrvxzn[0] = scrvxz[1]/scrvxznorm;
scrvxzn[1] = -scrvxz[0]/scrvxznorm;
relvec2f(p,w1, pw1);
relvec2f(p,w2, pw2);
relvec2f(w2,w1, w21);
w1d = dot2f(scrvxzn,pw1);
w2d = dot2f(scrvxzn,pw2);
w2d = -w2d;
if (w1d <= 0 || w2d <= 0)
continue;
ptonline[0] = w2[0]+(w2d/(w1d+w2d))*w21[0];
ptonline[1] = w2[1]+(w2d/(w1d+w2d))*w21[1];
relvec2f(p,ptonline, scrpxz);
if (dot2f(scrvxz,scrpxz)<0)
continue;
wdistsq = dot2f(scrpxz,scrpxz);
if (wdistsq < bestwdistsq)
{
bestk = k;
bestwdistsq = wdistsq;
}
}
searchwall = sector[searchsector].wallptr + bestk;
}
// :P
// searchwall = sector[num].wallptr;
break;
case 3:
// sprite

View file

@ -545,7 +545,7 @@ RIGHT smooth scrolling
^3SE 28: LIGHTNING
Hi = tile #4890 Hi
^3^0SE 29: WAVES
^3SE 29: WAVES
Hi: start height (phase)
GPSPEED Lo: amplitude (default: 256)

View file

@ -1068,3 +1068,61 @@ defstate corruptchk
}
}
ends
defstate mkterrain
var w2 w3 idx bit tmp sec
var warned
set warned 0
for i selwalls
{
sectorofwall j i
set tmp 0, ifand sector[j].floorstat 2, set tmp 1 // already handled
ife tmp 0 ife sector[j].wallnum 3
{
set w2 wall[i].point2
set idx w2, shiftr idx 3
set tmp w2, and tmp 7, set bit 1, shiftl bit tmp
ifand show2dwall[idx] bit
{
setfirstwall j i
set z 0x7ffffff
ifin3dmode
{
ife searchstat 2 // floor
set z sector[searchsector].floorz
}
else
{
for k allsectors
{
ifinside mousxplc mousyplc k
{
set z sector[k].floorz
break
}
}
}
ife z 0x7ffffff
{
ife warned 0
{
quote "Mouse pointer must be aiming at sector floor."
set warned 1
}
}
else
{
set w3 wall[w2].point2
set sec wall[i].nextsector
ifge sec 0
set sector[j].floorz sector[sec].floorz
alignflorslope j wall[w3].x wall[w3].y z
}
}
}
}
ends

View file

@ -1943,47 +1943,6 @@ static void SoundDisplay()
}
}
else if (keystatus[KEYSC_S]) // sorting
{
char ch, bad=0;
i=0;
bflushchars();
while (bad == 0)
{
_printmessage16("Sort by: (S)oundnum (D)ef (F)ile ori(g) or flags (12345)");
showframe(1);
idle_waitevent();
if (handleevents())
quitevent = 0;
ch = bgetchar();
if (keystatus[1]) bad = 1;
else if (ch == 's' || ch == 'd' || ch == 'f' || ch == 'g' ||
ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5')
{
bad = 2;
sort_sounds(ch);
}
}
if (bad==1)
{
keystatus[KEYSC_ESC] = keystatus[KEYSC_Q] = keystatus[KEYSC_F2] = 0;
}
if (bad==2)
{
keystatus[KEYSC_S] = keystatus[KEYSC_D] = keystatus[KEYSC_F] = 0;
keystatus[KEYSC_G] = keystatus[KEYSC_1] = keystatus[KEYSC_2] = 0;
keystatus[KEYSC_3] = keystatus[KEYSC_4] = keystatus[KEYSC_5] = 0;
}
}
_printmessage16(" FILE NAME PITCH RANGE PRI FLAGS VOLUME");
for (i=0; j=cursnd+i, i<SOUND_NUMDISPLINES && j<g_numsounds; i++)
{
@ -2015,11 +1974,52 @@ static void SoundDisplay()
}
printext16(8, ydim-overridepm16y+28+i*9,
S_CheckSoundPlaying(-1, k) ? editorcolors[2] : editorcolors[10],
keystatus[KEYSC_S]?editorcolors[8] : (S_CheckSoundPlaying(-1, k) ? editorcolors[2] : editorcolors[10]),
j==cursnd+curofs ? editorcolors[1] : -1,
disptext[i], 0);
}
if (keystatus[KEYSC_S]) // sorting
{
char ch, bad=0;
_printmessage16("Sort by: (S)oundnum (D)ef (F)ile ori(g) or flags (12345)");
showframe(1);
i=0;
bflushchars();
while (bad == 0)
{
idle_waitevent();
if (handleevents())
quitevent = 0;
ch = bgetchar();
if (keystatus[1]) bad = 1;
else if (ch == 's' || ch == 'd' || ch == 'f' || ch == 'g' ||
ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5')
{
bad = 2;
sort_sounds(ch);
}
}
if (bad==1)
{
keystatus[KEYSC_ESC] = keystatus[KEYSC_Q] = keystatus[KEYSC_F2] = 0;
}
if (bad==2)
{
keystatus[KEYSC_S] = keystatus[KEYSC_D] = keystatus[KEYSC_F] = 0;
keystatus[KEYSC_G] = keystatus[KEYSC_1] = keystatus[KEYSC_2] = 0;
keystatus[KEYSC_3] = keystatus[KEYSC_4] = keystatus[KEYSC_5] = 0;
}
}
else
showframe(1);
}
@ -7897,8 +7897,21 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
insptr = script + oscrofs;
Bmemcpy(&vm, &vm_default, sizeof(vmstate_t));
if (qsetmode==200 && AIMING_AT_SPRITE)
{
vm.g_i = searchwall;
vm.g_sp = &sprite[vm.g_i];
}
VM_Execute(0);
if (vm.updatehighlight)
{
update_highlight();
vm.updatehighlight = 0;
}
if (!(vm.flags&VMFLAG_ERROR))
{
int32_t idx, dosave=1;

View file

@ -139,8 +139,8 @@ const tokenmap_t altkeyw[] =
{ "al", CON_ADDLOGVAR },
{ "var", CON_GAMEVAR },
{ "array", CON_GAMEARRAY },
{ "shiftl", CON_SHIFTVARL },
{ "shiftr", CON_SHIFTVARR },
{ "shiftl", CON_SHIFTVARVARL },
{ "shiftr", CON_SHIFTVARVARR },
{ "rand", CON_RANDVARVAR },
{ "set", CON_SETVARVAR },
{ "add", CON_ADDVARVAR },
@ -230,6 +230,8 @@ const char *keyw[] =
"andvarvar",
"orvarvar",
"xorvarvar",
"shiftvarvarl",
"shiftvarvarr",
"sin",
"cos",
@ -286,6 +288,7 @@ const char *keyw[] =
"ifrnd",
"ifangdiffl",
"ifspritepal",
"ifhighlighted",
"ifactor",
"ifsound",
"ifpdistl",
@ -302,6 +305,7 @@ const char *keyw[] =
"ifinwater",
"ifoutside",
"ifnosounds",
"ifin3dmode",
"ifaimingsprite",
"ifaimingwall",
"ifaimingsector",
@ -344,6 +348,8 @@ const char *keyw[] =
"fixrepeats",
"getclosestcol",
"updatehighlight",
"sethighlight",
"addlogvar",
"addlog",
"debug",
@ -2738,6 +2744,8 @@ repeatcase:
case CON_ANDVARVAR:
case CON_ORVARVAR:
case CON_XORVARVAR:
case CON_SHIFTVARVARL:
case CON_SHIFTVARVARR:
{
instype *inst = (g_scriptPtr-1);
const char *otextptr;
@ -2896,6 +2904,7 @@ repeatcase:
// vvv if* using current sprite
case CON_IFANGDIFFL:
case CON_IFSPRITEPAL:
case CON_IFHIGHLIGHTED:
case CON_IFACTOR:
case CON_IFSOUND:
case CON_IFPDISTL:
@ -2919,6 +2928,7 @@ repeatcase:
/// case CON_IFINOUTERSPACE:
/// case CON_IFCANSEETARGET:
case CON_IFNOSOUNDS:
case CON_IFIN3DMODE:
case CON_IFAIMINGSPRITE:
case CON_IFAIMINGWALL:
case CON_IFAIMINGSECTOR:
@ -2955,8 +2965,27 @@ repeatcase:
}
}
else if (tw<=CON_IFPDISTG)
/// C_GetNextValue(LABEL_DEFINE);
{
if (tw==CON_IFHIGHLIGHTED)
{
int32_t id;
if (C_GetNextLabelName(1))
return 1;
id = GetGamevarID(tlabel, 0);
if (!(id==M32_SPRITE_VAR_ID || id==M32_WALL_VAR_ID))
{
C_CUSTOMERROR("\"ifhighlighted\" must be followed immediately by \"sprite\" or \"wall\".");
return 1;
}
*g_scriptPtr++ = id;
C_GetNextVar();
}
else
C_GetNextVar();
}
else if (tw<=CON_IFINSIDE)
C_GetManyVars(3);
// else {}
@ -3108,12 +3137,19 @@ repeatcase:
return 0;
// *** stuff
case CON_SETHIGHLIGHT:
// sethighlight <what> <index> <set_or_unset>
// if <what>&16384, index&16383 is sprite index, else wall index
C_GetManyVars(3);
return 0;
case CON_ADDLOGVAR:
// syntax: addlogvar <var>
// 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.

View file

@ -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,

View file

@ -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));