diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2011-06-09 21:35:00 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2011-06-09 21:35:00 (GMT) |
| commit | 1f7106acb16962f925dfccc67dafc39f3bcfd877 (patch) | |
| tree | 324c1f589da96a30205838e372489d9d9bde6132 /src | |
| parent | 1effdb052a0b952d1390109bed67b3371046ccb7 (diff) | |
| download | powder-1f7106acb16962f925dfccc67dafc39f3bcfd877.zip powder-1f7106acb16962f925dfccc67dafc39f3bcfd877.tar.gz | |
Gravity zoning
Diffstat (limited to 'src')
| -rw-r--r-- | src/air.c | 1 | ||||
| -rw-r--r-- | src/graphics.c | 60 | ||||
| -rw-r--r-- | src/main.c | 23 | ||||
| -rw-r--r-- | src/misc.c | 10 | ||||
| -rw-r--r-- | src/powder.c | 94 |
5 files changed, 186 insertions, 2 deletions
@@ -7,6 +7,7 @@ float kernel[9]; float gravmap[YRES/CELL][XRES/CELL]; //Maps to be used by the main thread float gravx[YRES/CELL][XRES/CELL]; float gravy[YRES/CELL][XRES/CELL]; +unsigned gravmask[YRES/CELL][XRES/CELL]; float th_ogravmap[YRES/CELL][XRES/CELL]; // Maps to be processed by the gravity thread float th_gravmap[YRES/CELL][XRES/CELL]; diff --git a/src/graphics.c b/src/graphics.c index aab77ab..669086a 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -656,13 +656,17 @@ void draw_tool(pixel *vid_buf, int b, int sl, int sr, unsigned pc, unsigned iswa int draw_tool_xy(pixel *vid_buf, int x, int y, int b, unsigned pc) { int i, j, c; + pixel gc; if (x > XRES-26 || x < 0) return 26; if (b>=UI_WALLSTART) { int ds = 0; if (b-UI_WALLSTART>=0 && b-UI_WALLSTART<UI_WALLCOUNT) + { ds = wtypes[b-UI_WALLSTART].drawstyle; + gc = wtypes[b-UI_WALLSTART].eglow; + } //x = (2+32*((b-22)/1)); //y = YRES+2+40; if (ds==1) @@ -683,6 +687,17 @@ int draw_tool_xy(pixel *vid_buf, int x, int y, int b, unsigned pc) for (i=1; i<27; i++) vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc; } + else if (ds==4) + { + for (j=1; j<15; j++) + for (i=1; i<27; i++) + if(i%CELL == j%CELL) + vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc; + else if (i%CELL == (j%CELL)+1 || (i%CELL == 0 && j%CELL == CELL-1)) + vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = gc; + else + vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = PIXPACK(0x202020); + } else switch (b) { @@ -1364,6 +1379,26 @@ void draw_air(pixel *vid) } } +void draw_grav_zones(pixel * vid) +{ + int x, y, i, j; + for (y=0; y<YRES/CELL; y++) + { + for (x=0; x<XRES/CELL; x++) + { + if(gravmask[y][x]) + { + for (j=0; j<CELL; j++)//draws the colors + for (i=0; i<CELL; i++) + if(i == j) + drawpixel(vid, x*CELL+i, y*CELL+j, 255, 200, 0, 120); + else + drawpixel(vid, x*CELL+i, y*CELL+j, 32, 32, 32, 120); + } + } + } +} + void draw_grav(pixel *vid) { int x, y, i; @@ -3186,6 +3221,7 @@ void draw_walls(pixel *vid) int x, y, i, j, cr, cg, cb; unsigned char wt; pixel pc; + pixel gc; for (y=0; y<YRES/CELL; y++) for (x=0; x<XRES/CELL; x++) if (bmap[y][x]) @@ -3194,6 +3230,7 @@ void draw_walls(pixel *vid) if (wt<0 || wt>=UI_WALLCOUNT) continue; pc = wtypes[wt].colour; + gc = wtypes[wt].eglow; // standard wall patterns if (wtypes[wt].drawstyle==1) @@ -3214,6 +3251,17 @@ void draw_walls(pixel *vid) for (i=0; i<CELL; i++) vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; } + else if (wtypes[wt].drawstyle==4) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if(i == j) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + else if (i == j+1 || (i == 0 && j == CELL-1)) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = gc; + else + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = PIXPACK(0x202020); + } // special rendering for some walls if (bmap[y][x]==WL_EWALL) @@ -3284,7 +3332,17 @@ void draw_walls(pixel *vid) for (i=0; i<CELL; i++) drawblob(vid, (x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); } - + else if (wtypes[wt].drawstyle==4) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if(i == j) + drawblob(vid, (x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + else if (i == j+1 || (i == 0 && j == CELL-1)) + drawblob(vid, (x*CELL+i), (y*CELL+j), PIXR(gc), PIXG(gc), PIXB(gc)); + else + drawblob(vid, (x*CELL+i), (y*CELL+j), 0x20, 0x20, 0x20); + } if (bmap[y][x]==WL_EWALL) { if (emap[y][x]) @@ -1007,6 +1007,8 @@ int parse_save(void *save, int size, int replace, int x0, int y0, unsigned char else stop_grav_async(); } + + gravity_mask(); if (p >= size) goto version1; @@ -1060,6 +1062,7 @@ corrupt: void clear_sim(void) { + int x, y; memset(bmap, 0, sizeof(bmap)); memset(emap, 0, sizeof(emap)); memset(signs, 0, sizeof(signs)); @@ -1080,6 +1083,15 @@ void clear_sim(void) memset(fire_r, 0, sizeof(fire_r)); memset(fire_g, 0, sizeof(fire_g)); memset(fire_b, 0, sizeof(fire_b)); + memset(gravmask, 0xFF, sizeof(gravmask)); + memset(gravy, 0, sizeof(gravy)); + memset(gravx, 0, sizeof(gravx)); + for(x = 0; x < XRES/CELL; x++){ + for(y = 0; y < YRES/CELL; y++){ + hv[y][x] = 273.15f+22.0f; //Set to room temperature + } + } + gravity_mask(); } // stamps library @@ -1758,6 +1770,12 @@ int main(int argc, char *argv[]) #ifdef OpenGL ClearScreen(); #else + if(gravwl_timeout) + { + if(gravwl_timeout==1) + gravity_mask(); + gravwl_timeout--; + } if (cmode==CM_VEL || cmode==CM_PRESS || cmode==CM_CRACK || (cmode==CM_HEAT && aheat_enable))//air only gets drawn in these modes { draw_air(vid_buf); @@ -1788,6 +1806,8 @@ int main(int argc, char *argv[]) draw_walls(vid_buf); update_particles(vid_buf); //update everything draw_parts(vid_buf); //draw particles + if(sl == WL_GRAV+100 || sr == WL_GRAV+100) + draw_grav_zones(vid_buf); if(ngrav_enable){ pthread_mutex_lock(&gravmutex); @@ -1803,6 +1823,9 @@ int main(int argc, char *argv[]) } } pthread_mutex_unlock(&gravmutex); + //Apply the gravity mask + membwand(gravy, gravmask, sizeof(gravy), sizeof(gravmask)); + membwand(gravx, gravmask, sizeof(gravx), sizeof(gravmask)); } if (!sys_pause||framerender) //Only update if not paused @@ -635,5 +635,15 @@ void RGB_to_HSV(int r,int g,int b,int *h,int *s,int *v)//convert 0-255 RGB value *v = (int)(255.0*x); } } + +void membwand(void * destv, void * srcv, size_t destsize, size_t srcsize) +{ + size_t i; + unsigned char * dest = destv; + unsigned char * src = srcv; + for(i = 0; i < destsize; i++){ + dest[i] = dest[i] & src[i%srcsize]; + } +} vector2d v2d_zero = {0,0}; matrix2d m2d_identity = {1,0,0,1}; diff --git a/src/powder.c b/src/powder.c index 5b3e03c..adb5cb7 100644 --- a/src/powder.c +++ b/src/powder.c @@ -5,6 +5,8 @@ #include <air.h> #include <misc.h> +int gravwl_timeout = 0; + int isplayer = 0; float player[27]; //[0] is a command cell, [3]-[18] are legs positions, [19] is index, [19]-[26] are accelerations float player2[27]; @@ -2428,6 +2430,10 @@ int create_parts(int x, int y, int rx, int ry, int c) b = WL_FANHELPER; dw = 1; } + if (wall == WL_GRAV) + { + gravwl_timeout = 60; + } if (dw==1) { rx = rx/CELL; @@ -2784,4 +2790,90 @@ inline void orbitalparts_set(int *block1, int *block2, int resblock1[], int resb *block1 = block1tmp; *block2 = block2tmp; } - +void grav_mask_r(int x, int y, char checkmap[YRES/CELL][XRES/CELL], char shape[YRES/CELL][XRES/CELL], char *shapeout) +{ + if(x < 0 || x >= XRES/CELL || y < 0 || y >= YRES/CELL) + return; + if(x == 0 || y ==0 || y == (YRES/CELL)-1 || x == (XRES/CELL)-1) + *shapeout = 1; + checkmap[y][x] = 1; + shape[y][x] = 1; + if(x-1 >= 0 && !checkmap[y][x-1] && bmap[y][x-1]!=WL_GRAV) + grav_mask_r(x-1, y, checkmap, shape, shapeout); + if(y-1 >= 0 && !checkmap[y-1][x] && bmap[y-1][x]!=WL_GRAV) + grav_mask_r(x, y-1, checkmap, shape, shapeout); + if(x+1 < XRES/CELL && !checkmap[y][x+1] && bmap[y][x+1]!=WL_GRAV) + grav_mask_r(x+1, y, checkmap, shape, shapeout); + if(y+1 < YRES/CELL && !checkmap[y+1][x] && bmap[y+1][x]!=WL_GRAV) + grav_mask_r(x, y+1, checkmap, shape, shapeout); + return; +} +struct mask_el { + char *shape; + char shapeout; + void *next; +}; +typedef struct mask_el mask_el; +void mask_free(mask_el *c_mask_el){ + if(c_mask_el==NULL) + return; + if(c_mask_el->next!=NULL) + mask_free(c_mask_el->next); + free(c_mask_el->shape); + free(c_mask_el); +} +void gravity_mask() +{ + char checkmap[YRES/CELL][XRES/CELL]; + int x = 0, y = 0; + mask_el *t_mask_el = NULL; + mask_el *c_mask_el = NULL; + memset(checkmap, 0, sizeof(checkmap)); + for(x = 0; x < XRES/CELL; x++) + { + for(y = 0; y < YRES/CELL; y++) + { + if(bmap[y][x]!=WL_GRAV && checkmap[y][x] == 0) + { + //Create a new shape + if(t_mask_el==NULL){ + t_mask_el = malloc(sizeof(mask_el)); + t_mask_el->shape = malloc((XRES/CELL)*(YRES/CELL)); + memset(t_mask_el->shape, 0, (XRES/CELL)*(YRES/CELL)); + t_mask_el->shapeout = 0; + t_mask_el->next = NULL; + c_mask_el = t_mask_el; + } else { + c_mask_el->next = malloc(sizeof(mask_el)); + c_mask_el = c_mask_el->next; + c_mask_el->shape = malloc((XRES/CELL)*(YRES/CELL)); + memset(c_mask_el->shape, 0, (XRES/CELL)*(YRES/CELL)); + c_mask_el->shapeout = 0; + c_mask_el->next = NULL; + } + //Fill the shape + grav_mask_r(x, y, checkmap, c_mask_el->shape, &c_mask_el->shapeout); + } + } + } + c_mask_el = t_mask_el; + memset(gravmask, 0, sizeof(gravmask)); + while(c_mask_el!=NULL) + { + char *cshape = c_mask_el->shape; + for(x = 0; x < XRES/CELL; x++) + { + for(y = 0; y < YRES/CELL; y++) + { + if(cshape[y*(XRES/CELL)+x]){ + if(c_mask_el->shapeout) + gravmask[y][x] = 0xFFFFFFFF; + else + gravmask[y][x] = 0x00000000; + } + } + } + c_mask_el = c_mask_el->next; + } + mask_free(t_mask_el); +} |
