From f603e33e74f82fa14bb6747a43773a8b47ceaa3c Mon Sep 17 00:00:00 2001 From: jacksonmj Date: Sat, 28 May 2011 23:15:29 +0100 Subject: [PATCH] Small speed improvement to eval_move Warning: may be buggy, test thoroughly. --- includes/powder.h | 1 + src/main.c | 1 + src/powder.c | 180 +++++++++++++++++++++++++++------------------- 3 files changed, 108 insertions(+), 74 deletions(-) diff --git a/includes/powder.h b/includes/powder.h index f960ee1ff..4328844ac 100644 --- a/includes/powder.h +++ b/includes/powder.h @@ -862,6 +862,7 @@ unsigned photons[YRES][XRES]; int do_move(int i, int x, int y, float nxf, float nyf); int try_move(int i, int x, int y, int nx, int ny); int eval_move(int pt, int nx, int ny, unsigned *rr); +void init_can_move(); static void create_cherenkov_photon(int pp); static void create_gain_photon(int pp); diff --git a/src/main.c b/src/main.c index 9524c262b..41a6c74fd 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 48265fc00..cdff22349 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=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) - return 0; + 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 (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; + 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; + } + 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()>8)> 8; //e is now the particle number at r (pmap[ny][nx]) if (r && e