diff options
| author | Philip <philip@philip-linuxlaptop.(none)> | 2010-10-28 23:18:06 (GMT) |
|---|---|---|
| committer | Philip <philip@philip-linuxlaptop.(none)> | 2010-10-28 23:18:06 (GMT) |
| commit | bff5961d602531b224821da54a874a09f1dba317 (patch) | |
| tree | 5663de4f3f51edb932e19acfd20b42cd6622e30d /src | |
| parent | e4f9f77de906d65264c7d09635761dd05940e1aa (diff) | |
| download | powder-bff5961d602531b224821da54a874a09f1dba317.zip powder-bff5961d602531b224821da54a874a09f1dba317.tar.gz | |
updating
Diffstat (limited to 'src')
| -rw-r--r-- | src/graphics.c | 244 | ||||
| -rw-r--r-- | src/interface.c | 708 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/main.c | 21 | ||||
| -rw-r--r-- | src/powder.c | 436 |
4 files changed, 1148 insertions, 261 deletions
diff --git a/src/graphics.c b/src/graphics.c index 2c9a686..d6604a3 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -745,15 +745,15 @@ int draw_tool_xy(pixel *vid_buf, int x, int y, int b, unsigned pc) void draw_menu(pixel *vid_buf, int i, int hover) { - drawrect(vid_buf, XRES-2, (i*16)+YRES+MENUSIZE-16-(SC_TOTAL*16), 14, 14, 255, 255, 255, 255); + drawrect(vid_buf, (XRES+BARSIZE)-16, (i*16)+YRES+MENUSIZE-16-(SC_TOTAL*16), 14, 14, 255, 255, 255, 255); if(hover==i) { - fillrect(vid_buf, XRES-2, (i*16)+YRES+MENUSIZE-16-(SC_TOTAL*16), 14, 14, 255, 255, 255, 255); - drawtext(vid_buf, XRES+1, (i*16)+YRES+MENUSIZE-14-(SC_TOTAL*16), msections[i].icon, 0, 0, 0, 255); + fillrect(vid_buf, (XRES+BARSIZE)-16, (i*16)+YRES+MENUSIZE-16-(SC_TOTAL*16), 14, 14, 255, 255, 255, 255); + drawtext(vid_buf, (XRES+BARSIZE)-13, (i*16)+YRES+MENUSIZE-14-(SC_TOTAL*16), msections[i].icon, 0, 0, 0, 255); } else { - drawtext(vid_buf, XRES+1, (i*16)+YRES+MENUSIZE-14-(SC_TOTAL*16), msections[i].icon, 255, 255, 255, 255); + drawtext(vid_buf, (XRES+BARSIZE)-13, (i*16)+YRES+MENUSIZE-14-(SC_TOTAL*16), msections[i].icon, 255, 255, 255, 255); } } @@ -844,6 +844,62 @@ int drawtext(pixel *vid, int x, int y, const char *s, int r, int g, int b, int a #endif return x; } +int drawtextwrap(pixel *vid, int x, int y, int w, const char *s, int r, int g, int b, int a) +{ +#ifdef OpenGL +#else + int sx = x; + int rh = 12; + int rw = 0; + int cw = x; + for(; *s; s++) + { + if(*s == '\n') + { + x = sx; + rw = 0; + y += FONT_H+2; + } + else if(*s == '\b') + { + switch(s[1]) + { + case 'w': + r = g = b = 255; + break; + case 'g': + r = g = b = 192; + break; + case 'o': + r = 255; + g = 216; + b = 32; + break; + case 'r': + r = 255; + g = b = 0; + break; + case 'b': + r = g = 0; + b = 255; + break; + } + s++; + } + else + { + if(x-cw>=w) { + x = sx; + rw = 0; + y+=FONT_H+2; + rh+=FONT_H+2; + } + x = drawchar(vid, x, y, *(unsigned char *)s, r, g, b, a); + } + } +#endif + return rh; +} void drawrect(pixel *vid, int x, int y, int w, int h, int r, int g, int b, int a) { @@ -946,6 +1002,19 @@ int textnwidth(char *s, int n) } return x-1; } +int textnheight(char *s, int n, int w) +{ + int x = 0; + //TODO: Implement Textnheight for wrapped text + for(; *s; s++) + { + if(!n) + break; + x += font_data[font_ptrs[(int)(*(unsigned char *)s)]]; + n--; + } + return x-1; +} int textwidthx(char *s, int w) { @@ -1420,20 +1489,20 @@ void draw_parts(pixel *vid) cg = 0; cb = 0; cr = 0; - for(x=0; x<12; x++) { - cr += (parts[i].ctype >> (x+18)) & 1; - cb += (parts[i].ctype >> x) & 1; - } - for(x=0; x<14; x++) - cg += (parts[i].ctype >> (x+9)) & 1; - x = 624/(cr+cg+cb+1); - cr *= x; - cg *= x; - cb *= x; + for(x=0; x<12; x++) { + cr += (parts[i].ctype >> (x+18)) & 1; + cb += (parts[i].ctype >> x) & 1; + } + for(x=0; x<14; x++) + cg += (parts[i].ctype >> (x+9)) & 1; + x = 624/(cr+cg+cb+1); + cr *= x; + cg *= x; + cb *= x; vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(cr>255?255:cr,cg>255?255:cg,cb>255?255:cb); - cr >>= 4; - cg >>= 4; - cb >>= 4; + cr >>= 4; + cg >>= 4; + cb >>= 4; x = nx/CELL; y = ny/CELL; cg += fire_g[y][x]; @@ -1448,9 +1517,22 @@ void draw_parts(pixel *vid) } else { - cr = 0xFF; - cg = 0xFF; - cb = 0xFF; + cg = 0; + cb = 0; + cr = 0; + for(x=0; x<12; x++) { + cr += (parts[i].ctype >> (x+18)) & 1; + cb += (parts[i].ctype >> x) & 1; + } + for(x=0; x<14; x++) + cg += (parts[i].ctype >> (x+9)) & 1; + x = 624/(cr+cg+cb+1); + cr *= x; + cg *= x; + cb *= x; + cr = cr>255?255:cr; + cg = cg>255?255:cg; + cb = cb>255?255:cb; blendpixel(vid, nx, ny, cr, cg, cb, 192); blendpixel(vid, nx+1, ny, cr, cg, cb, 96); blendpixel(vid, nx-1, ny, cr, cg, cb, 96); @@ -1883,45 +1965,48 @@ void draw_parts(pixel *vid) } else if(t==PT_FIRE && parts[i].life) { - float ttemp = (float)parts[i].life; - int caddress = restrict_flt(restrict_flt(ttemp, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); - uint8 R = flm_data[caddress]; - uint8 G = flm_data[caddress+1]; - uint8 B = flm_data[caddress+2]; - if(cmode == 3||cmode==4 || cmode==6) - { - cr = R/8; - cg = G/8; - cb = B/8; - x = nx/CELL; - y = ny/CELL; - cg += fire_g[y][x]; - if(cg > 255) cg = 255; - fire_g[y][x] = cg; - cb += fire_b[y][x]; - if(cb > 255) cb = 255; - fire_b[y][x] = cb; - cr += fire_r[y][x]; - if(cr > 255) cr = 255; - fire_r[y][x] = cr; - } - else - { - cr = R; - cg = G; - cb = B; - blendpixel(vid, nx, ny, cr, cg, cb, 192); - blendpixel(vid, nx+1, ny, cr, cg, cb, 96); - blendpixel(vid, nx-1, ny, cr, cg, cb, 96); - blendpixel(vid, nx, ny+1, cr, cg, cb, 96); - blendpixel(vid, nx, ny-1, cr, cg, cb, 96); - blendpixel(vid, nx+1, ny-1, cr, cg, cb, 32); - blendpixel(vid, nx-1, ny+1, cr, cg, cb, 32); - blendpixel(vid, nx+1, ny+1, cr, cg, cb, 32); - blendpixel(vid, nx-1, ny-1, cr, cg, cb, 32); - } - // Older Code - /*if(cmode == 3||cmode==4 || cmode==6) + float ttemp = (float)((int)(parts[i].life/2)); + int caddress = restrict_flt(restrict_flt(ttemp, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + uint8 R = flm_data[caddress]; + uint8 G = flm_data[caddress+1]; + uint8 B = flm_data[caddress+2]; + if(cmode == 3||cmode==4 || cmode==6) + { + cr = R/8; + cg = G/8; + cb = B/8; + x = nx/CELL; + y = ny/CELL; + cg += fire_g[y][x]; + if(cg > 255) cg = 255; + fire_g[y][x] = cg; + cb += fire_b[y][x]; + if(cb > 255) cb = 255; + fire_b[y][x] = cb; + cr += fire_r[y][x]; + if(cr > 255) cr = 255; + fire_r[y][x] = cr; + } + else + { + cr = parts[i].life * 8; + cg = parts[i].life * 2; + cb = parts[i].life; + if(cr>255) cr = 255; + if(cg>192) cg = 212; + if(cb>128) cb = 192; + blendpixel(vid, nx, ny, cr, cg, cb, 255); + blendpixel(vid, nx+1, ny, cr, cg, cb, 96); + blendpixel(vid, nx-1, ny, cr, cg, cb, 96); + blendpixel(vid, nx, ny+1, cr, cg, cb, 96); + blendpixel(vid, nx, ny-1, cr, cg, cb, 96); + blendpixel(vid, nx+1, ny-1, cr, cg, cb, 32); + blendpixel(vid, nx-1, ny+1, cr, cg, cb, 32); + blendpixel(vid, nx+1, ny+1, cr, cg, cb, 32); + blendpixel(vid, nx-1, ny-1, cr, cg, cb, 32); + } + // Older Code + /*if(cmode == 3||cmode==4 || cmode==6) { cr = parts[i].life / 4; cg = parts[i].life / 16; @@ -2065,23 +2150,42 @@ void draw_parts(pixel *vid) } if(cmode == 4&&t!=PT_FIRE&&t!=PT_PLSM&&t!=PT_HFLM&&t!=PT_NONE&&t!=PT_ACID&&t!=PT_LCRY&&t!=PT_GLOW&&t!=PT_SWCH&&t!=PT_SMKE&&t!=PT_WTRV&&!(t==PT_FIRW&&parts[i].tmp==3)) { - uint8 R = PIXR(ptypes[t].pcolors); - uint8 G = PIXG(ptypes[t].pcolors); - uint8 B = PIXB(ptypes[t].pcolors); + if(t==PT_PHOT) { + cg = 0; + cb = 0; + cr = 0; + for(x=0; x<12; x++) { + cr += (parts[i].ctype >> (x+18)) & 1; + cb += (parts[i].ctype >> x) & 1; + } + for(x=0; x<14; x++) + cg += (parts[i].ctype >> (x+9)) & 1; + x = 624/(cr+cg+cb+1); + cr *= x; + cg *= x; + cb *= x; + cr = cr>255?255:cr; + cg = cg>255?255:cg; + cb = cb>255?255:cb; + } else { + cr = PIXR(ptypes[t].pcolors); + cg = PIXG(ptypes[t].pcolors); + cb = PIXB(ptypes[t].pcolors); + } //if(vid[(ny-1)*YRES+(nx-1)]!=0){ // blendpixel(vid, nx, ny-1, R, G, B, 46); //} - blendpixel(vid, nx+1, ny, R, G, B, 223); - blendpixel(vid, nx-1, ny, R, G, B, 223); - blendpixel(vid, nx, ny+1, R, G, B, 223); - blendpixel(vid, nx, ny-1, R, G, B, 223); + blendpixel(vid, nx+1, ny, cr, cg, cb, 223); + blendpixel(vid, nx-1, ny, cr, cg, cb, 223); + blendpixel(vid, nx, ny+1, cr, cg, cb, 223); + blendpixel(vid, nx, ny-1, cr, cg, cb, 223); - blendpixel(vid, nx+1, ny-1, R, G, B, 112); - blendpixel(vid, nx-1, ny-1, R, G, B, 112); - blendpixel(vid, nx+1, ny+1, R, G, B, 112); - blendpixel(vid, nx-1, ny+1, R, G, B, 112); + blendpixel(vid, nx+1, ny-1, cr, cg, cb, 112); + blendpixel(vid, nx-1, ny-1, cr, cg, cb, 112); + blendpixel(vid, nx+1, ny+1, cr, cg, cb, 112); + blendpixel(vid, nx-1, ny+1, cr, cg, cb, 112); } } #endif diff --git a/src/interface.c b/src/interface.c index bdec111..4ab7bf4 100644 --- a/src/interface.c +++ b/src/interface.c @@ -1,3 +1,6 @@ +#ifdef MACOSX +#include <CoreFoundation/CFString.h> +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -46,6 +49,7 @@ void *search_thumbs[GRID_X*GRID_Y]; int search_thsizes[GRID_X*GRID_Y]; int search_own = 0; +int search_fav = 0; int search_date = 0; int search_page = 0; char search_expr[256] = ""; @@ -207,7 +211,7 @@ void add_sign_ui(pixel *vid_buf, int mx, int my) strcpy(signs[i].text, ed.str); signs[i].ju = ju; } - +//TODO: Finish text wrapping in text edits void ui_edit_draw(pixel *vid_buf, ui_edit *ed) { int cx, i; @@ -225,8 +229,13 @@ void ui_edit_draw(pixel *vid_buf, ui_edit *ed) if(ed->str[0]) { - drawtext(vid_buf, ed->x, ed->y, str, 255, 255, 255, 255); - drawtext(vid_buf, ed->x+ed->w-11, ed->y-1, "\xAA", 128, 128, 128, 255); + if(ed->multiline){ + drawtextwrap(vid_buf, ed->x, ed->y, ed->w-14, str, 255, 255, 255, 255); + drawtext(vid_buf, ed->x+ed->w-11, ed->y-1, "\xAA", 128, 128, 128, 255); + } else { + drawtext(vid_buf, ed->x, ed->y, str, 255, 255, 255, 255); + drawtext(vid_buf, ed->x+ed->w-11, ed->y-1, "\xAA", 128, 128, 128, 255); + } } else if(!ed->focus) drawtext(vid_buf, ed->x, ed->y, ed->def, 128, 128, 128, 255); @@ -258,19 +267,35 @@ void ui_edit_process(int mx, int my, int mb, ui_edit *ed) else str = ed->str; - if(mx>=ed->x+ed->w-11 && mx<ed->x+ed->w && my>=ed->y-5 && my<ed->y+11) - { - ed->focus = 1; - ed->cursor = 0; - ed->str[0] = 0; - } - else if(mx>=ed->x-ed->nx && mx<ed->x+ed->w && my>=ed->y-5 && my<ed->y+11) - { - ed->focus = 1; - ed->cursor = textwidthx(str, mx-ed->x); - } - else - ed->focus = 0; + if(ed->multiline){ + if(mx>=ed->x+ed->w-11 && mx<ed->x+ed->w && my>=ed->y-5 && my<ed->y+11) + { + ed->focus = 1; + ed->cursor = 0; + ed->str[0] = 0; + } + else if(mx>=ed->x-ed->nx && mx<ed->x+ed->w && my>=ed->y-5 && my<ed->y+ed->h) + { + ed->focus = 1; + ed->cursor = textwidthx(str, mx-ed->x); + } + else + ed->focus = 0; + } else { + if(mx>=ed->x+ed->w-11 && mx<ed->x+ed->w && my>=ed->y-5 && my<ed->y+11) + { + ed->focus = 1; + ed->cursor = 0; + ed->str[0] = 0; + } + else if(mx>=ed->x-ed->nx && mx<ed->x+ed->w && my>=ed->y-5 && my<ed->y+11) + { + ed->focus = 1; + ed->cursor = textwidthx(str, mx-ed->x); + } + else + ed->focus = 0; + } } if(ed->focus && sdl_key) { @@ -335,19 +360,19 @@ void ui_edit_process(int mx, int my, int mb, ui_edit *ed) } ts[0]=ed->hide?0x8D:ch; ts[1]=0; - if(textwidth(str)+textwidth(ts) > ed->w-14) + if((textwidth(str)+textwidth(ts) > ed->w-14 && !ed->multiline) || (float)(((textwidth(str)+textwidth(ts))/(ed->w-14)*12) > ed->h && ed->multiline)) break; memmove(ed->str+ed->cursor+1, ed->str+ed->cursor, l+1-ed->cursor); ed->str[ed->cursor] = ch; ed->cursor++; } #else - if(sdl_ascii>=' ' && sdl_ascii<127) + if(sdl_ascii>=' ' && sdl_ascii<127 && l<255) { ch = sdl_ascii; ts[0]=ed->hide?0x8D:ch; ts[1]=0; - if(textwidth(str)+textwidth(ts) > ed->w-14) + if((textwidth(str)+textwidth(ts) > ed->w-14 && !ed->multiline) || (float)(((textwidth(str)+textwidth(ts))/(ed->w-14)*12) > ed->h && ed->multiline)) break; memmove(ed->str+ed->cursor+1, ed->str+ed->cursor, l+1-ed->cursor); ed->str[ed->cursor] = ch; @@ -1121,6 +1146,7 @@ int save_name_ui(pixel *vid_buf) ed.focus = 1; ed.hide = 0; ed.cursor = strlen(svf_name); + ed.multiline = 0; strcpy(ed.str, svf_name); cb.x = x0+10; @@ -1759,7 +1785,7 @@ corrupt: int search_ui(pixel *vid_buf) { - int uih=0,nyu,nyd,b=1,bq,mx=0,my=0,mxq=0,myq=0,mmt=0,gi,gj,gx,gy,pos,i,mp,dp,dap,own,last_own=search_own,page_count=0,last_page=0,last_date=0,j,w,h,st=0,lv; + int uih=0,nyu,nyd,b=1,bq,mx=0,my=0,mxq=0,myq=0,mmt=0,gi,gj,gx,gy,pos,i,mp,dp,dap,own,last_own=search_own,last_fav=search_fav,page_count=0,last_page=0,last_date=0,j,w,h,st=0,lv; int is_p1=0, exp_res=GRID_X*GRID_Y, tp, view_own=0; int thumb_drawn[GRID_X*GRID_Y]; pixel *v_buf = (pixel *)malloc(((YRES+MENUSIZE)*(XRES+BARSIZE))*PIXELSIZE); @@ -1817,6 +1843,7 @@ int search_ui(pixel *vid_buf) ed.focus = 1; ed.hide = 0; ed.cursor = strlen(search_expr); + ed.multiline = 0; strcpy(ed.str, search_expr); sdl_wheel = 0; @@ -1851,39 +1878,50 @@ int search_ui(pixel *vid_buf) if(!svf_login) { search_own = 0; - drawrect(vid_buf, XRES-64, 8, 56, 16, 96, 96, 96, 255); - drawtext(vid_buf, XRES-61, 11, "\x94", 96, 80, 16, 255); - drawtext(vid_buf, XRES-61, 11, "\x93", 128, 128, 128, 255); - drawtext(vid_buf, XRES-46, 13, "My Own", 128, 128, 128, 255); + drawrect(vid_buf, XRES-64+16, 8, 56, 16, 96, 96, 96, 255); + drawtext(vid_buf, XRES-61+16, 11, "\x94", 96, 80, 16, 255); + drawtext(vid_buf, XRES-61+16, 11, "\x93", 128, 128, 128, 255); + drawtext(vid_buf, XRES-46+16, 13, "My Own", 128, 128, 128, 255); } else if(search_own) { - fillrect(vid_buf, XRES-65, 7, 58, 18, 255, 255, 255, 255); - drawtext(vid_buf, XRES-61, 11, "\x94", 192, 160, 64, 255); - drawtext(vid_buf, XRES-61, 11, "\x93", 32, 32, 32, 255); - drawtext(vid_buf, XRES-46, 13, "My Own", 0, 0, 0, 255); + fillrect(vid_buf, XRES-65+16, 7, 58, 18, 255, 255, 255, 255); + drawtext(vid_buf, XRES-61+16, 11, "\x94", 192, 160, 64, 255); + drawtext(vid_buf, XRES-61+16, 11, "\x93", 32, 32, 32, 255); + drawtext(vid_buf, XRES-46+16, 13, "My Own", 0, 0, 0, 255); } else { - drawrect(vid_buf, XRES-64, 8, 56, 16, 192, 192, 192, 255); - drawtext(vid_buf, XRES-61, 11, "\x94", 192, 160, 32, 255); - drawtext(vid_buf, XRES-61, 11, "\x93", 255, 255, 255, 255); - drawtext(vid_buf, XRES-46, 13, "My Own", 255, 255, 255, 255); + drawrect(vid_buf, XRES-64+16, 8, 56, 16, 192, 192, 192, 255); + drawtext(vid_buf, XRES-61+16, 11, "\x94", 192, 160, 32, 255); + drawtext(vid_buf, XRES-61+16, 11, "\x93", 255, 255, 255, 255); + drawtext(vid_buf, XRES-46+16, 13, "My Own", 255, 255, 255, 255); + } + + if(search_fav) + { + fillrect(vid_buf, XRES-134, 7, 18, 18, 255, 255, 255, 255); + drawtext(vid_buf, XRES-130, 11, "\xCC", 192, 160, 64, 255); + } + else + { + drawrect(vid_buf, XRES-134, 8, 16, 16, 192, 192, 192, 255); + drawtext(vid_buf, XRES-130, 11, "\xCC", 192, 160, 32, 255); } if(search_date) { - fillrect(vid_buf, XRES-130, 7, 62, 18, 255, 255, 255, 255); - drawtext(vid_buf, XRES-126, 11, "\xA6", 32, 32, 32, 255); - drawtext(vid_buf, XRES-111, 13, "By date", 0, 0, 0, 255); + fillrect(vid_buf, XRES-130+16, 7, 62, 18, 255, 255, 255, 255); + drawtext(vid_buf, XRES-126+16, 11, "\xA6", 32, 32, 32, 255); + drawtext(vid_buf, XRES-111+16, 13, "By date", 0, 0, 0, 255); } else { - drawrect(vid_buf, XRES-129, 8, 60, 16, 192, 192, 192, 255); - drawtext(vid_buf, XRES-126, 11, "\xA9", 144, 48, 32, 255); - drawtext(vid_buf, XRES-126, 11, "\xA8", 32, 144, 32, 255); - drawtext(vid_buf, XRES-126, 11, "\xA7", 255, 255, 255, 255); - drawtext(vid_buf, XRES-111, 13, "By votes", 255, 255, 255, 255); + drawrect(vid_buf, XRES-129+16, 8, 60, 16, 192, 192, 192, 255); + drawtext(vid_buf, XRES-126+16, 11, "\xA9", 144, 48, 32, 255); + drawtext(vid_buf, XRES-126+16, 11, "\xA8", 32, 144, 32, 255); + drawtext(vid_buf, XRES-126+16, 11, "\xA7", 255, 255, 255, 255); + drawtext(vid_buf, XRES-111+16, 13, "By votes", 255, 255, 255, 255); } if(search_page) @@ -2133,16 +2171,21 @@ int search_ui(pixel *vid_buf) if(sdl_key==SDLK_ESCAPE) goto finish; - if(b && !bq && mx>=XRES-64 && mx<=XRES-8 && my>=8 && my<=24 && svf_login) + if(b && !bq && mx>=XRES-64+16 && mx<=XRES-8+16 && my>=8 && my<=24 && svf_login) { search_own = !search_own; lasttime = TIMEOUT; } - if(b && !bq && mx>=XRES-129 && mx<=XRES-65 && my>=8 && my<=24) + if(b && !bq && mx>=XRES-129+16 && mx<=XRES-65+16 && my>=8 && my<=24) { search_date = !search_date; lasttime = TIMEOUT; } + if(b && !bq && mx>=XRES-134 && mx<=XRES-134+16 && my>=8 && my<=24) + { + search_fav = !search_fav; + lasttime = TIMEOUT; + } if(b && !bq && dp!=-1) if(confirm_ui(vid_buf, "Do you want to delete?", search_names[dp], "Delete")) @@ -2180,6 +2223,10 @@ int search_ui(pixel *vid_buf) if((b && !bq && mp!=-1 && !st && !uih) || do_open==1) { + if(open_ui(vid_buf, search_ids[mp], search_dates[mp]?search_dates[mp]:NULL)==1) { + goto finish; + } + /* fillrect(vid_buf, 0, 0, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 255); info_box(vid_buf, "Loading..."); @@ -2300,17 +2347,17 @@ int search_ui(pixel *vid_buf) if(data) free(data); - goto finish; + goto finish;*/ } if(!last) { search = 1; } - else if(!active && (strcmp(last, ed.str) || last_own!=search_own || last_date!=search_date || last_page!=search_page)) + else if(!active && (strcmp(last, ed.str) || last_own!=search_own || last_date!=search_date || last_page!=search_page || last_fav!=search_fav)) { search = 1; - if(strcmp(last, ed.str) || last_own!=search_own || last_date!=search_date) + if(strcmp(last, ed.str) || last_own!=search_own || last_fav!=search_fav || last_date!=search_date) { search_page = 0; page_count = 0; @@ -2328,8 +2375,10 @@ int search_ui(pixel *vid_buf) last_own = search_own; last_date = search_date; last_page = search_page; + last_fav = search_fav; active = 1; - uri = malloc(strlen(last)*3+80+strlen(SERVER)+strlen(svf_user)); + // TODO: Create a better fix for this bug + uri = malloc(strlen(last)*3+180+strlen(SERVER)+strlen(svf_user)+20); //Increase "padding" from 80 to 180 to fix the search memory corruption bug if(search_own || svf_admin || svf_mod) tmp = "&ShowVotes=true"; else @@ -2358,6 +2407,10 @@ int search_ui(pixel *vid_buf) strcaturl(uri, " user:"); strcaturl(uri, svf_user); } + if(search_fav) + { + strcaturl(uri, " cat:favs"); + } if(search_date) strcaturl(uri, " sort:date"); @@ -2495,6 +2548,449 @@ finish: return 0; } +int open_ui(pixel *vid_buf, char *save_id, char *save_date) +{ + int b=1,bq,mx,my,ca=0,thumb_w,thumb_h,active=0,active_2=0,cc=0,ccy=0,cix=0,hasdrawninfo=0,hasdrawnthumb=0,authoritah=0,myown=0,queue_open=0,data_size=0,retval=0,bc=255,openable=1; + char *uri, *uri_2, *o_uri; + void *data, *info_data; + save_info *info = malloc(sizeof(save_info)); + void *http = NULL, *http_2 = NULL; + int lasttime = TIMEOUT; + int status, status_2, info_ready = 0, data_ready = 0; + time_t http_last_use = HTTP_TIMEOUT, http_last_use_2 = HTTP_TIMEOUT; + pixel *save_pic;// = malloc((XRES/2)*(YRES/2)); + ui_edit ed; + + pixel *old_vid=(pixel *)calloc((XRES+BARSIZE)*(YRES+MENUSIZE), PIXELSIZE); + fillrect(vid_buf, -1, -1, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 192); + + fillrect(vid_buf, 50, 50, XRES+BARSIZE-100, YRES+MENUSIZE-100, 0, 0, 0, 255); + drawrect(vid_buf, 50, 50, XRES+BARSIZE-100, YRES+MENUSIZE-100, 255, 255, 255, 255); + drawrect(vid_buf, 50, 50, (XRES/2)+1, (YRES/2)+1, 255, 255, 255, 155); + drawrect(vid_buf, 50+(XRES/2)+1, 50, XRES+BARSIZE-100-((XRES/2)+1), YRES+MENUSIZE-100, 155, 155, 155, 255); + drawtext(vid_buf, 50+(XRES/4)-textwidth("Loading...")/2, 50+(YRES/4), "Loading...", 255, 255, 255, 128); + + ed.x = 57+(XRES/2)+1; + ed.y = YRES+MENUSIZE-118; + ed.w = XRES+BARSIZE-114-((XRES/2)+1); + ed.h = 48; + ed.nx = 1; + ed.def = "Add comment"; + ed.focus = 1; + ed.hide = 0; + ed.multiline = 1; + ed.cursor = 0; + strcpy(ed.str, ""); + + memcpy(old_vid, vid_buf, ((XRES+BARSIZE)*(YRES+MENUSIZE))*PIXELSIZE); + + while(!sdl_poll()) + { + b = SDL_GetMouseState(&mx, &my); + if(!b) + break; + } + + //Begin Async loading of data + if(save_date) { + // We're loading an historical save + uri = malloc(strlen(save_id)*3+strlen(save_date)*3+strlen(SERVER)+71); + strcpy(uri, "http://" SERVER "/Get.api?Op=save&ID="); + strcaturl(uri, save_id); + strappend(uri, "&Date="); + strcaturl(uri, save_date); + + uri_2 = malloc(strlen(save_id)*3+strlen(save_date)*3+strlen(SERVER)+71); + strcpy(uri_2, "http://" SERVER "/Info.api?ID="); + strcaturl(uri_2, save_id); + strappend(uri_2, "&Date="); + strcaturl(uri_2, save_date); + } else { + //We're loading a normal save + uri = malloc(strlen(save_id)*3+strlen(SERVER)+64); + strcpy(uri, "http://" SERVER "/Get.api?Op=save&ID="); + strcaturl(uri, save_id); + + uri_2 = malloc(strlen(save_id)*3+strlen(SERVER)+64); + strcpy(uri_2, "http://" SERVER "/Info.api?ID="); + strcaturl(uri_2, save_id); + } + http = http_async_req_start(http, uri, NULL, 0, 1); + http_2 = http_async_req_start(http_2, uri_2, NULL, 0, 1); + if(svf_login) + { + http_auth_headers(http, svf_user, svf_pass); + http_auth_headers(http_2, svf_user, svf_pass); + } + http_last_use = time(NULL); + http_last_use_2 = time(NULL); + free(uri); + free(uri_2); + active = 1; + active_2 = 1; + while(!sdl_poll()) + { + bq = b; + b = SDL_GetMouseState(&mx, &my); + mx /= sdl_scale; + my /= sdl_scale; + + if(active && http_async_req_status(http)) + { + int imgh, imgw, nimgh, nimgw; + http_last_use = time(NULL); + data = http_async_req_stop(http, &status, &data_size); + if(status == 200) + { + pixel *full_save = prerender_save(data, data_size, &imgw, &imgh); + save_pic = rescale_img(full_save, imgw, imgh, &thumb_w, &thumb_h, 2); + data_ready = 1; + free(full_save); + } + active = 0; + free(http); + http = NULL; + } + if(active_2 && http_async_req_status(http_2)) + { + http_last_use_2 = time(NULL); + info_data = http_async_req_stop(http_2, &status_2, NULL); + if(status_2 == 200) + { + info_ready = info_parse(info_data, info); + if(info_ready==-1) { + error_ui(vid_buf, 0, "Not found"); + break; + } + } + free(info_data); + active_2 = 0; + free(http_2); + http_2 = NULL; + } + + if(data_ready && !hasdrawnthumb) { + draw_image(vid_buf, save_pic, 51, 51, thumb_w, thumb_h, 255); + hasdrawnthumb = 1; + memcpy(old_vid, vid_buf, ((XRES+BARSIZE)*(YRES+MENUSIZE))*PIXELSIZE); + } + if(info_ready && !hasdrawninfo) { + //drawtext(vid_buf, 2, 2, info->name, 255, 255, 255, 255); + cix = drawtext(vid_buf, 60, (YRES/2)+60, info->name, 255, 255, 255, 255); + cix = drawtext(vid_buf, 60, (YRES/2)+72, "Author:", 255, 255, 255, 155); + cix = drawtext(vid_buf, cix+4, (YRES/2)+72, info->author, 255, 255, 255, 255); + cix = drawtext(vid_buf, cix+4, (YRES/2)+72, "Date:", 255, 255, 255, 155); + cix = drawtext(vid_buf, cix+4, (YRES/2)+72, info->date, 255, 255, 255, 255); + drawtextwrap(vid_buf, 62, (YRES/2)+86, (XRES/2)-24, info->description, 255, 255, 255, 200); + + ccy = 0; + for(cc=0; cc<info->comment_count; cc++) { + drawtext(vid_buf, 60+(XRES/2)+1, ccy+60, info->commentauthors[cc], 255, 255, 255, 255); + ccy += 12; + ccy += drawtextwrap(vid_buf, 60+(XRES/2)+1, ccy+60, XRES+BARSIZE-100-((XRES/2)+1)-20, info->comments[cc], 255, 255, 255, 185); + ccy += 10; + draw_line(vid_buf, 50+(XRES/2)+2, ccy+52, XRES+BARSIZE-50, ccy+52, 100, 100, 100, XRES+BARSIZE); + } + hasdrawninfo = 1; + myown = svf_login && !strcmp(info->author, svf_user); + authoritah = svf_login && (!strcmp(info->author, svf_user) || svf_admin || svf_mod); + memcpy(old_vid, vid_buf, ((XRES+BARSIZE)*(YRES+MENUSIZE))*PIXELSIZE); + } + if(info_ready && svf_login){ + + fillrect(vid_buf, 50+(XRES/2)+1, YRES+MENUSIZE-125, XRES+BARSIZE-100-((XRES/2)+1), 75, 0, 0, 0, 255); + drawrect(vid_buf, 50+(XRES/2)+1, YRES+MENUSIZE-125, XRES+BARSIZE-100-((XRES/2)+1), 75, 200, 200, 200, 255); + + drawrect(vid_buf, 54+(XRES/2)+1, YRES+MENUSIZE-121, XRES+BARSIZE-108-((XRES/2)+1), 48, 255, 255, 255, 200); + + ui_edit_draw(vid_buf, &ed); + + drawrect(vid_buf, XRES+BARSIZE-100, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, 255); + drawtext(vid_buf, XRES+BARSIZE-90, YRES+MENUSIZE-63, "Submit", 255, 255, 255, 255); + } + + if(queue_open) { + if(info_ready && data_ready) { + // Do Open! + status = parse_save(data, data_size, 1, 0, 0); + if(!status) { + //if(svf_last) + //free(svf_last); + svf_last = data; + svf_lsize = data_size; + + svf_open = 1; + svf_own = svf_login && !strcmp(info->author, svf_user); + svf_publish = info->publish && svf_login && !strcmp(info->author, svf_user); + + strcpy(svf_id, save_id); + strcpy(svf_name, info->name); + if(info->tags) + { + strncpy(svf_tags, info->tags, 255); + svf_tags[255] = 0; + } else { + svf_tags[0] = 0; + } + svf_myvote = info->myvote; + retval = 1; + break; + } else { + queue_open = 0; + + svf_open = 0; + svf_publish = 0; + svf_own = 0; + svf_myvote = 0; + svf_id[0] = 0; + svf_name[0] = 0; + svf_tags[0] = 0; + if(svf_last) + free(svf_last); + svf_last = NULL; + error_ui(vid_buf, 0, "An Error Occurred"); + } + } else { + fillrect(vid_buf, -1, -1, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 190); + drawtext(vid_buf, XRES+BARSIZE/2, XRES+MENUSIZE, "Loading...", 0, 0, 0, 200); + } + } + + //Open Button + bc = openable?255:150; + drawrect(vid_buf, 50, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, bc); + drawtext(vid_buf, 73, YRES+MENUSIZE-63, "Open", 255, 255, 255, bc); + drawtext(vid_buf, 58, YRES+MENUSIZE-64, "\x81", 255, 255, 255, bc); + //Fav Button + bc = svf_login?255:150; + drawrect(vid_buf, 100, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, bc); + drawtext(vid_buf, 122, YRES+MENUSIZE-63, "Fav.", 255, 255, 255, bc); + drawtext(vid_buf, 107, YRES+MENUSIZE-64, "\xCC", 255, 255, 255, bc); + //Report Button + bc = (svf_login && info_ready)?255:150; + drawrect(vid_buf, 150, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, bc); + drawtext(vid_buf, 168, YRES+MENUSIZE-63, "Report", 255, 255, 255, bc); + drawtext(vid_buf, 158, YRES+MENUSIZE-63, "!", 255, 255, 255, bc); + //Delete Button + bc = authoritah?255:150; + drawrect(vid_buf, 200, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, bc); + drawtext(vid_buf, 218, YRES+MENUSIZE-63, "Delete", 255, 255, 255, bc); + drawtext(vid_buf, 206, YRES+MENUSIZE-64, "\xAA", 255, 255, 255, bc); + //Open in browser button + bc = 255; + drawrect(vid_buf, 250, YRES+MENUSIZE-68, 107, 18, 255, 255, 255, bc); + drawtext(vid_buf, 273, YRES+MENUSIZE-63, "Open in Browser", 255, 255, 255, bc); + drawtext(vid_buf, 258, YRES+MENUSIZE-64, "\x81", 255, 255, 255, bc); + + //Open Button + if(sdl_key==SDLK_RETURN && openable) { + queue_open = 1; + } + if(mx > 50 && mx < 50+50 && my > YRES+MENUSIZE-68 && my < YRES+MENUSIZE-50 && openable) { + fillrect(vid_buf, 50, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, 40); + if(b && !bq) { + //Button Clicked + queue_open = 1; + } + } + //Fav Button + if(mx > 100 && mx < 100+50 && my > YRES+MENUSIZE-68 && my < YRES+MENUSIZE-50 && svf_login) { + fillrect(vid_buf, 100, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, 40); + if(b && !bq) { + //Button Clicked + fillrect(vid_buf, -1, -1, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 192); + info_box(vid_buf, "Adding to favourites..."); + execute_fav(vid_buf, save_id); + } + } + //Report Button + if(mx > 150 && mx < 150+50 && my > YRES+MENUSIZE-68 && my < YRES+MENUSIZE-50 && svf_login && info_ready) { + fillrect(vid_buf, 150, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, 40); + if(b && !bq) { + //Button Clicked + if(confirm_ui(vid_buf, "Are you sure?", "Are you sure you wish to report this save?", "Report")){ + fillrect(vid_buf, -1, -1, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 192); + info_box(vid_buf, "Reporting..."); + if(execute_report(vid_buf, save_id)){ + info_ui(vid_buf, "Success", "This save has been reported"); + retval = 0; + break; + } + } + } + } + //Delete Button + if(mx > 200 && mx < 200+50 && my > YRES+MENUSIZE-68 && my < YRES+MENUSIZE-50 && (authoritah || myown)) { + fillrect(vid_buf, 200, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, 40); + if(b && !bq) { + //Button Clicked + if(myown || !info->publish){ + if(confirm_ui(vid_buf, "Are you sure you wish to delete this?", "You will not be able recover it.", "Delete")){ + fillrect(vid_buf, -1, -1, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 192); + info_box(vid_buf, "Deleting..."); + if(execute_delete(vid_buf, save_id)){ + retval = 0; + break; + } + } + } else { + if(confirm_ui(vid_buf, "Are you sure?", "This save will be removed from the search index.", "Remove")){ + fillrect(vid_buf, -1, -1, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 192); + info_box(vid_buf, "Removing..."); + if(execute_delete(vid_buf, save_id)){ + retval = 0; + break; + } + } + } + } + } + //Open in browser button + if(mx > 250 && mx < 250+107 && my > YRES+MENUSIZE-68 && my < YRES+MENUSIZE-50) { + fillrect(vid_buf, 250, YRES+MENUSIZE-68, 107, 18, 255, 255, 255, 40); + if(b && !bq) { + //Button Clicked + //TODO: Open link + o_uri = malloc(7+strlen(SERVER)+41+strlen(save_id)*3); + strcpy(o_uri, "http://" SERVER "/Browse/View.html?ID="); + strcaturl(o_uri, save_id); + open_link(o_uri); + free(o_uri); + } + } + //Submit Button + if(mx > XRES+BARSIZE-100 && mx < XRES+BARSIZE-100+50 && my > YRES+MENUSIZE-68 && my < YRES+MENUSIZE-50 && svf_login && info_ready) { + fillrect(vid_buf, XRES+BARSIZE-100, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, 40); + if(b && !bq) { + //Button Clicked + fillrect(vid_buf, -1, -1, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 192); + info_box(vid_buf, "Submitting Comment..."); + execute_submit(vid_buf, save_id, ed.str); + } + } + + sdl_blit(0, 0, (XRES+BARSIZE), YRES+MENUSIZE, vid_buf, (XRES+BARSIZE)); + memcpy(vid_buf, old_vid, ((XRES+BARSIZE)*(YRES+MENUSIZE))*PIXELSIZE); + if(info_ready && svf_login){ + ui_edit_process(mx, my, b, &ed); + } + + if(sdl_key==SDLK_ESCAPE) + break; + + if(lasttime<TIMEOUT) + lasttime++; + } + return retval; +} + +int info_parse(char *info_data, save_info *info) +{ + int i,j; + char *p,*q,*r,*s,*vu,*vd,*pu,*sd; + + memset(info, 0, sizeof(save_info)); + + if(!info_data || !*info_data) + return 0; + + i = 0; + j = 0; + s = NULL; + do_open = 0; + while(1) + { + if(!*info_data) + break; + p = strchr(info_data, '\n'); + if(!p) + p = info_data + strlen(info_data); + else + *(p++) = 0; + + if(!strncmp(info_data, "TITLE ", 6)) + { + info->title = mystrdup(info_data+6); + j++; + } + else if(!strncmp(info_data, "NAME ", 5)) + { + info->name = mystrdup(info_data+5); + j++; + } + else if(!strncmp(info_data, "AUTHOR ", 7)) + { + info->author = mystrdup(info_data+7); + j++; + } + else if(!strncmp(info_data, "DATE ", 5)) + { + info->date = mystrdup(info_data+5); + j++; + } + else if(!strncmp(info_data, "DESCRIPTION ", 12)) + { + info->description = mystrdup(info_data+12); + j++; + } + else if(!strncmp(info_data, "VOTEUP ", 7)) + { + info->voteup = atoi(info_data+7); + j++; + } + else if(!strncmp(info_data, "VOTEDOWN ", 9)) + { + info->votedown = atoi(info_data+9); + j++; + } + else if(!strncmp(info_data, "VOTE ", 5)) + { + info->vote = atoi(info_data+5); + j++; + } + else if(!strncmp(info_data, "MYVOTE ", 7)) + { + info->myvote = atoi(info_data+7); + j++; + } + else if(!strncmp(info_data, "MYFAV ", 6)) + { + info->myfav = atoi(info_data+6); + j++; + } + else if(!strncmp(info_data, "PUBLISH ", 8)) + { + info->publish = atoi(info_data+8); + j++; + } + else if(!strncmp(info_data, "TAGS ", 5)) + { + info->tags = mystrdup(info_data+5); + j++; + } + else if(!strncmp(info_data, "COMMENT ", 8)) + { + if(info->comment_count>=6) { + info_data = p; + continue; + } else { + q = strchr(info_data+8, ' '); + *(q++) = 0; + info->commentauthors[info->comment_count] = mystrdup(info_data+8); + info->comments[info->comment_count] = mystrdup(q); + info->comment_count++; + } + j++; + } + info_data = p; + } + if(j>=8) { + return 1; + } else { + return -1; + } +} + int search_results(char *str, int votes) { int i,j; @@ -2890,7 +3386,7 @@ void execute_save(pixel *vid_buf) free(result); } -void execute_delete(pixel *vid_buf, char *id) +int execute_delete(pixel *vid_buf, char *id) { int status; char *result; @@ -2911,6 +3407,111 @@ void execute_delete(pixel *vid_buf, char *id) error_ui(vid_buf, status, http_ret_text(status)); if(result) free(result); + return 0; + } + if(result && strncmp(result, "OK", 2)) + { + error_ui(vid_buf, 0, result); + free(result); + return 0; + } + + if(result) + free(result); + return 1; +} + +void execute_submit(pixel *vid_buf, char *id, char *message) +{ + int status; + char *result; + + char *names[] = {"ID", "Message", NULL}; + char *parts[2]; + + parts[0] = id; + parts[1] = message; + + result = http_multipart_post( + "http://" SERVER "/Comment.api", + names, parts, NULL, + svf_user, svf_pass, + &status, NULL); + + if(status!=200) + { + error_ui(vid_buf, status, http_ret_text(status)); + if(result) + free(result); + return; + } + if(result && strncmp(result, "OK", 2)) + { + error_ui(vid_buf, 0, result); + free(result); + return; + } + + if(result) + free(result); +} + +int execute_report(pixel *vid_buf, char *id) +{ + int status; + char *result; + + char *names[] = {"ID", NULL}; + char *parts[1]; + + parts[0] = id; + + result = http_multipart_post( + "http://" SERVER "/Report.api", + names, parts, NULL, + svf_user, svf_pass, + &status, NULL); + + if(status!=200) + { + error_ui(vid_buf, status, http_ret_text(status)); + if(result) + free(result); + return 0; + } + if(result && strncmp(result, "OK", 2)) + { + error_ui(vid_buf, 0, result); + free(result); + return 0; + } + + if(result) + free(result); + return 1; +} + +void execute_fav(pixel *vid_buf, char *id) +{ + int status; + char *result; + + char *names[] = {"ID", NULL}; + char *parts[1]; + + parts[0] = id; + + result = http_multipart_post( + "http://" SERVER "/Favourite.api", + names, parts, NULL, + svf_user, svf_pass, + &status, NULL); + + if(status!=200) + { + error_ui(vid_buf, status, http_ret_text(status)); + if(result) + free(result); return; } if(result && strncmp(result, "OK", 2)) @@ -2959,3 +3560,16 @@ int execute_vote(pixel *vid_buf, char *id, char *action) free(result); return 1; } +void open_link(char *uri){ +#ifdef WIN32 + ShellExecute(0, "OPEN", uri, NULL, NULL, 0) +#elif MACOSX + //LSOpenCFURLRef(CFURLCreateWithString(NULL, CFStringCreateWithCString(NULL, uri, 0) ,NULL), NULL); //TODO: Get this crap working +#elif LIN32 + execvp("xdg-open", uri); +#elif LIN64 + execvp("xdg-open", uri); +#else + printf("Cannot open browser\n"); +#endif +} diff --git a/src/main.c b/src/main.c index d88b972..5ef9ce3 100755..100644 --- a/src/main.c +++ b/src/main.c @@ -270,8 +270,11 @@ void *build_save(int *size, int x0, int y0, int w, int h) { x = (int)(parts[i].x+0.5f); y = (int)(parts[i].y+0.5f); - if(x>=x0 && x<x0+w && y>=y0 && y<y0+h) - m[(x-x0)+(y-y0)*w] = i+1; + if(x>=x0 && x<x0+w && y>=y0 && y<y0+h) { + if(!m[(x-x0)+(y-y0)*w] || + parts[m[(x-x0)+(y-y0)*w]-1].type == PT_PHOT) + m[(x-x0)+(y-y0)*w] = i+1; + } } for(j=0; j<w*h; j++) { @@ -319,7 +322,7 @@ void *build_save(int *size, int x0, int y0, int w, int h) for(j=0; j<w*h; j++) { i = m[j]; - if(i && (parts[i-1].type==PT_CLNE || parts[i-1].type==PT_SPRK || parts[i-1].type==PT_LAVA)) + if(i && (parts[i-1].type==PT_CLNE || parts[i-1].type==PT_PCLN || parts[i-1].type==PT_SPRK || parts[i-1].type==PT_LAVA)) d[p++] = parts[i-1].ctype; } @@ -504,14 +507,18 @@ int parse_save(void *save, int size, int replace, int x0, int y0) if(p >= size) goto corrupt; j=d[p++]; - if(j >= PT_NUM) - goto corrupt; + if(j >= PT_NUM) { + //TODO: Possibly some server side translation + j = PT_DUST;//goto corrupt; + } if(j)// && !(isplayer == 1 && j==PT_STKM)) { if(pmap[y][x]) { k = pmap[y][x]>>8; parts[k].type = j; + if(j == PT_PHOT) + parts[k].ctype = 0x3fffffff; parts[k].x = (float)x; parts[k].y = (float)y; m[(x-x0)+(y-y0)*w] = k+1; @@ -519,6 +526,8 @@ int parse_save(void *save, int size, int replace, int x0, int y0) else if(i < nf) { parts[fp[i]].type = j; + if(j == PT_PHOT) + parts[fp[i]].ctype = 0x3fffffff; parts[fp[i]].x = (float)x; parts[fp[i]].y = (float)y; m[(x-x0)+(y-y0)*w] = fp[i]+1; @@ -629,7 +638,7 @@ int parse_save(void *save, int size, int replace, int x0, int y0) { i = m[j]; ty = d[pty+j]; - if(i && (ty==PT_CLNE || (ty==PT_SPRK && ver>=21) || (ty==PT_LAVA && ver>=34))) + if(i && (ty==PT_CLNE || (ty==PT_PCLN && ver>=43) || (ty==PT_SPRK && ver>=21) || (ty==PT_LAVA && ver>=34))) { if(p >= size) goto corrupt; diff --git a/src/powder.c b/src/powder.c index f578e28..fc645a5 100644 --- a/src/powder.c +++ b/src/powder.c @@ -26,10 +26,10 @@ static int pn_junction_sprk(int x, int y, int pt) { unsigned r = pmap[y][x]; if((r & 0xFF) != pt) - return 0; + return 0; r >>= 8; if(parts[r].type != pt) - return 0; + return 0; parts[r].ctype = pt; parts[r].type = PT_SPRK; @@ -42,14 +42,19 @@ static void photoelectric_effect(int nx, int ny) unsigned r = pmap[ny][nx]; if((r&0xFF) == PT_PSCN) { - if((pmap[ny][nx-1] & 0xFF) == PT_NSCN || - (pmap[ny][nx+1] & 0xFF) == PT_NSCN || - (pmap[ny-1][nx] & 0xFF) == PT_NSCN || - (pmap[ny+1][nx] & 0xFF) == PT_NSCN) - pn_junction_sprk(nx, ny, PT_PSCN); + if((pmap[ny][nx-1] & 0xFF) == PT_NSCN || + (pmap[ny][nx+1] & 0xFF) == PT_NSCN || + (pmap[ny-1][nx] & 0xFF) == PT_NSCN || + (pmap[ny+1][nx] & 0xFF) == PT_NSCN) + pn_junction_sprk(nx, ny, PT_PSCN); } } - +/* + RETURN-value explenation +1 = Swap +0 = No move/Bounce +2 = Both particles occupy the same space. + */ static int eval_move(int pt, int nx, int ny, unsigned *rr) { unsigned r; @@ -64,15 +69,13 @@ static int eval_move(int pt, int nx, int ny, unsigned *rr) *rr = r; if((r&0xFF)==PT_VOID || (r&0xFF)==PT_BHOL) - return 1; - - if(pt==PT_NEUT && (r&0xFF)==PT_GLAS) - return 2; + return 1; if(pt==PT_PHOT&&( (r&0xFF)==PT_GLAS || (r&0xFF)==PT_PHOT || (r&0xFF)==PT_CLNE || (r&0xFF)==PT_PCLN || - (r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW || (r&0xFF)==PT_SLTW || + (r&0xFF)==PT_GLOW || (r&0xFF)==PT_WATR || + (r&0xFF)==PT_DSTW || (r&0xFF)==PT_SLTW || ((r&0xFF)==PT_LCRY&&parts[r>>8].life > 5))) return 2; @@ -92,15 +95,25 @@ static int eval_move(int pt, int nx, int ny, unsigned *rr) if(ptypes[pt].falldown!=1 && bmap[ny/CELL][nx/CELL]==10) return 0; - if (r && ((r&0xFF) >= PT_NUM || !can_move[pt][(r&0xFF)])) + if(ptypes[pt].properties&TYPE_ENERGY && (r && ((r&0xFF) >= PT_NUM || (ptypes[(r&0xFF)].properties&TYPE_ENERGY)))) + return 2; + + if(pt==PT_NEUT && (r && ((r&0xFF) >= PT_NUM || (ptypes[(r&0xFF)].properties&PROP_NEUTPENETRATE)))) + return 1; + if((r&0xFF)==PT_NEUT && ptypes[pt].properties&PROP_NEUTPENETRATE) + return 0; + + if (r && ((r&0xFF) >= PT_NUM || (ptypes[pt].weight <= ptypes[(r&0xFF)].weight))) return 0; - if(pt == PT_PHOT) + if(pt == PT_PHOT) return 2; + return 1; } static void create_cherenkov_photon(int pp); +static void create_gain_photon(int pp); int try_move(int i, int x, int y, int nx, int ny) { @@ -110,21 +123,39 @@ int try_move(int i, int x, int y, int nx, int ny) return 1; e = eval_move(parts[i].type, nx, ny, &r); - if(!e) { - if(!legacy_enable && parts[i].type==PT_PHOT) { + + /* half-silvered mirror */ + if(!e && parts[i].type==PT_PHOT && + (((r&0xFF)==PT_BMTL && rand()<RAND_MAX/2) || + (pmap[y][x]&0xFF)==PT_BMTL)) + e = 2; + + if(!e) + { + if(!legacy_enable && parts[i].type==PT_PHOT) + { if((r & 0xFF) == PT_COAL || (r & 0xFF) == PT_BCOL) parts[r>>8].temp = parts[i].temp; + if((r & 0xFF) < PT_NUM) - parts[i].temp = parts[r>>8].temp = - restrict_flt((parts[r>>8].temp+parts[i].temp)/2, MIN_TEMP, MAX_TEMP); + parts[i].temp = parts[r>>8].temp = restrict_flt((parts[r>>8].temp+parts[i].temp)/2, MIN_TEMP, MAX_TEMP); } return 0; } - if(e == 2) { - if(parts[i].type == PT_NEUT && (r&0xFF)==PT_GLAS) { - if(rand() < RAND_MAX/10) - create_cherenkov_photon(i); - } + + if(e == 2) + { + if(parts[i].type == PT_PHOT && (r&0xFF)==PT_GLOW && !parts[r>>8].life) + if(rand() < RAND_MAX/30) + { + parts[r>>8].life = 120; + create_gain_photon(i); + } + + if(parts[i].type == PT_NEUT && (r&0xFF)==PT_GLAS) { + if(rand() < RAND_MAX/10) + create_cherenkov_photon(i); + } return 1; } @@ -154,29 +185,24 @@ int try_move(int i, int x, int y, int nx, int ny) if(r && (r>>8)<NPART && ptypes[r&0xFF].falldown!=2 && bmap[y/CELL][x/CELL]==3) return 0; - pmap[ny][nx] = (i<<8)|parts[i].type; - pmap[y][x] = r; + if(parts[i].type == PT_PHOT) + return 1; - if(r && (r>>8)<NPART) + e = r >> 8; + if(r && e<NPART) { - r >>= 8; - parts[r].x += x-nx; - parts[r].y += y-ny; + if(parts[e].type == PT_PHOT) + return 1; + + parts[e].x += x-nx; + parts[e].y += y-ny; } + pmap[ny][nx] = (i<<8)|parts[i].type; + pmap[y][x] = r; + return 1; } -#define SURF_RANGE 10 -#define NORMAL_MIN_EST 3 -#define NORMAL_INTERP 20 -#define NORMAL_FRAC 16 - -#define REFRACT 0x80000000 - -/* heavy flint glass, for awesome refraction/dispersion - this way you can make roof prisms easily */ -#define GLASS_IOR 1.9 -#define GLASS_DISP 0.07 static unsigned direction_to_map(float dx, float dy) { @@ -306,7 +332,7 @@ int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, return 0; if(pt == PT_PHOT) - photoelectric_effect(x, y); + photoelectric_effect(x, y); return get_normal(pt, x, y, dx, dy, nx, ny); } @@ -314,19 +340,21 @@ int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, void kill_part(int i) { int x, y; - parts[i].type = PT_NONE; - x = (int)(parts[i].x+0.5f); - y = (int)(parts[i].y+0.5f); + if(parts[i].type != PT_PHOT) { + x = (int)(parts[i].x+0.5f); + y = (int)(parts[i].y+0.5f); - if(x>=0 && y>=0 && x<XRES && y<YRES) - pmap[y][x] = 0; + if(x>=0 && y>=0 && x<XRES && y<YRES) + pmap[y][x] = 0; + } + parts[i].type = PT_NONE; parts[i].life = pfree; pfree = i; } -#if defined(WIN32) && !defined(__MINGW32__) +#ifdef WIN32 _inline int create_part(int p, int x, int y, int t) #else inline int create_part(int p, int x, int y, int t) @@ -398,6 +426,7 @@ inline int create_part(int p, int x, int y, int t) (pmap[y][x]&0xFF)!=PT_ETRD && (pmap[y][x]&0xFF)!=PT_BRMT && (pmap[y][x]&0xFF)!=PT_NBLE && + (pmap[y][x]&0xFF)!=PT_IRON && (pmap[y][x]&0xFF)!=PT_INWR) return -1; parts[pmap[y][x]>>8].type = PT_SPRK; @@ -476,11 +505,15 @@ inline int create_part(int p, int x, int y, int t) parts[i].vx = r*cosf(a); parts[i].vy = r*sinf(a); } + if(t==PT_MORT) + { + parts[i].vx = 2; + } if(t==PT_PHOT) { - float a = (rand()%8) * 0.78540f; + float a = (rand()%8) * 0.78540f; parts[i].life = 680; - parts[i].ctype = 0x3FFFFFFF; + parts[i].ctype = 0x3FFFFFFF; parts[i].vx = 3.0f*cosf(a); parts[i].vy = 3.0f*sinf(a); } @@ -529,6 +562,51 @@ inline int create_part(int p, int x, int y, int t) return i; } +static void create_gain_photon(int pp) +{ + float xx, yy; + int i, lr, temp_bin, nx, ny; + + if(pfree == -1) + return; + i = pfree; + + lr = rand() % 2; + + if(lr) { + xx = parts[pp].x - 0.3*parts[pp].vy; + yy = parts[pp].y + 0.3*parts[pp].vx; + } else { + xx = parts[pp].x + 0.3*parts[pp].vy; + yy = parts[pp].y - 0.3*parts[pp].vx; + } + + nx = (int)(xx + 0.5f); + ny = (int)(yy + 0.5f); + + if(nx<0 || ny<0 || nx>=XRES || ny>=YRES) + return; + + if((pmap[ny][nx] & 0xFF) != PT_GLOW) + return; + + pfree = parts[i].life; + + parts[i].type = PT_PHOT; + parts[i].life = 680; + parts[i].x = xx; + parts[i].y = yy; + parts[i].vx = parts[pp].vx; + parts[i].vy = parts[pp].vy; + parts[i].temp = parts[pmap[ny][nx] >> 8].temp; + parts[i].tmp = 0; + + temp_bin = (int)((parts[i].temp-273.0f)*0.25f); + if(temp_bin < 0) temp_bin = 0; + if(temp_bin > 25) temp_bin = 25; + parts[i].ctype = 0x1F << temp_bin; +} + static void create_cherenkov_photon(int pp) { int i, lr, nx, ny; @@ -541,10 +619,10 @@ static void create_cherenkov_photon(int pp) nx = (int)(parts[pp].x + 0.5f); ny = (int)(parts[pp].y + 0.5f); if((pmap[ny][nx] & 0xFF) != PT_GLAS) - return; + return; if(hypotf(parts[pp].vx, parts[pp].vy) < 1.44f) - return; + return; pfree = parts[i].life; @@ -559,11 +637,11 @@ static void create_cherenkov_photon(int pp) parts[i].tmp = 0; if(lr) { - parts[i].vx = parts[pp].vx - 2.5f*parts[pp].vy; - parts[i].vy = parts[pp].vy + 2.5f*parts[pp].vx; + parts[i].vx = parts[pp].vx - 2.5f*parts[pp].vy; + parts[i].vy = parts[pp].vy + 2.5f*parts[pp].vx; } else { - parts[i].vx = parts[pp].vx + 2.5f*parts[pp].vy; - parts[i].vy = parts[pp].vy - 2.5f*parts[pp].vx; + parts[i].vx = parts[pp].vx + 2.5f*parts[pp].vy; + parts[i].vy = parts[pp].vy - 2.5f*parts[pp].vx; } /* photons have speed of light. no discussion. */ @@ -572,7 +650,7 @@ static void create_cherenkov_photon(int pp) parts[i].vy *= r; } -#if defined(WIN32) && !defined(__MINGW32__) +#ifdef WIN32 _inline void delete_part(int x, int y) #else inline void delete_part(int x, int y) @@ -590,7 +668,7 @@ inline void delete_part(int x, int y) pmap[y][x] = 0; // just in case } -#if defined(WIN32) && !defined(__MINGW32__) +#ifdef WIN32 _inline int is_wire(int x, int y) #else inline int is_wire(int x, int y) @@ -599,7 +677,7 @@ inline int is_wire(int x, int y) return bmap[y][x]==6 || bmap[y][x]==7 || bmap[y][x]==3 || bmap[y][x]==8 || bmap[y][x]==11 || bmap[y][x]==12; } -#if defined(WIN32) && !defined(__MINGW32__) +#ifdef WIN32 _inline int is_wire_off(int x, int y) #else inline int is_wire_off(int x, int y) @@ -613,18 +691,18 @@ int get_wavelength_bin(int *wm) int i, w0=30, wM=0; if(!*wm) - return -1; + return -1; for(i=0; i<30; i++) - if(*wm & (1<<i)) { - if(i < w0) - w0 = i; - if(i > wM) - wM = i; - } + if(*wm & (1<<i)) { + if(i < w0) + w0 = i; + if(i > wM) + wM = i; + } if(wM-w0 < 5) - return (wM+w0)/2; + return (wM+w0)/2; i = rand() % (wM-w0-3); i += w0; @@ -690,7 +768,7 @@ void set_emap(int x, int y) } } -#if defined(WIN32) && !defined(__MINGW32__) +#ifdef WIN32 _inline int parts_avg(int ci, int ni) #else inline int parts_avg(int ci, int ni) @@ -734,9 +812,6 @@ int nearest_part(int ci, int t) void update_particles_i(pixel *vid, int start, int inc) { int i, j, x, y, t, nx, ny, r, a, s, lt, rt, fe, nt, lpv, nearp, pavg; - uint16_t tempu1, tempu2; - int16_t temps1, temps2; - float tempf1, tempf2; float mv, dx, dy, ix, iy, lx, ly, d, pp, nrx, nry, dp; float nn, ct1, ct2; float pt = R_TEMP; @@ -759,7 +834,7 @@ void update_particles_i(pixel *vid, int start, int inc) { if(!(parts[i].life==10&&(parts[i].type==PT_LCRY||parts[i].type==PT_PCLN||parts[i].type==PT_HSWC))) parts[i].life--; - if(parts[i].life<=0 && t!=PT_METL && t!=PT_FIRW && t!=PT_PCLN && t!=PT_HSWC && t!=PT_WATR && t!=PT_RBDM && t!=PT_LRBD && t!=PT_SLTW && t!=PT_BRMT && t!=PT_PSCN && t!=PT_NSCN && t!=PT_NTCT && t!=PT_PTCT && t!=PT_BMTL && t!=PT_SPRK && t!=PT_LAVA && t!=PT_ETRD&&t!=PT_LCRY && t!=PT_INWR) + if(parts[i].life<=0 && t!=PT_METL && t!=PT_IRON && t!=PT_FIRW && t!=PT_PCLN && t!=PT_HSWC && t!=PT_WATR && t!=PT_RBDM && t!=PT_LRBD && t!=PT_SLTW && t!=PT_BRMT && t!=PT_PSCN && t!=PT_NSCN && t!=PT_NTCT && t!=PT_PTCT && t!=PT_BMTL && t!=PT_SPRK && t!=PT_LAVA && t!=PT_ETRD&&t!=PT_LCRY && t!=PT_INWR && t!=PT_GLOW) { kill_part(i); continue; @@ -767,7 +842,7 @@ void update_particles_i(pixel *vid, int start, int inc) if(parts[i].life<=0 && t==PT_SPRK) { t = parts[i].ctype; - if(t!=PT_METL&&t!=PT_BMTL&&t!=PT_BRMT&&t!=PT_LRBD&&t!=PT_RBDM&&t!=PT_BTRY&&t!=PT_NBLE) + if(t!=PT_METL&&t!=PT_IRON&&t!=PT_BMTL&&t!=PT_BRMT&&t!=PT_LRBD&&t!=PT_RBDM&&t!=PT_BTRY&&t!=PT_NBLE) parts[i].temp = R_TEMP + 273.15f; if(!t) t = PT_METL; @@ -869,7 +944,7 @@ void update_particles_i(pixel *vid, int start, int inc) } // interpolator -#if defined(WIN32) && !defined(__MINGW32__) +#ifdef WIN32 mv = max(fabsf(parts[i].vx), fabsf(parts[i].vy)); #else mv = fmaxf(fabsf(parts[i].vx), fabsf(parts[i].vy)); @@ -943,6 +1018,8 @@ void update_particles_i(pixel *vid, int start, int inc) t = parts[i].type = PT_OIL; if(t==PT_BMTL && pv[y/CELL][x/CELL]>2.5f) t = parts[i].type = PT_BRMT; + if(t==PT_BMTL && pv[y/CELL][x/CELL]>1.0f && parts[i].tmp==1) + t = parts[i].type = PT_BRMT; if(t==PT_BRCK && pv[y/CELL][x/CELL]>2.8f) t = parts[i].type = PT_STNE; //if(t==PT_GLAS && pv[y/CELL][x/CELL]>4.0f) @@ -1118,7 +1195,7 @@ void update_particles_i(pixel *vid, int start, int inc) pt = parts[i].temp -= 2.5f; } - if(t==PT_WATR || t==PT_ETRD || t==PT_SLTW || t==PT_METL || t==PT_RBDM || t==PT_LRBD || t==PT_BRMT || t==PT_PSCN || t==PT_NSCN || t==PT_NTCT || t==PT_PTCT || t==PT_BMTL || t==PT_SPRK|| t == PT_NBLE || t==PT_INWR) + if(t==PT_WATR || t==PT_ETRD || t==PT_SLTW || t==PT_METL || t==PT_IRON || t==PT_RBDM || t==PT_LRBD || t==PT_BRMT || t==PT_PSCN || t==PT_NSCN || t==PT_NTCT || t==PT_PTCT || t==PT_BMTL || t==PT_SPRK|| t == PT_NBLE || t==PT_INWR) { nx = x % CELL; if(nx == 0) @@ -1136,7 +1213,7 @@ void update_particles_i(pixel *vid, int start, int inc) ny = y/CELL; if(nx>=0 && ny>=0 && nx<XRES/CELL && ny<YRES/CELL) { - if(t==PT_WATR || t==PT_ETRD || t==PT_SLTW || t==PT_METL || t==PT_RBDM || t==PT_LRBD || t==PT_NSCN || t==PT_NTCT || t==PT_PTCT || t==PT_PSCN || t==PT_BRMT || t==PT_BMTL||t==PT_NBLE || t==PT_INWR) + if(t==PT_WATR || t==PT_ETRD || t==PT_SLTW || t==PT_METL || t==PT_IRON || t==PT_RBDM || t==PT_LRBD || t==PT_NSCN || t==PT_NTCT || t==PT_PTCT || t==PT_PSCN || t==PT_BRMT || t==PT_BMTL||t==PT_NBLE || t==PT_INWR) { if(emap[ny][nx]==12 && !parts[i].life) { @@ -1167,8 +1244,7 @@ void update_particles_i(pixel *vid, int start, int inc) r = pmap[y+ny][x+nx]; if((r>>8)>=NPART || !r) continue; - if(((r&0xFF)==PT_METL || (r&0xFF)==PT_ETRD || (r&0xFF)==PT_PSCN || (r&0xFF)==PT_NSCN || (r&0xFF)==PT_NTCT || (r&0xFF)==PT_PTCT || (r&0xFF)==PT_BMTL || (r&0xFF)==PT_RBDM || (r&0xFF)==PT_LRBD || (r&0xFF)==PT_BRMT||(r&0xFF)==PT_NBLE) || (r&0xFF)==PT_INWR && parts[r>>8].ctype!=PT_SPRK) - + if(((r&0xFF)==PT_METL || (r&0xFF)==PT_IRON || (r&0xFF)==PT_ETRD || (r&0xFF)==PT_PSCN || (r&0xFF)==PT_NSCN || (r&0xFF)==PT_NTCT || (r&0xFF)==PT_PTCT || (r&0xFF)==PT_BMTL || (r&0xFF)==PT_RBDM || (r&0xFF)==PT_LRBD || (r&0xFF)==PT_BRMT || (r&0xFF)==PT_NBLE || (r&0xFF)==PT_INWR) && parts[r>>8].ctype!=PT_SPRK) { t = parts[i].type = PT_NONE; parts[r>>8].ctype = parts[r>>8].type; @@ -1217,6 +1293,67 @@ void update_particles_i(pixel *vid, int start, int inc) } } } + else if(t==PT_BMTL) { + if(parts[i].tmp>1) { + parts[i].tmp--; + for(nx=-1; nx<2; nx++) + for(ny=-1; ny<2; ny++) + if(x+nx>=0 && y+ny>0 && x+nx<XRES && y+ny<YRES && (nx || ny)) + { + r = pmap[y+ny][x+nx]; + if((r>>8)>=NPART || !r) + continue; + rt =parts[r>>8].type; + if((rt==PT_METL || rt==PT_IRON) && 1>(rand()/(RAND_MAX/100))) + { + parts[r>>8].type=PT_BMTL; + parts[r>>8].tmp=(parts[i].tmp<=7)?parts[i].tmp=1:parts[i].tmp-(rand()%5);//rand()/(RAND_MAX/300)+100; + } + } + } else if(parts[i].tmp==1 && 1>rand()%1000) { + parts[i].tmp = 0; + t = parts[i].type = PT_BRMT; + } + } + + else if(t==PT_IRON) { + for(nx=-1; nx<2; nx++) + for(ny=-1; ny<2; ny++) + if(x+nx>=0 && y+ny>0 && x+nx<XRES && y+ny<YRES && (nx || ny)) + { + r = pmap[y+ny][x+nx]; + if((r>>8)>=NPART || !r) + continue; + if((((r&0xFF) == PT_SALT && 15>(rand()/(RAND_MAX/700))) || + ((r&0xFF) == PT_SLTW && 30>(rand()/(RAND_MAX/2000))) || + ((r&0xFF) == PT_WATR && 5 >(rand()/(RAND_MAX/6000))) || + ((r&0xFF) == PT_O2 && 2 >(rand()/(RAND_MAX/500))) || + ((r&0xFF) == PT_LO2))&& + (!(parts[i].life)) + ) + { + parts[i].type=PT_BMTL; + parts[i].tmp=(rand()/(RAND_MAX/10))+20; + } + } + } + else if((t==PT_SPRK||parts[i].type==PT_SPRK) && parts[i].ctype==PT_IRON) { + for(nx=-1; nx<2; nx++) + for(ny=-1; ny<2; ny++) + if(x+nx>=0 && y+ny>0 && x+nx<XRES && y+ny<YRES && (nx || ny)) + { + r = pmap[y+ny][x+nx]; + if((r>>8)>=NPART || !r) + continue; + if(((r&0xFF) == PT_DSTW && 30>(rand()/(RAND_MAX/1000))) || + ((r&0xFF) == PT_SLTW && 30>(rand()/(RAND_MAX/1000))) || + ((r&0xFF) == PT_WATR && 30>(rand()/(RAND_MAX/1000)))) + { + parts[r>>8].type=PT_O2; + //parts[r>>8].tmp=(rand()/(RAND_MAX/10))+20; + } + } + } else if(t==PT_COAL) { if(parts[i].life<=0) { @@ -1285,16 +1422,18 @@ void update_particles_i(pixel *vid, int start, int inc) else if(t==PT_FUSE) { if(parts[i].life<=0) { - t = PT_NONE; + //t = parts[i].life = PT_NONE; kill_part(i); r = create_part(-1, x, y, PT_PLSM); - parts[r].life = 50; - goto killed; + if(r!=-1) + parts[r].life = 50; + //goto killed; } else if (parts[i].life < 40) { parts[i].life--; if((rand()%100)==0) { r = create_part(-1, (nx=x+rand()%3-1), (ny=y+rand()%3-1), PT_PLSM); - parts[r].life = 50; + if(r!=-1) + parts[r].life = 50; } } if((pv[y/CELL][x/CELL] > 2.7f)&&parts[i].tmp>40) @@ -1302,10 +1441,10 @@ void update_particles_i(pixel *vid, int start, int inc) else if(parts[i].tmp<40&&parts[i].tmp>0) parts[i].tmp--; else if(parts[i].tmp<=0) { - t = PT_NONE; + //t = PT_NONE; kill_part(i); r = create_part(-1, x, y, PT_FSEP); - goto killed; + //goto killed; } for(nx=-2; nx<3; nx++) for(ny=-2; ny<3; ny++) @@ -1326,16 +1465,18 @@ void update_particles_i(pixel *vid, int start, int inc) else if(t==PT_FSEP) { if(parts[i].life<=0) { - t = PT_NONE; + //t = PT_NONE; kill_part(i); r = create_part(-1, x, y, PT_PLSM); - parts[r].life = 50; - goto killed; + if(r!=-1) + parts[r].life = 50; + //goto killed; } else if (parts[i].life < 40) { parts[i].life--; if((rand()%10)==0) { r = create_part(-1, (nx=x+rand()%3-1), (ny=y+rand()%3-1), PT_PLSM); - parts[r].life = 50; + if(r!=-1) + parts[r].life = 50; } } for(nx=-2; nx<3; nx++) @@ -1346,7 +1487,7 @@ void update_particles_i(pixel *vid, int start, int inc) r = pmap[y+ny][x+nx]; if((r>>8)>=NPART || !r) continue; - if((r&0xFF)==PT_SPRK || (parts[i].temp>=(273.15+400.0f)) && 1>(rand()%15)) + if(((r&0xFF)==PT_SPRK || (parts[i].temp>=(273.15+400.0f))) && 1>(rand()%15)) { if(parts[i].life>40) { parts[i].life = 39; @@ -1548,7 +1689,7 @@ void update_particles_i(pixel *vid, int start, int inc) parts[r>>8].type = PT_FIRE; parts[r>>8].life = 4; } - else if(((r&0xFF)!=PT_CLNE && ptypes[parts[r>>8].type].hardness>(rand()%1000))&&parts[i].life>=50) + else if(((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && ptypes[parts[r>>8].type].hardness>(rand()%1000))&&parts[i].life>=50) { parts[i].life--; parts[r>>8].type = PT_NONE; @@ -1641,6 +1782,9 @@ void update_particles_i(pixel *vid, int start, int inc) } } } + else if(t==PT_MORT) { + create_part(-1, x, y-1, PT_SMKE); + } else if(t==PT_LCRY) { for(nx=-1; nx<2; nx++) @@ -1807,7 +1951,7 @@ void update_particles_i(pixel *vid, int start, int inc) } } else if(parts[i].tmp==2) { - int col = rand()%200+4; + int col = rand()%200+4; for(nx=-2; nx<3; nx++) { for(ny=-2; ny<3; ny++) { if(x+nx>=0 && y+ny>0 && x+nx<XRES && y+ny<YRES && (nx || ny)) @@ -1849,7 +1993,7 @@ void update_particles_i(pixel *vid, int start, int inc) rt = parts[r>>8].type; if(parts_avg(i,r>>8) != PT_INSL) { - if((rt==PT_METL||rt==PT_ETRD||rt==PT_BMTL||rt==PT_BRMT||rt==PT_LRBD||rt==PT_RBDM||rt==PT_PSCN||rt==PT_NSCN||rt==PT_NBLE)&&parts[r>>8].life==0 && abs(nx)+abs(ny) < 4) + if((rt==PT_METL||rt==PT_IRON||rt==PT_ETRD||rt==PT_BMTL||rt==PT_BRMT||rt==PT_LRBD||rt==PT_RBDM||rt==PT_PSCN||rt==PT_NSCN||rt==PT_NBLE)&&parts[r>>8].life==0 && abs(nx)+abs(ny) < 4) { parts[r>>8].life = 4; parts[r>>8].ctype = rt; @@ -1901,7 +2045,8 @@ void update_particles_i(pixel *vid, int start, int inc) continue; rt = parts[r>>8].type; if((a || ptypes[rt].explosive) && ((rt!=PT_RBDM && rt!=PT_LRBD && rt!=PT_INSL && rt!=PT_SWCH) || t!=PT_SPRK) && - (t!=PT_LAVA || parts[i].life>0 || (rt!=PT_STNE && rt!=PT_PSCN && rt!=PT_NSCN && rt!=PT_NTCT && rt!=PT_PTCT && rt!=PT_METL && rt!=PT_ETRD && rt!=PT_BMTL && rt!=PT_BRMT && rt!=PT_SWCH && rt!=PT_INWR)) && + !(t==PT_PHOT && rt==PT_INSL) && + (t!=PT_LAVA || parts[i].life>0 || (rt!=PT_STNE && rt!=PT_PSCN && rt!=PT_NSCN && rt!=PT_NTCT && rt!=PT_PTCT && rt!=PT_METL && rt!=PT_IRON && rt!=PT_ETRD && rt!=PT_BMTL && rt!=PT_BRMT && rt!=PT_SWCH && rt!=PT_INWR)) && ptypes[rt].flammable && (ptypes[rt].flammable + (int)(pv[(y+ny)/CELL][(x+nx)/CELL]*10.0f))>(rand()%1000)) { parts[r>>8].type = PT_FIRE; @@ -1915,7 +2060,7 @@ void update_particles_i(pixel *vid, int start, int inc) if(lpv < 1) lpv = 1; if(legacy_enable) { - if(t!=PT_SPRK && ptypes[rt].meltable && ((rt!=PT_RBDM && rt!=PT_LRBD) || t!=PT_SPRK) && ((t!=PT_FIRE&&t!=PT_PLSM) || (rt!=PT_METL && rt!=PT_ETRD && rt!=PT_PSCN && rt!=PT_NSCN && rt!=PT_NTCT && rt!=PT_PTCT && rt!=PT_BMTL && rt!=PT_BRMT && rt!=PT_SALT && rt!=PT_INWR)) && + if(t!=PT_SPRK && ptypes[rt].meltable && ((rt!=PT_RBDM && rt!=PT_LRBD) || t!=PT_SPRK) && ((t!=PT_FIRE&&t!=PT_PLSM) || (rt!=PT_METL && rt!=PT_IRON && rt!=PT_ETRD && rt!=PT_PSCN && rt!=PT_NSCN && rt!=PT_NTCT && rt!=PT_PTCT && rt!=PT_BMTL && rt!=PT_BRMT && rt!=PT_SALT && rt!=PT_INWR)) && ptypes[rt].meltable*lpv>(rand()%1000)) { if(t!=PT_LAVA || parts[i].life>0) @@ -1987,7 +2132,7 @@ void update_particles_i(pixel *vid, int start, int inc) pavg = parts_avg(i, r>>8); if(pavg != PT_INSL) { - if(t==PT_SPRK && (rt==PT_METL||rt==PT_ETRD||rt==PT_BMTL||rt==PT_BRMT||rt==PT_LRBD||rt==PT_RBDM||rt==PT_PSCN||rt==PT_NSCN||rt==PT_NBLE) && parts[r>>8].life==0 && + if(t==PT_SPRK && (rt==PT_METL||rt==PT_IRON||rt==PT_ETRD||rt==PT_BMTL||rt==PT_BRMT||rt==PT_LRBD||rt==PT_RBDM||rt==PT_PSCN||rt==PT_NSCN||rt==PT_NBLE) && parts[r>>8].life==0 && (parts[i].life<3 || ((r>>8)<i && parts[i].life<4)) && abs(nx)+abs(ny)<4) { if(!(rt==PT_PSCN&&parts[i].ctype==PT_NSCN)&&!(rt!=PT_PSCN&&!(rt==PT_NSCN&&parts[i].temp>=373.0f)&&parts[i].ctype==PT_NTCT)&&!(rt!=PT_PSCN&&!(rt==PT_NSCN&&parts[i].temp<=373.0f)&&parts[i].ctype==PT_PTCT)&&!(rt!=PT_PSCN&&!(rt==PT_NSCN)&&parts[i].ctype==PT_INWR) && pavg != PT_INSL &&!(parts[i].ctype==PT_SWCH&&(rt==PT_PSCN||rt==PT_NSCN)) ) @@ -2480,8 +2625,10 @@ killed: (pmap[y+ny][x+nx]&0xFF)!=0xFF) parts[i].ctype = pmap[y+ny][x+nx]&0xFF; } - else + else { create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + } if(parts[i].type==PT_PCLN) { @@ -2499,8 +2646,21 @@ killed: (pmap[y+ny][x+nx]&0xFF)!=PT_STKM && (pmap[y+ny][x+nx]&0xFF)!=0xFF) parts[i].ctype = pmap[y+ny][x+nx]&0xFF; - if(parts[i].ctype && parts[i].life==10) - create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + if(parts[i].ctype && parts[i].life==10) { + if(parts[i].ctype==PT_PHOT) { + for(nx=-1; nx<2; nx++) { + for(ny=-1; ny<2; ny++) { + r = create_part(-1, x+nx, y+ny, parts[i].ctype); + if(r!=-1) { + parts[r].vx = nx*3; + parts[r].vy = ny*3; + } + } + } + } else { + create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + } } if(t==PT_YEST) { @@ -2534,7 +2694,7 @@ killed: if(parts[i].type == PT_PHOT) { rt = pmap[ny][nx] & 0xFF; - if(rt==PT_CLNE) { + if(rt==PT_CLNE || rt==PT_PCLN) { lt = pmap[ny][nx] >> 8; if(!parts[lt].ctype) parts[lt].ctype = PT_PHOT; @@ -2542,7 +2702,7 @@ killed: lt = pmap[y][x] & 0xFF; - r = eval_move(PT_PHOT, nx, ny, NULL); + r = eval_move(PT_PHOT, nx, ny, NULL); if(((rt==PT_GLAS && lt!=PT_GLAS) || (rt!=PT_GLAS && lt==PT_GLAS)) && r) { if(!get_normal_interp(REFRACT|parts[i].type, x, y, parts[i].vx, parts[i].vy, &nrx, &nry)) { @@ -2550,13 +2710,13 @@ killed: continue; } - r = get_wavelength_bin(&parts[i].ctype); - if(r == -1) { - kill_part(i); - continue; - } - nn = GLASS_IOR - GLASS_DISP*(r-15)/15.0f; - nn *= nn; + r = get_wavelength_bin(&parts[i].ctype); + if(r == -1) { + kill_part(i); + continue; + } + nn = GLASS_IOR - GLASS_DISP*(r-15)/15.0f; + nn *= nn; nrx = -nrx; nry = -nry; @@ -2567,10 +2727,10 @@ killed: if(ct2 < 0.0f) { parts[i].vx -= 2.0f*ct1*nrx; parts[i].vy -= 2.0f*ct1*nry; - parts[i].x = lx; - parts[i].y = ly; - nx = (int)(lx + 0.5f); - ny = (int)(ly + 0.5f); + parts[i].x = lx; + parts[i].y = ly; + nx = (int)(lx + 0.5f); + ny = (int)(ly + 0.5f); } else { ct2 = sqrtf(ct2); ct2 = ct2 - nn*ct1; @@ -2700,24 +2860,25 @@ killed: } else if(t==PT_NEUT || t==PT_PHOT) { - r = pmap[ny][nx]; - - /* this should be replaced with a particle type attribute ("photwl" or something) */ - if((r & 0xFF) == PT_PSCN) parts[i].ctype = 0x00000000; - if((r & 0xFF) == PT_NSCN) parts[i].ctype = 0x00000000; - if((r & 0xFF) == PT_COAL) parts[i].ctype = 0x00000000; - if((r & 0xFF) == PT_BCOL) parts[i].ctype = 0x00000000; - if((r & 0xFF) == PT_PLEX) parts[i].ctype &= 0x1F00003E; - if((r & 0xFF) == PT_NITR) parts[i].ctype &= 0x0007C000; - if((r & 0xFF) == PT_NBLE) parts[i].ctype &= 0x3FFF8000; - if((r & 0xFF) == PT_LAVA) parts[i].ctype &= 0x3FF00000; - if((r & 0xFF) == PT_ACID) parts[i].ctype &= 0x1FE001FE; - if((r & 0xFF) == PT_DUST) parts[i].ctype &= 0x3FFFFFC0; - if((r & 0xFF) == PT_SNOW) parts[i].ctype &= 0x03FFFFFF; - if((r & 0xFF) == PT_GOO) parts[i].ctype &= 0x3FFAAA00; - if((r & 0xFF) == PT_PLNT) parts[i].ctype &= 0x0007C000; - if((r & 0xFF) == PT_PLUT) parts[i].ctype &= 0x001FCE00; - if((r & 0xFF) == PT_URAN) parts[i].ctype &= 0x003FC000; + r = pmap[ny][nx]; + + /* this should be replaced with a particle type attribute ("photwl" or something) */ + if((r & 0xFF) == PT_PSCN) parts[i].ctype = 0x00000000; + if((r & 0xFF) == PT_NSCN) parts[i].ctype = 0x00000000; + if((r & 0xFF) == PT_SPRK) parts[i].ctype = 0x00000000; + if((r & 0xFF) == PT_COAL) parts[i].ctype = 0x00000000; + if((r & 0xFF) == PT_BCOL) parts[i].ctype = 0x00000000; + if((r & 0xFF) == PT_PLEX) parts[i].ctype &= 0x1F00003E; + if((r & 0xFF) == PT_NITR) parts[i].ctype &= 0x0007C000; + if((r & 0xFF) == PT_NBLE) parts[i].ctype &= 0x3FFF8000; + if((r & 0xFF) == PT_LAVA) parts[i].ctype &= 0x3FF00000; + if((r & 0xFF) == PT_ACID) parts[i].ctype &= 0x1FE001FE; + if((r & 0xFF) == PT_DUST) parts[i].ctype &= 0x3FFFFFC0; + if((r & 0xFF) == PT_SNOW) parts[i].ctype &= 0x03FFFFFF; + if((r & 0xFF) == PT_GOO) parts[i].ctype &= 0x3FFAAA00; + if((r & 0xFF) == PT_PLNT) parts[i].ctype &= 0x0007C000; + if((r & 0xFF) == PT_PLUT) parts[i].ctype &= 0x001FCE00; + if((r & 0xFF) == PT_URAN) parts[i].ctype &= 0x003FC000; if(get_normal_interp(t, lx, ly, parts[i].vx, parts[i].vy, &nrx, &nry)) { dp = nrx*parts[i].vx + nry*parts[i].vy; @@ -2737,10 +2898,10 @@ killed: continue; } - if(!parts[i].ctype) { - kill_part(i); - continue; - } + if(!parts[i].ctype) { + kill_part(i); + continue; + } } else @@ -2801,10 +2962,10 @@ void update_particles(pixel *vid) t = parts[i].type; x = (int)(parts[i].x+0.5f); y = (int)(parts[i].y+0.5f); - if(x>=0 && y>=0 && x<XRES && y<YRES && parts[i].type!=PT_PHOT) { - if(parts[i].type!=PT_NEUT || (pmap[y][x]&0xFF)!=PT_GLAS) - pmap[y][x] = t|(i<<8); - } + if(x>=0 && y>=0 && x<XRES && y<YRES && t!=PT_PHOT) { + if(t!=PT_NEUT || (pmap[y][x]&0xFF)!=PT_GLAS) + pmap[y][x] = t|(i<<8); + } } else { @@ -3434,7 +3595,6 @@ int create_parts(int x, int y, int r, int c) bmap[j][i] = 5; return 1; } - //LOLOLOLOLLOLOLOLO if(c == 127) { b = 4; |
