summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjacksonmj <mj-pt@jacksonmj.co.uk>2011-05-28 22:15:29 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2011-05-29 12:36:11 (GMT)
commitf603e33e74f82fa14bb6747a43773a8b47ceaa3c (patch)
treede64fddd4f65cd42419d3d79a076aa2184dedc2f /src
parent5e414e64dcb41df0621ac35ffe53c13233469356 (diff)
downloadpowder-f603e33e74f82fa14bb6747a43773a8b47ceaa3c.zip
powder-f603e33e74f82fa14bb6747a43773a8b47ceaa3c.tar.gz
Small speed improvement to eval_move
Warning: may be buggy, test thoroughly.
Diffstat (limited to 'src')
-rw-r--r--src/main.c1
-rw-r--r--src/powder.c178
2 files changed, 106 insertions, 73 deletions
diff --git a/src/main.c b/src/main.c
index 9524c26..41a6c74 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1650,6 +1650,7 @@ int main(int argc, char *argv[])
parts[NPART-1].life = -1;
pfree = 0;
fire_bg=calloc(XRES*YRES, PIXELSIZE);
+ init_can_move();
clear_sim();
//fbi_img = render_packed_rgb(fbi, FBI_W, FBI_H, FBI_CMP);
diff --git a/src/powder.c b/src/powder.c
index 48265fc..cdff223 100644
--- a/src/powder.c
+++ b/src/powder.c
@@ -57,6 +57,81 @@ static void photoelectric_effect(int nx, int ny)//create sparks from PHOT when h
pn_junction_sprk(nx, ny, PT_PSCN);
}
}
+
+unsigned char can_move[PT_NUM][PT_NUM];
+
+void init_can_move()
+{
+ // can_move[moving type][type at destination]
+ // 0 = No move/Bounce
+ // 1 = Swap
+ // 2 = Both particles occupy the same space.
+ // 3 = Varies, go run some extra checks
+ int t, rt;
+ for (rt=0;rt<PT_NUM;rt++)
+ can_move[0][rt] = 0; // particles that don't exist shouldn't move...
+ for (t=1;t<PT_NUM;t++)
+ for (rt=0;rt<PT_NUM;rt++)
+ can_move[t][rt] = 1;
+ for (rt=1;rt<PT_NUM;rt++)
+ {
+ can_move[PT_PHOT][rt] = 2;
+ }
+ for (t=1;t<PT_NUM;t++)
+ {
+ for (rt=1;rt<PT_NUM;rt++)
+ {
+ // weight check, also prevents particles of same type displacing each other
+ if (ptypes[t].weight <= ptypes[rt].weight) can_move[t][rt] = 0;
+ if (t==PT_NEUT && ptypes[rt].properties&PROP_NEUTPASS)
+ can_move[t][rt] = 2;
+ if (t==PT_NEUT && ptypes[rt].properties&PROP_NEUTPENETRATE)
+ can_move[t][rt] = 1;
+ if (ptypes[t].properties&PROP_NEUTPENETRATE && rt==PT_NEUT)
+ can_move[t][rt] = 0;
+ if (ptypes[t].properties&TYPE_ENERGY && ptypes[rt].properties&TYPE_ENERGY)
+ can_move[t][rt] = 2;
+ }
+ }
+ can_move[PT_BIZR][PT_FILT] = 2;
+ can_move[PT_BIZRG][PT_FILT] = 2;
+ for (t=0;t<PT_NUM;t++)
+ {
+ //spark shouldn't move
+ can_move[PT_SPRK][t] = 0;
+ //all stickman collisions are done in stickman update function
+ can_move[PT_STKM][t] = 2;
+ can_move[PT_STKM2][t] = 2;
+ }
+ for (t=0;t<PT_NUM;t++)
+ {
+ // make them eat things
+ can_move[t][PT_VOID] = 1;
+ can_move[t][PT_BHOL] = 1;
+ can_move[t][PT_NBHL] = 1;
+ //all stickman collisions are done in stickman update function
+ can_move[t][PT_STKM] = 2;
+ can_move[t][PT_STKM2] = 2;
+ //INVIS behaviour varies with pressure
+ can_move[t][PT_INVIS] = 3;
+ //stop CNCT being displaced by other particles
+ can_move[t][PT_CNCT] = 0;
+ }
+ for (t=0;t<PT_NUM;t++)
+ {
+ if (t==PT_GLAS || t==PT_PHOT || t==PT_CLNE || t==PT_PCLN
+ || t==PT_GLOW || t==PT_WATR || t==PT_DSTW || t==PT_SLTW
+ || t==PT_ISOZ || t==PT_ISZS || t==PT_FILT || t==PT_INVIS
+ || t==PT_QRTZ || t==PT_PQRT)
+ can_move[PT_PHOT][t] = 2;
+ }
+ can_move[PT_PHOT][PT_LCRY] = 3;//varies according to LCRY life
+ can_move[PT_NEUT][PT_INVIS] = 2;
+ //whol eats anar
+ can_move[PT_ANAR][PT_WHOL] = 2;
+ can_move[PT_ANAR][PT_NWHL] = 2;
+}
+
/*
RETURN-value explenation
1 = Swap
@@ -66,6 +141,7 @@ static void photoelectric_effect(int nx, int ny)//create sparks from PHOT when h
int eval_move(int pt, int nx, int ny, unsigned *rr)
{
unsigned r;
+ int result;
if (nx<0 || ny<0 || nx>=XRES || ny>=YRES)
return 0;
@@ -75,65 +151,34 @@ int eval_move(int pt, int nx, int ny, unsigned *rr)
r = (r&~0xFF) | parts[r>>8].type;
if (rr)
*rr = r;
-
- if ((r&0xFF)==PT_VOID || (r&0xFF)==PT_BHOL || (r&0xFF)==PT_NBHL)
- return 1;
-
- if (((r&0xFF)==PT_WHOL||(r&0xFF)==PT_NWHL) && pt==PT_ANAR)
- return 1;
-
- if (pt==PT_SPRK)//spark shouldn't move
+ if (pt>=PT_NUM || (r&0xFF)>=PT_NUM)
return 0;
-
- if (pt==PT_PHOT&&(
- (r&0xFF)==PT_GLAS || (r&0xFF)==PT_PHOT ||
- (r&0xFF)==PT_CLNE || (r&0xFF)==PT_PCLN ||
- (r&0xFF)==PT_GLOW || (r&0xFF)==PT_WATR ||
- (r&0xFF)==PT_DSTW || (r&0xFF)==PT_SLTW ||
- (r&0xFF)==PT_ISOZ || (r&0xFF)==PT_ISZS ||
- (r&0xFF)==PT_FILT || (r&0xFF)==PT_INVIS ||
- (r&0xFF)==PT_QRTZ || (r&0xFF)==PT_PQRT ||
- ((r&0xFF)==PT_LCRY&&parts[r>>8].life > 5)))
- return 2;
-
- if (pt==PT_STKM) //Stick man's head shouldn't collide
- return 2;
- if (pt==PT_STKM2) //Stick man's head shouldn't collide
- return 2;
- if ((pt==PT_BIZR||pt==PT_BIZRG)&&(r&0xFF)==PT_FILT)
- return 2;
- if (bmap[ny/CELL][nx/CELL]==WL_ALLOWGAS && ptypes[pt].falldown!=0 && pt!=PT_FIRE && pt!=PT_SMKE)
- return 0;
- if (ptypes[pt].falldown!=2 && bmap[ny/CELL][nx/CELL]==WL_ALLOWLIQUID)
- return 0;
- if ((pt==PT_NEUT ||pt==PT_PHOT) && bmap[ny/CELL][nx/CELL]==WL_EWALL && !emap[ny/CELL][nx/CELL])
- return 0;
- if (bmap[ny/CELL][nx/CELL]==WL_EHOLE && !emap[ny/CELL][nx/CELL])
- return 2;
- if (bmap[ny/CELL][nx/CELL]==WL_ALLOWAIR)
- return 0;
-
- if (ptypes[pt].falldown!=1 && bmap[ny/CELL][nx/CELL]==WL_ALLOWSOLID)
- return 0;
- if (r && (r&0xFF) < PT_NUM) {
- if (ptypes[pt].properties&TYPE_ENERGY && ptypes[(r&0xFF)].properties&TYPE_ENERGY)
- return 2;
-
- if (pt==PT_NEUT && ptypes[(r&0xFF)].properties&PROP_NEUTPASS)
- return 2;
- if (pt==PT_NEUT && ptypes[(r&0xFF)].properties&PROP_NEUTPENETRATE)
- return 1;
- if ((r&0xFF)==PT_NEUT && ptypes[pt].properties&PROP_NEUTPENETRATE)
+ result = can_move[pt][r&0xFF];
+ if (result==3)
+ {
+ if (pt==PT_PHOT && (r&0xFF)==PT_LCRY)
+ result = (parts[r>>8].life > 5)? 2 : 0;
+ if ((r&0xFF)==PT_INVIS)
+ {
+ if (pv[ny/CELL][nx/CELL]>4.0f || pv[ny/CELL][nx/CELL]<-4.0f) result = 2;
+ else result = 0;
+ }
+ }
+ if (bmap[ny/CELL][nx/CELL])
+ {
+ if (bmap[ny/CELL][nx/CELL]==WL_ALLOWGAS && ptypes[pt].falldown!=0 && pt!=PT_FIRE && pt!=PT_SMKE)
+ return 0;
+ if (bmap[ny/CELL][nx/CELL]==WL_ALLOWLIQUID && ptypes[pt].falldown!=2)
+ return 0;
+ if (bmap[ny/CELL][nx/CELL]==WL_ALLOWSOLID && ptypes[pt].falldown!=1)
+ return 0;
+ // blocking by WL_WALL, WL_WALLELEC and unpowered WL_EWALL is currently done by putting 0x7FFFFFFF in pmap
+ if (bmap[ny/CELL][nx/CELL]==WL_ALLOWAIR)
return 0;
+ if (bmap[ny/CELL][nx/CELL]==WL_EHOLE && !emap[ny/CELL][nx/CELL])
+ return 2;
}
-
- if (r && ((r&0xFF) >= PT_NUM || (ptypes[pt].weight <= ptypes[(r&0xFF)].weight))) //the particle weight check
- return 0;
-
- if (pt == PT_PHOT)
- return 2;
-
- return 1;
+ return result;
}
int try_move(int i, int x, int y, int nx, int ny)
@@ -147,11 +192,9 @@ int try_move(int i, int x, int y, int nx, int ny)
e = eval_move(parts[i].type, nx, ny, &r);
- if ((pmap[ny][nx]&0xFF)==PT_BOMB && parts[i].type==PT_BOMB && parts[i].tmp == 1)
+ if ((r&0xFF)==PT_BOMB && parts[i].type==PT_BOMB && parts[i].tmp == 1)
e = 2;
- if ((pmap[ny][nx]&0xFF)==PT_INVIS && (pv[ny/CELL][nx/CELL]>4.0f ||pv[ny/CELL][nx/CELL]<-4.0f))
- return 1;
/* half-silvered mirror */
if (!e && parts[i].type==PT_PHOT &&
(((r&0xFF)==PT_BMTL && rand()<RAND_MAX/2) ||
@@ -160,6 +203,8 @@ int try_move(int i, int x, int y, int nx, int ny)
if (!e) //if no movement
{
+ if (parts[i].type!=PT_NEUT && parts[i].type!=PT_PHOT)
+ return 0;
if (!legacy_enable && parts[i].type==PT_PHOT && r)//PHOT heat conduction
{
if ((r & 0xFF) == PT_COAL || (r & 0xFF) == PT_BCOL)
@@ -286,28 +331,15 @@ int try_move(int i, int x, int y, int nx, int ny)
return 0;
}
- if ((pmap[ny][nx]&0xFF)==PT_CNCT)//stops CNCT being displaced by other particles
- return 0;
if (parts[i].type==PT_CNCT && y<ny && (pmap[y+1][x]&0xFF)==PT_CNCT)//check below CNCT for another CNCT
return 0;
- if (bmap[ny/CELL][nx/CELL]==WL_EHOLE && !emap[y/CELL][x/CELL])
- return 1;
- if ((bmap[y/CELL][x/CELL]==WL_EHOLE && !emap[y/CELL][x/CELL]) && (bmap[ny/CELL][nx/CELL]!=WL_EHOLE && !emap[ny/CELL][nx/CELL]))
- return 0;
-
- if (r && (r>>8)<NPART && ptypes[r&0xFF].falldown!=2 && bmap[y/CELL][x/CELL]==WL_ALLOWLIQUID)
+ if ((bmap[y/CELL][x/CELL]==WL_EHOLE && !emap[y/CELL][x/CELL]) && !(bmap[ny/CELL][nx/CELL]==WL_EHOLE && !emap[ny/CELL][nx/CELL]))
return 0;
- if (parts[i].type == PT_PHOT)
- return 1;
-
e = r >> 8; //e is now the particle number at r (pmap[ny][nx])
if (r && e<NPART)//the swap part, if we make it this far, swap
{
- if (parts[e].type == PT_PHOT||parts[e].type == PT_NEUT)
- return 1;
-
if (parts[i].type==PT_NEUT) {
// target material is NEUTPENETRATE, meaning it gets moved around when neutron passes
unsigned s = pmap[y][x];