diff --git a/Makefile b/Makefile index c02fb2eb5..1e1860a63 100755 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SOURCES := powder.c http.c md5.c update.c +SOURCES := *.c HEADERS := font.h hmap.h http.h md5.h icon.h update.h version.h CFLAGS := -Wall -std=c99 -D_POSIX_C_SOURCE=200112L diff --git a/defines.h b/defines.h index bbce8b243..7a14da2a9 100644 --- a/defines.h +++ b/defines.h @@ -7,10 +7,20 @@ #define PATH_SEP "/" #endif +#define SAVE_VERSION 41 +#define MINOR_VERSION 3 +#define IDENT_VERSION "S" //Change this if you're not Simon! It should be a single letter. + #define SERVER "powdertoy.co.uk" #undef PLOSS +#define THUMB_CACHE_SIZE 256 + +#define IMGCONNS 3 +#define TIMEOUT 100 +#define HTTP_TIMEOUT 10 + #define MENUSIZE 40 #define BARSIZE 14 #define XRES 612 @@ -18,6 +28,7 @@ #define NPART XRES*YRES #define MAXSIGNS 16 +#define TAG_MAX 256 #define ZSIZE_D 16 #define ZFACTOR_D 8 @@ -81,4 +92,13 @@ extern int stamp_count; extern int itc; extern char itc_msg[64]; +extern int do_open; +extern int sys_pause; +extern int legacy_enable; //Used to disable new features such as heat, will be set by commandline or save. +extern int death, framerender; + +extern unsigned char last_major, last_minor, update_flag; + +extern char http_proxy_string[256]; + #endif \ No newline at end of file diff --git a/graphics.c b/graphics.c index 8f5c6aeb6..c058d439d 100644 --- a/graphics.c +++ b/graphics.c @@ -1893,4 +1893,65 @@ pixel *render_packed_rgb(void *image, int width, int height, int cmp_size) free(tmp); return res; } - \ No newline at end of file + +void draw_image(pixel *vid, pixel *img, int x, int y, int w, int h, int a) +{ + int i, j, r, g, b; + for(j=0; j0) + r--; + if(g>0) + g--; + if(b>0) + b--; + dst[i] = PIXRGB(r,g,b); + } +} + +void render_zoom(pixel *img) +{ + int x, y, i, j; + pixel pix; + drawrect(img, zoom_wx-2, zoom_wy-2, ZSIZE*ZFACTOR+2, ZSIZE*ZFACTOR+2, 192, 192, 192, 255); + drawrect(img, zoom_wx-1, zoom_wy-1, ZSIZE*ZFACTOR, ZSIZE*ZFACTOR, 0, 0, 0, 255); + clearrect(img, zoom_wx, zoom_wy, ZSIZE*ZFACTOR, ZSIZE*ZFACTOR); + for(j=0; j #endif -#include "version.h" +#include "defines.h" #include "http.h" #include "md5.h" diff --git a/interface.c b/interface.c index d5d87e548..9a3fe4c45 100644 --- a/interface.c +++ b/interface.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "http.h" #include "md5.h" @@ -32,8 +33,30 @@ char svf_tags[256] = ""; void *svf_last = NULL; int svf_lsize; +char *search_ids[GRID_X*GRID_Y]; +int search_votes[GRID_X*GRID_Y]; +int search_publish[GRID_X*GRID_Y]; +int search_scoredown[GRID_X*GRID_Y]; +int search_scoreup[GRID_X*GRID_Y]; +char *search_names[GRID_X*GRID_Y]; +char *search_owners[GRID_X*GRID_Y]; +void *search_thumbs[GRID_X*GRID_Y]; +int search_thsizes[GRID_X*GRID_Y]; + +int search_own = 0; +int search_date = 0; +int search_page = 0; +char search_expr[256] = ""; + +char *tag_names[TAG_MAX]; +int tag_votes[TAG_MAX]; + int Z_keysym = 'z'; +int zoom_en = 0; +int zoom_x=(XRES-ZSIZE_D)/2, zoom_y=(YRES-ZSIZE_D)/2; +int zoom_wx=0, zoom_wy=0; + void menu_count(void) { int i=0; @@ -1636,4 +1659,772 @@ void set_cmode(int cm) strcpy(itc_msg, "Pressure Display"); else strcpy(itc_msg, "Velocity Display"); +} + +char *download_ui(pixel *vid_buf, char *uri, int *len) +{ + int dstate = 0; + void *http = http_async_req_start(NULL, uri, NULL, 0, 0); + int x0=(XRES-240)/2,y0=(YRES-MENUSIZE)/2; + int done, total, i, ret, zlen, ulen; + char str[16], *tmp, *res; + + while(!http_async_req_status(http)) + { + sdl_poll(); + + http_async_get_length(http, &total, &done); + + clearrect(vid_buf, x0-2, y0-2, 244, 64); + drawrect(vid_buf, x0, y0, 240, 60, 192, 192, 192, 255); + drawtext(vid_buf, x0+8, y0+8, "Please wait", 255, 216, 32, 255); + drawtext(vid_buf, x0+8, y0+26, "Downloading update...", 255, 255, 255, 255); + + if(total) + { + i = (236*done)/total; + fillrect(vid_buf, x0+1, y0+45, i+1, 14, 255, 216, 32, 255); + i = (100*done)/total; + sprintf(str, "%d%%", i); + if(i<50) + drawtext(vid_buf, x0+120-textwidth(str)/2, y0+48, str, 192, 192, 192, 255); + else + drawtext(vid_buf, x0+120-textwidth(str)/2, y0+48, str, 0, 0, 0, 255); + } + else + drawtext(vid_buf, x0+120-textwidth("Waiting...")/2, y0+48, "Waiting...", 255, 216, 32, 255); + + drawrect(vid_buf, x0, y0+44, 240, 16, 192, 192, 192, 255); + sdl_blit(0, 0, (XRES+BARSIZE), YRES+MENUSIZE, vid_buf, (XRES+BARSIZE)); + } + + tmp = http_async_req_stop(http, &ret, &zlen); + if(ret!=200) + { + error_ui(vid_buf, ret, http_ret_text(ret)); + if(tmp) + free(tmp); + return NULL; + } + if(!tmp) + { + error_ui(vid_buf, 0, "Server did not return data"); + return NULL; + } + + if(zlen<16) + { + printf("ZLen is not 16!\n"); + goto corrupt; + } + if(tmp[0]!=0x42 || tmp[1]!=0x75 || tmp[2]!=0x54 || tmp[3]!=0x54) + { + printf("Tmperr %d, %d, %d, %d\n", tmp[0], tmp[1], tmp[2], tmp[3]); + goto corrupt; + } + + ulen = (unsigned char)tmp[4]; + ulen |= ((unsigned char)tmp[5])<<8; + ulen |= ((unsigned char)tmp[6])<<16; + ulen |= ((unsigned char)tmp[7])<<24; + + res = (char *)malloc(ulen); + if(!res) + { + printf("No res!\n"); + goto corrupt; + } + dstate = BZ2_bzBuffToBuffDecompress((char *)res, (unsigned *)&ulen, (char *)(tmp+8), zlen-8, 0, 0); + if(dstate) + { + printf("Decompression failure: %d!\n", dstate); + free(res); + goto corrupt; + } + + free(tmp); + if(len) + *len = ulen; + return res; + +corrupt: + error_ui(vid_buf, 0, "Downloaded update is corrupted"); + free(tmp); + return NULL; +} + +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,own,last_own=search_own,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); + float ry; + time_t http_last_use=HTTP_TIMEOUT; + ui_edit ed; + + + void *http = NULL; + int active = 0; + char *last = NULL; + int search = 0; + int lasttime = TIMEOUT; + char *uri; + int status; + char *results; + char *tmp, ts[64]; + + void *img_http[IMGCONNS]; + char *img_id[IMGCONNS]; + void *thumb, *data; + int thlen, dlen; + + memset(v_buf, 0, ((YRES+MENUSIZE)*(XRES+BARSIZE))*PIXELSIZE); + + memset(img_http, 0, sizeof(img_http)); + memset(img_id, 0, sizeof(img_id)); + + memset(search_ids, 0, sizeof(search_ids)); + memset(search_names, 0, sizeof(search_names)); + memset(search_scoreup, 0, sizeof(search_scoreup)); + memset(search_scoredown, 0, sizeof(search_scoredown)); + memset(search_publish, 0, sizeof(search_publish)); + memset(search_owners, 0, sizeof(search_owners)); + memset(search_thumbs, 0, sizeof(search_thumbs)); + memset(search_thsizes, 0, sizeof(search_thsizes)); + + memset(thumb_drawn, 0, sizeof(thumb_drawn)); + + do_open = 0; + + while(!sdl_poll()) + { + b = SDL_GetMouseState(&mx, &my); + if(!b) + break; + } + + ed.x = 65; + ed.y = 13; + ed.w = XRES-200; + ed.nx = 1; + ed.def = "[search terms]"; + ed.focus = 1; + ed.hide = 0; + ed.cursor = strlen(search_expr); + strcpy(ed.str, search_expr); + + sdl_wheel = 0; + + while(!sdl_poll()) + { + uih = 0; + bq = b; + mxq = mx; + myq = my; + b = SDL_GetMouseState(&mx, &my); + mx /= sdl_scale; + my /= sdl_scale; + + if(mx!=mxq || my!=myq || sdl_wheel || b) + mmt = 0; + else if(mmt 9) + { + drawtext(vid_buf, XRES-15, YRES+MENUSIZE-16, "\x95", 255, 255, 255, 255); + drawrect(vid_buf, XRES-18, YRES+MENUSIZE-20, 16, 16, 255, 255, 255, 255); + } + + ui_edit_draw(vid_buf, &ed); + + if((b && !bq && mx>=1 && mx<=17 && my>=YRES+MENUSIZE-20 && my0) + { + if(search_page) + { + search_page --; + lasttime = TIMEOUT; + } + sdl_wheel = 0; + uih = 1; + } + if((b && !bq && mx>=XRES-18 && mx<=XRES-1 && my>=YRES+MENUSIZE-20 && myexp_res) + { + lasttime = TIMEOUT; + search_page ++; + page_count = exp_res; + } + sdl_wheel = 0; + uih = 1; + } + + tp = -1; + if(is_p1) + { + drawtext(vid_buf, (XRES-textwidth("Popular tags:"))/2, 31, "Popular tags:", 255, 192, 64, 255); + for(gj=0; gj<((GRID_Y-GRID_P)*YRES)/(GRID_Y*14); gj++) + for(gi=0; giTAG_MAX || !tag_names[pos]) + break; + if(tag_votes[0]) + i = 127+(128*tag_votes[pos])/tag_votes[0]; + else + i = 192; + w = textwidth(tag_names[pos]); + if(w>XRES/GRID_X-5) + w = XRES/GRID_X-5; + gx = (XRES/GRID_X)*gi; + gy = gj*14 + 46; + if(mx>=gx && mx=gy && my XRES/GRID_X-10) + { + tmp = malloc(strlen(search_names[pos])+4); + strcpy(tmp, search_names[pos]); + j = textwidthx(tmp, XRES/GRID_X-15); + strcpy(tmp+j, "..."); + drawtext(vid_buf, gx+XRES/(GRID_S*2)-textwidth(tmp)/2, gy+YRES/GRID_S+7, tmp, 192, 192, 192, 255); + free(tmp); + } + else + drawtext(vid_buf, gx+XRES/(GRID_S*2)-textwidth(search_names[pos])/2, gy+YRES/GRID_S+7, search_names[pos], 192, 192, 192, 255); + j = textwidth(search_owners[pos]); + if(mx>=gx+XRES/(GRID_S*2)-j/2 && mx<=gx+XRES/(GRID_S*2)+j/2 && + my>=gy+YRES/GRID_S+18 && my<=gy+YRES/GRID_S+31) + { + st = 1; + drawtext(vid_buf, gx+XRES/(GRID_S*2)-j/2, gy+YRES/GRID_S+20, search_owners[pos], 128, 128, 160, 255); + } + else + drawtext(vid_buf, gx+XRES/(GRID_S*2)-j/2, gy+YRES/GRID_S+20, search_owners[pos], 128, 128, 128, 255); + if(search_thumbs[pos]&&thumb_drawn[pos]==0) + { + render_thumb(search_thumbs[pos], search_thsizes[pos], 1, v_buf, gx, gy, GRID_S); + thumb_drawn[pos] = 1; + } + own = svf_login && (!strcmp(svf_user, search_owners[pos]) || svf_admin || svf_mod); + if(mx>=gx-2 && mx<=gx+XRES/GRID_S+3 && my>=gy-2 && my<=gy+YRES/GRID_S+30) + mp = pos; + if(own) + { + if(mx>=gx+XRES/GRID_S-4 && mx<=gx+XRES/GRID_S+6 && my>=gy-6 && my<=gy+4) + { + mp = -1; + dp = pos; + } + } + if(mp==pos && !st) + drawrect(vid_buf, gx-2, gy-2, XRES/GRID_S+3, YRES/GRID_S+3, 160, 160, 192, 255); + else + drawrect(vid_buf, gx-2, gy-2, XRES/GRID_S+3, YRES/GRID_S+3, 128, 128, 128, 255); + if(own) + { + if(dp == pos) + drawtext(vid_buf, gx+XRES/GRID_S-4, gy-6, "\x86", 255, 48, 32, 255); + else + drawtext(vid_buf, gx+XRES/GRID_S-4, gy-6, "\x86", 160, 48, 32, 255); + drawtext(vid_buf, gx+XRES/GRID_S-4, gy-6, "\x85", 255, 255, 255, 255); + } + if(!search_publish[pos]) + { + drawtext(vid_buf, gx-6, gy-6, "\xCD", 255, 255, 255, 255); + drawtext(vid_buf, gx-6, gy-6, "\xCE", 212, 151, 81, 255); + } + if(view_own || svf_admin || svf_mod) + { + sprintf(ts+1, "%d", search_votes[pos]); + ts[0] = 0xBB; + for(j=1; ts[j]; j++) + ts[j] = 0xBC; + ts[j-1] = 0xB9; + ts[j] = 0xBA; + ts[j+1] = 0; + w = gx+XRES/GRID_S-2-textwidth(ts); + h = gy+YRES/GRID_S-11; + drawtext(vid_buf, w, h, ts, 16, 72, 16, 255); + for(j=0; ts[j]; j++) + ts[j] -= 14; + drawtext(vid_buf, w, h, ts, 192, 192, 192, 255); + sprintf(ts, "%d", search_votes[pos]); + for(j=0; ts[j]; j++) + ts[j] += 127; + drawtext(vid_buf, w+3, h, ts, 255, 255, 255, 255); + } + if(search_scoreup[pos]>0||search_scoredown[pos]>0) + { + lv = (search_scoreup[pos]>search_scoredown[pos]?search_scoreup[pos]:search_scoredown[pos]); + + if(((YRES/GRID_S+3)/2)>lv) + { + ry = ((float)((YRES/GRID_S+3)/2)/(float)lv); + if(lv<8) + { + ry = ry/(8-lv); + } + nyu = search_scoreup[pos]*ry; + nyd = search_scoredown[pos]*ry; + } + else + { + ry = ((float)lv/(float)((YRES/GRID_S+3)/2)); + nyu = search_scoreup[pos]/ry; + nyd = search_scoredown[pos]/ry; + } + + fillrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)-nyu, 4, nyu, 0, 187, 40, 255); + fillrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)+1, 4, nyd, 187, 40, 0, 255); + + drawrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)-nyu, 4, nyu, 0, 107, 10, 255); + drawrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)+1, 4, nyd, 107, 10, 0, 255); + } + } + + if(mp!=-1 && mmt>=TIMEOUT/5 && !st) + { + gi = mp % GRID_X; + gj = mp / GRID_X; + if(is_p1) + gj += GRID_Y-GRID_P; + gx = ((XRES/GRID_X)*gi) + (XRES/GRID_X-XRES/GRID_S)/2; + gy = (((YRES+15)/GRID_Y)*gj) + (YRES/GRID_Y-YRES/GRID_S+10)/2 + 18; + i = w = textwidth(search_names[mp]); + h = YRES/GRID_Z+30; + if(w=XRES-2) gx=XRES-3-w; + if(gy<32) gy=32; + if(gy+h>=YRES+(MENUSIZE-2)) gy=YRES+(MENUSIZE-3)-h; + clearrect(vid_buf, gx-2, gy-3, w+4, h); + drawrect(vid_buf, gx-2, gy-3, w+4, h, 160, 160, 192, 255); + if(search_thumbs[mp]) + render_thumb(search_thumbs[mp], search_thsizes[mp], 1, vid_buf, gx+(w-(XRES/GRID_Z))/2, gy, GRID_Z); + drawtext(vid_buf, gx+(w-i)/2, gy+YRES/GRID_Z+4, search_names[mp], 192, 192, 192, 255); + drawtext(vid_buf, gx+(w-textwidth(search_owners[mp]))/2, gy+YRES/GRID_Z+16, search_owners[mp], 128, 128, 128, 255); + } + + sdl_blit(0, 0, (XRES+BARSIZE), YRES+MENUSIZE, vid_buf, (XRES+BARSIZE)); + + ui_edit_process(mx, my, b, &ed); + + if(sdl_key==SDLK_RETURN) + { + if(!last || (!active && (strcmp(last, ed.str) || last_own!=search_own || last_date!=search_date || last_page!=search_page))) + lasttime = TIMEOUT; + else if(search_ids[0] && !search_ids[1]) + { + bq = 0; + b = 1; + mp = 0; + } + } + if(sdl_key==SDLK_ESCAPE) + goto finish; + + if(b && !bq && mx>=XRES-64 && mx<=XRES-8 && 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) + { + search_date = !search_date; + lasttime = TIMEOUT; + } + + if(b && !bq && dp!=-1) + if(confirm_ui(vid_buf, "Do you want to delete?", search_names[dp], "Delete")) + { + execute_delete(vid_buf, search_ids[dp]); + lasttime = TIMEOUT; + if(last) + { + free(last); + last = NULL; + } + } + + if(b && !bq && tp!=-1) + { + strncpy(ed.str, tag_names[tp], 255); + lasttime = TIMEOUT; + } + + if(b && !bq && mp!=-1 && st) + { + sprintf(ed.str, "user:%s", search_owners[mp]); + lasttime = TIMEOUT; + } + + if(do_open==1) + { + mp = 0; + } + + if((b && !bq && mp!=-1 && !st && !uih) || do_open==1) + { + fillrect(vid_buf, 0, 0, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 255); + info_box(vid_buf, "Loading..."); + + uri = malloc(strlen(search_ids[mp])*3+strlen(SERVER)+64); + strcpy(uri, "http://" SERVER "/Get.api?Op=save&ID="); + strcaturl(uri, search_ids[mp]); + data = http_simple_get(uri, &status, &dlen); + free(uri); + + if(status == 200) + { + status = parse_save(data, dlen, 1, 0, 0); + switch(status) + { + case 1: + error_ui(vid_buf, 0, "Simulation corrupted"); + break; + case 2: + error_ui(vid_buf, 0, "Simulation from a newer version"); + break; + case 3: + error_ui(vid_buf, 0, "Simulation on a too large grid"); + break; + } + if(!status) + { + char *tnames[] = {"ID", NULL}; + char *tparts[1]; + int tplens[1]; + if(svf_last) + free(svf_last); + svf_last = data; + svf_lsize = dlen; + + tparts[0] = search_ids[mp]; + tplens[0] = strlen(search_ids[mp]); + data = http_multipart_post("http://" SERVER "/Tags.api", tnames, tparts, tplens, svf_user, svf_pass, &status, NULL); + + svf_open = 1; + svf_own = svf_login && !strcmp(search_owners[mp], svf_user); + svf_publish = search_publish[mp] && svf_login && !strcmp(search_owners[mp], svf_user); + + strcpy(svf_id, search_ids[mp]); + strcpy(svf_name, search_names[mp]); + if(status == 200) + { + if(data) + { + strncpy(svf_tags, data, 255); + svf_tags[255] = 0; + } + else + svf_tags[0] = 0; + } + else + { + svf_tags[0] = 0; + } + + if(svf_login) + { + char *names[] = {"ID", NULL}; + char *parts[1]; + parts[0] = search_ids[mp]; + data = http_multipart_post("http://" SERVER "/Vote.api", names, parts, NULL, svf_user, svf_pass, &status, NULL); + if(status == 200) + { + if(data) + { + if(!strcmp(data, "Up")) + { + svf_myvote = 1; + } + else if(!strcmp(data, "Down")) + { + svf_myvote = -1; + } + else + { + svf_myvote = 0; + } + } + else + { + svf_myvote = 0; + } + } + else + { + svf_myvote = 0; + } + } + } + else + { + 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; + } + } + else + error_ui(vid_buf, status, http_ret_text(status)); + + if(data) + free(data); + 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)) + { + search = 1; + if(strcmp(last, ed.str) || last_own!=search_own || last_date!=search_date) + { + search_page = 0; + page_count = 0; + } + free(last); + last = NULL; + } + else + search = 0; + + if(search && lasttime>=TIMEOUT) + { + lasttime = 0; + last = mystrdup(ed.str); + last_own = search_own; + last_date = search_date; + last_page = search_page; + active = 1; + uri = malloc(strlen(last)*3+80+strlen(SERVER)+strlen(svf_user)); + if(search_own || svf_admin || svf_mod) + tmp = "&ShowVotes=true"; + else + tmp = ""; + if(!search_own && !search_date && !*last) + { + if(search_page) + { + exp_res = GRID_X*GRID_Y; + sprintf(uri, "http://" SERVER "/Search.api?Start=%d&Count=%d%s&Query=", (search_page-1)*GRID_X*GRID_Y+GRID_X*GRID_P, exp_res+1, tmp); + } + else + { + exp_res = GRID_X*GRID_P; + sprintf(uri, "http://" SERVER "/Search.api?Start=%d&Count=%d&t=%d%s&Query=", 0, exp_res+1, ((GRID_Y-GRID_P)*YRES)/(GRID_Y*14)*GRID_X, tmp); + } + } + else + { + exp_res = GRID_X*GRID_Y; + sprintf(uri, "http://" SERVER "/Search.api?Start=%d&Count=%d%s&Query=", search_page*GRID_X*GRID_Y, exp_res+1, tmp); + } + strcaturl(uri, last); + if(search_own) + { + strcaturl(uri, " user:"); + strcaturl(uri, svf_user); + } + if(search_date) + strcaturl(uri, " sort:date"); + + http = http_async_req_start(http, uri, NULL, 0, 1); + if(svf_login) + { + http_auth_headers(http, svf_user, svf_pass); + } + http_last_use = time(NULL); + free(uri); + } + + if(active && http_async_req_status(http)) + { + http_last_use = time(NULL); + results = http_async_req_stop(http, &status, NULL); + view_own = last_own; + if(status == 200) + { + page_count = search_results(results, last_own||svf_admin||svf_mod); + memset(thumb_drawn, 0, sizeof(thumb_drawn)); + memset(v_buf, 0, ((YRES+MENUSIZE)*(XRES+BARSIZE))*PIXELSIZE); + } + is_p1 = (exp_res < GRID_X*GRID_Y); + free(results); + active = 0; + } + + if(http && !active && (time(NULL)>http_last_use+HTTP_TIMEOUT)) + { + http_async_req_close(http); + http = NULL; + } + + for(i=0; i +#include "graphics.h" struct menu_section { @@ -98,8 +100,30 @@ extern char svf_tags[256]; extern void *svf_last; extern int svf_lsize; +extern char *search_ids[GRID_X*GRID_Y]; +extern int search_votes[GRID_X*GRID_Y]; +extern int search_publish[GRID_X*GRID_Y]; +extern int search_scoredown[GRID_X*GRID_Y]; +extern int search_scoreup[GRID_X*GRID_Y]; +extern char *search_names[GRID_X*GRID_Y]; +extern char *search_owners[GRID_X*GRID_Y]; +extern void *search_thumbs[GRID_X*GRID_Y]; +extern int search_thsizes[GRID_X*GRID_Y]; + +extern int search_own; +extern int search_date; +extern int search_page; +extern char search_expr[256]; + +extern char *tag_names[TAG_MAX]; +extern int tag_votes[TAG_MAX]; + extern int Z_keysym; +extern int zoom_en; +extern int zoom_x, zoom_y; +extern int zoom_wx, zoom_wy; + void menu_count(void); void get_sign_pos(int i, int *x0, int *y0, int *w, int *h); @@ -139,4 +163,8 @@ void menu_ui_v3(pixel *vid_buf, int i, int *sl, int *sr, int b, int bq, int mx, int sdl_poll(void); void set_cmode(int cm); + +char *download_ui(pixel *vid_buf, char *uri, int *len); + +int search_ui(pixel *vid_buf); #endif \ No newline at end of file diff --git a/main.c b/main.c index e30a97260..1d818a84f 100644 --- a/main.c +++ b/main.c @@ -145,7 +145,6 @@ int mousex, mousey = 0; //They contain mouse position * SDL OUTPUT * ***********************************************************/ -#include "icon.h" void sdl_seticon(void) { #ifdef WIN32 @@ -1335,8 +1334,6 @@ void strcaturl(char *dst, char *src) *d = 0; } -#define THUMB_CACHE_SIZE 256 - char *thumb_cache_id[THUMB_CACHE_SIZE]; void *thumb_cache_data[THUMB_CACHE_SIZE]; int thumb_cache_size[THUMB_CACHE_SIZE]; @@ -1402,20 +1399,6 @@ int thumb_cache_find(char *id, void **thumb, int *size) return 1; } -char *search_ids[GRID_X*GRID_Y]; -int search_votes[GRID_X*GRID_Y]; -int search_publish[GRID_X*GRID_Y]; -int search_scoredown[GRID_X*GRID_Y]; -int search_scoreup[GRID_X*GRID_Y]; -char *search_names[GRID_X*GRID_Y]; -char *search_owners[GRID_X*GRID_Y]; -void *search_thumbs[GRID_X*GRID_Y]; -int search_thsizes[GRID_X*GRID_Y]; - -#define TAG_MAX 256 -char *tag_names[TAG_MAX]; -int tag_votes[TAG_MAX]; - int search_results(char *str, int votes) { int i,j; @@ -1616,705 +1599,6 @@ int search_results(char *str, int votes) return i; } -#define IMGCONNS 3 -#define TIMEOUT 100 -#define HTTP_TIMEOUT 10 - -int search_own = 0; -int search_date = 0; -int search_page = 0; -char search_expr[256] = ""; - -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,own,last_own=search_own,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); - float ry; - time_t http_last_use=HTTP_TIMEOUT; - ui_edit ed; - - - void *http = NULL; - int active = 0; - char *last = NULL; - int search = 0; - int lasttime = TIMEOUT; - char *uri; - int status; - char *results; - char *tmp, ts[64]; - - void *img_http[IMGCONNS]; - char *img_id[IMGCONNS]; - void *thumb, *data; - int thlen, dlen; - - memset(v_buf, 0, ((YRES+MENUSIZE)*(XRES+BARSIZE))*PIXELSIZE); - - memset(img_http, 0, sizeof(img_http)); - memset(img_id, 0, sizeof(img_id)); - - memset(search_ids, 0, sizeof(search_ids)); - memset(search_names, 0, sizeof(search_names)); - memset(search_scoreup, 0, sizeof(search_scoreup)); - memset(search_scoredown, 0, sizeof(search_scoredown)); - memset(search_publish, 0, sizeof(search_publish)); - memset(search_owners, 0, sizeof(search_owners)); - memset(search_thumbs, 0, sizeof(search_thumbs)); - memset(search_thsizes, 0, sizeof(search_thsizes)); - - memset(thumb_drawn, 0, sizeof(thumb_drawn)); - - do_open = 0; - - while(!sdl_poll()) - { - b = SDL_GetMouseState(&mx, &my); - if(!b) - break; - } - - ed.x = 65; - ed.y = 13; - ed.w = XRES-200; - ed.nx = 1; - ed.def = "[search terms]"; - ed.focus = 1; - ed.hide = 0; - ed.cursor = strlen(search_expr); - strcpy(ed.str, search_expr); - - sdl_wheel = 0; - - while(!sdl_poll()) - { - uih = 0; - bq = b; - mxq = mx; - myq = my; - b = SDL_GetMouseState(&mx, &my); - mx /= sdl_scale; - my /= sdl_scale; - - if(mx!=mxq || my!=myq || sdl_wheel || b) - mmt = 0; - else if(mmt 9) - { - drawtext(vid_buf, XRES-15, YRES+MENUSIZE-16, "\x95", 255, 255, 255, 255); - drawrect(vid_buf, XRES-18, YRES+MENUSIZE-20, 16, 16, 255, 255, 255, 255); - } - - ui_edit_draw(vid_buf, &ed); - - if((b && !bq && mx>=1 && mx<=17 && my>=YRES+MENUSIZE-20 && my0) - { - if(search_page) - { - search_page --; - lasttime = TIMEOUT; - } - sdl_wheel = 0; - uih = 1; - } - if((b && !bq && mx>=XRES-18 && mx<=XRES-1 && my>=YRES+MENUSIZE-20 && myexp_res) - { - lasttime = TIMEOUT; - search_page ++; - page_count = exp_res; - } - sdl_wheel = 0; - uih = 1; - } - - tp = -1; - if(is_p1) - { - drawtext(vid_buf, (XRES-textwidth("Popular tags:"))/2, 31, "Popular tags:", 255, 192, 64, 255); - for(gj=0; gj<((GRID_Y-GRID_P)*YRES)/(GRID_Y*14); gj++) - for(gi=0; giTAG_MAX || !tag_names[pos]) - break; - if(tag_votes[0]) - i = 127+(128*tag_votes[pos])/tag_votes[0]; - else - i = 192; - w = textwidth(tag_names[pos]); - if(w>XRES/GRID_X-5) - w = XRES/GRID_X-5; - gx = (XRES/GRID_X)*gi; - gy = gj*14 + 46; - if(mx>=gx && mx=gy && my XRES/GRID_X-10) - { - tmp = malloc(strlen(search_names[pos])+4); - strcpy(tmp, search_names[pos]); - j = textwidthx(tmp, XRES/GRID_X-15); - strcpy(tmp+j, "..."); - drawtext(vid_buf, gx+XRES/(GRID_S*2)-textwidth(tmp)/2, gy+YRES/GRID_S+7, tmp, 192, 192, 192, 255); - free(tmp); - } - else - drawtext(vid_buf, gx+XRES/(GRID_S*2)-textwidth(search_names[pos])/2, gy+YRES/GRID_S+7, search_names[pos], 192, 192, 192, 255); - j = textwidth(search_owners[pos]); - if(mx>=gx+XRES/(GRID_S*2)-j/2 && mx<=gx+XRES/(GRID_S*2)+j/2 && - my>=gy+YRES/GRID_S+18 && my<=gy+YRES/GRID_S+31) - { - st = 1; - drawtext(vid_buf, gx+XRES/(GRID_S*2)-j/2, gy+YRES/GRID_S+20, search_owners[pos], 128, 128, 160, 255); - } - else - drawtext(vid_buf, gx+XRES/(GRID_S*2)-j/2, gy+YRES/GRID_S+20, search_owners[pos], 128, 128, 128, 255); - if(search_thumbs[pos]&&thumb_drawn[pos]==0) - { - render_thumb(search_thumbs[pos], search_thsizes[pos], 1, v_buf, gx, gy, GRID_S); - thumb_drawn[pos] = 1; - } - own = svf_login && (!strcmp(svf_user, search_owners[pos]) || svf_admin || svf_mod); - if(mx>=gx-2 && mx<=gx+XRES/GRID_S+3 && my>=gy-2 && my<=gy+YRES/GRID_S+30) - mp = pos; - if(own) - { - if(mx>=gx+XRES/GRID_S-4 && mx<=gx+XRES/GRID_S+6 && my>=gy-6 && my<=gy+4) - { - mp = -1; - dp = pos; - } - } - if(mp==pos && !st) - drawrect(vid_buf, gx-2, gy-2, XRES/GRID_S+3, YRES/GRID_S+3, 160, 160, 192, 255); - else - drawrect(vid_buf, gx-2, gy-2, XRES/GRID_S+3, YRES/GRID_S+3, 128, 128, 128, 255); - if(own) - { - if(dp == pos) - drawtext(vid_buf, gx+XRES/GRID_S-4, gy-6, "\x86", 255, 48, 32, 255); - else - drawtext(vid_buf, gx+XRES/GRID_S-4, gy-6, "\x86", 160, 48, 32, 255); - drawtext(vid_buf, gx+XRES/GRID_S-4, gy-6, "\x85", 255, 255, 255, 255); - } - if(!search_publish[pos]) - { - drawtext(vid_buf, gx-6, gy-6, "\xCD", 255, 255, 255, 255); - drawtext(vid_buf, gx-6, gy-6, "\xCE", 212, 151, 81, 255); - } - if(view_own || svf_admin || svf_mod) - { - sprintf(ts+1, "%d", search_votes[pos]); - ts[0] = 0xBB; - for(j=1; ts[j]; j++) - ts[j] = 0xBC; - ts[j-1] = 0xB9; - ts[j] = 0xBA; - ts[j+1] = 0; - w = gx+XRES/GRID_S-2-textwidth(ts); - h = gy+YRES/GRID_S-11; - drawtext(vid_buf, w, h, ts, 16, 72, 16, 255); - for(j=0; ts[j]; j++) - ts[j] -= 14; - drawtext(vid_buf, w, h, ts, 192, 192, 192, 255); - sprintf(ts, "%d", search_votes[pos]); - for(j=0; ts[j]; j++) - ts[j] += 127; - drawtext(vid_buf, w+3, h, ts, 255, 255, 255, 255); - } - if(search_scoreup[pos]>0||search_scoredown[pos]>0) - { - lv = (search_scoreup[pos]>search_scoredown[pos]?search_scoreup[pos]:search_scoredown[pos]); - - if(((YRES/GRID_S+3)/2)>lv) - { - ry = ((float)((YRES/GRID_S+3)/2)/(float)lv); - if(lv<8) - { - ry = ry/(8-lv); - } - nyu = search_scoreup[pos]*ry; - nyd = search_scoredown[pos]*ry; - } - else - { - ry = ((float)lv/(float)((YRES/GRID_S+3)/2)); - nyu = search_scoreup[pos]/ry; - nyd = search_scoredown[pos]/ry; - } - - fillrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)-nyu, 4, nyu, 0, 187, 40, 255); - fillrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)+1, 4, nyd, 187, 40, 0, 255); - - drawrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)-nyu, 4, nyu, 0, 107, 10, 255); - drawrect(vid_buf, gx-2+(XRES/GRID_S)+5, gy-2+((YRES/GRID_S+3)/2)+1, 4, nyd, 107, 10, 0, 255); - } - } - - if(mp!=-1 && mmt>=TIMEOUT/5 && !st) - { - gi = mp % GRID_X; - gj = mp / GRID_X; - if(is_p1) - gj += GRID_Y-GRID_P; - gx = ((XRES/GRID_X)*gi) + (XRES/GRID_X-XRES/GRID_S)/2; - gy = (((YRES+15)/GRID_Y)*gj) + (YRES/GRID_Y-YRES/GRID_S+10)/2 + 18; - i = w = textwidth(search_names[mp]); - h = YRES/GRID_Z+30; - if(w=XRES-2) gx=XRES-3-w; - if(gy<32) gy=32; - if(gy+h>=YRES+(MENUSIZE-2)) gy=YRES+(MENUSIZE-3)-h; - clearrect(vid_buf, gx-2, gy-3, w+4, h); - drawrect(vid_buf, gx-2, gy-3, w+4, h, 160, 160, 192, 255); - if(search_thumbs[mp]) - render_thumb(search_thumbs[mp], search_thsizes[mp], 1, vid_buf, gx+(w-(XRES/GRID_Z))/2, gy, GRID_Z); - drawtext(vid_buf, gx+(w-i)/2, gy+YRES/GRID_Z+4, search_names[mp], 192, 192, 192, 255); - drawtext(vid_buf, gx+(w-textwidth(search_owners[mp]))/2, gy+YRES/GRID_Z+16, search_owners[mp], 128, 128, 128, 255); - } - - sdl_blit(0, 0, (XRES+BARSIZE), YRES+MENUSIZE, vid_buf, (XRES+BARSIZE)); - - ui_edit_process(mx, my, b, &ed); - - if(sdl_key==SDLK_RETURN) - { - if(!last || (!active && (strcmp(last, ed.str) || last_own!=search_own || last_date!=search_date || last_page!=search_page))) - lasttime = TIMEOUT; - else if(search_ids[0] && !search_ids[1]) - { - bq = 0; - b = 1; - mp = 0; - } - } - if(sdl_key==SDLK_ESCAPE) - goto finish; - - if(b && !bq && mx>=XRES-64 && mx<=XRES-8 && 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) - { - search_date = !search_date; - lasttime = TIMEOUT; - } - - if(b && !bq && dp!=-1) - if(confirm_ui(vid_buf, "Do you want to delete?", search_names[dp], "Delete")) - { - execute_delete(vid_buf, search_ids[dp]); - lasttime = TIMEOUT; - if(last) - { - free(last); - last = NULL; - } - } - - if(b && !bq && tp!=-1) - { - strncpy(ed.str, tag_names[tp], 255); - lasttime = TIMEOUT; - } - - if(b && !bq && mp!=-1 && st) - { - sprintf(ed.str, "user:%s", search_owners[mp]); - lasttime = TIMEOUT; - } - - if(do_open==1) - { - mp = 0; - } - - if((b && !bq && mp!=-1 && !st && !uih) || do_open==1) - { - fillrect(vid_buf, 0, 0, XRES+BARSIZE, YRES+MENUSIZE, 0, 0, 0, 255); - info_box(vid_buf, "Loading..."); - - uri = malloc(strlen(search_ids[mp])*3+strlen(SERVER)+64); - strcpy(uri, "http://" SERVER "/Get.api?Op=save&ID="); - strcaturl(uri, search_ids[mp]); - data = http_simple_get(uri, &status, &dlen); - free(uri); - - if(status == 200) - { - status = parse_save(data, dlen, 1, 0, 0); - switch(status) - { - case 1: - error_ui(vid_buf, 0, "Simulation corrupted"); - break; - case 2: - error_ui(vid_buf, 0, "Simulation from a newer version"); - break; - case 3: - error_ui(vid_buf, 0, "Simulation on a too large grid"); - break; - } - if(!status) - { - char *tnames[] = {"ID", NULL}; - char *tparts[1]; - int tplens[1]; - if(svf_last) - free(svf_last); - svf_last = data; - svf_lsize = dlen; - - tparts[0] = search_ids[mp]; - tplens[0] = strlen(search_ids[mp]); - data = http_multipart_post("http://" SERVER "/Tags.api", tnames, tparts, tplens, svf_user, svf_pass, &status, NULL); - - svf_open = 1; - svf_own = svf_login && !strcmp(search_owners[mp], svf_user); - svf_publish = search_publish[mp] && svf_login && !strcmp(search_owners[mp], svf_user); - - strcpy(svf_id, search_ids[mp]); - strcpy(svf_name, search_names[mp]); - if(status == 200) - { - if(data) - { - strncpy(svf_tags, data, 255); - svf_tags[255] = 0; - } - else - svf_tags[0] = 0; - } - else - { - svf_tags[0] = 0; - } - - if(svf_login) - { - char *names[] = {"ID", NULL}; - char *parts[1]; - parts[0] = search_ids[mp]; - data = http_multipart_post("http://" SERVER "/Vote.api", names, parts, NULL, svf_user, svf_pass, &status, NULL); - if(status == 200) - { - if(data) - { - if(!strcmp(data, "Up")) - { - svf_myvote = 1; - } - else if(!strcmp(data, "Down")) - { - svf_myvote = -1; - } - else - { - svf_myvote = 0; - } - } - else - { - svf_myvote = 0; - } - } - else - { - svf_myvote = 0; - } - } - } - else - { - 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; - } - } - else - error_ui(vid_buf, status, http_ret_text(status)); - - if(data) - free(data); - 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)) - { - search = 1; - if(strcmp(last, ed.str) || last_own!=search_own || last_date!=search_date) - { - search_page = 0; - page_count = 0; - } - free(last); - last = NULL; - } - else - search = 0; - - if(search && lasttime>=TIMEOUT) - { - lasttime = 0; - last = mystrdup(ed.str); - last_own = search_own; - last_date = search_date; - last_page = search_page; - active = 1; - uri = malloc(strlen(last)*3+80+strlen(SERVER)+strlen(svf_user)); - if(search_own || svf_admin || svf_mod) - tmp = "&ShowVotes=true"; - else - tmp = ""; - if(!search_own && !search_date && !*last) - { - if(search_page) - { - exp_res = GRID_X*GRID_Y; - sprintf(uri, "http://" SERVER "/Search.api?Start=%d&Count=%d%s&Query=", (search_page-1)*GRID_X*GRID_Y+GRID_X*GRID_P, exp_res+1, tmp); - } - else - { - exp_res = GRID_X*GRID_P; - sprintf(uri, "http://" SERVER "/Search.api?Start=%d&Count=%d&t=%d%s&Query=", 0, exp_res+1, ((GRID_Y-GRID_P)*YRES)/(GRID_Y*14)*GRID_X, tmp); - } - } - else - { - exp_res = GRID_X*GRID_Y; - sprintf(uri, "http://" SERVER "/Search.api?Start=%d&Count=%d%s&Query=", search_page*GRID_X*GRID_Y, exp_res+1, tmp); - } - strcaturl(uri, last); - if(search_own) - { - strcaturl(uri, " user:"); - strcaturl(uri, svf_user); - } - if(search_date) - strcaturl(uri, " sort:date"); - - http = http_async_req_start(http, uri, NULL, 0, 1); - if(svf_login) - { - http_auth_headers(http, svf_user, svf_pass); - } - http_last_use = time(NULL); - free(uri); - } - - if(active && http_async_req_status(http)) - { - http_last_use = time(NULL); - results = http_async_req_stop(http, &status, NULL); - view_own = last_own; - if(status == 200) - { - page_count = search_results(results, last_own||svf_admin||svf_mod); - memset(thumb_drawn, 0, sizeof(thumb_drawn)); - memset(v_buf, 0, ((YRES+MENUSIZE)*(XRES+BARSIZE))*PIXELSIZE); - } - is_p1 = (exp_res < GRID_X*GRID_Y); - free(results); - active = 0; - } - - if(http && !active && (time(NULL)>http_last_use+HTTP_TIMEOUT)) - { - http_async_req_close(http); - http = NULL; - } - - for(i=0; i> 8; - fwrite(lb, 2, 1, f); - fwrite(str, li, 1, f); -} - -int load_string(FILE *f, char *str, int max) -{ - int li; - unsigned char lb[2]; - fread(lb, 2, 1, f); - li = lb[0] | (lb[1] << 8); - if(li > max) - { - str[0] = 0; - return 1; - } - fread(str, li, 1, f); - str[li] = 0; - return 0; -} +char http_proxy_string[256] = ""; unsigned char last_major=0, last_minor=0, update_flag=0; -void save_presets(int do_update) -{ - FILE *f=fopen("powder.def", "wb"); - unsigned char sig[4] = {0x50, 0x44, 0x65, 0x66}; - unsigned char tmp = sdl_scale; - if(!f) - return; - fwrite(sig, 1, 4, f); - save_string(f, svf_user); - save_string(f, svf_pass); - fwrite(&tmp, 1, 1, f); - tmp = cmode; - fwrite(&tmp, 1, 1, f); - tmp = svf_admin; - fwrite(&tmp, 1, 1, f); - tmp = svf_mod; - fwrite(&tmp, 1, 1, f); - save_string(f, http_proxy); - tmp = SAVE_VERSION; - fwrite(&tmp, 1, 1, f); - tmp = MINOR_VERSION; - fwrite(&tmp, 1, 1, f); - tmp = do_update; - fwrite(&tmp, 1, 1, f); - fclose(f); -} - -void load_presets(void) -{ - FILE *f=fopen("powder.def", "rb"); - unsigned char sig[4], tmp; - if(!f) - return; - fread(sig, 1, 4, f); - if(sig[0]!=0x50 || sig[1]!=0x44 || sig[2]!=0x65 || sig[3]!=0x66) - { - if(sig[0]==0x4D && sig[1]==0x6F && sig[2]==0x46 && sig[3]==0x6F) - { - if(fseek(f, -3, SEEK_END)) - { - remove("powder.def"); - return; - } - if(fread(sig, 1, 3, f) != 3) - { - remove("powder.def"); - goto fail; - } - last_major = sig[0]; - last_minor = sig[1]; - update_flag = sig[2]; - } - fclose(f); - remove("powder.def"); - return; - } - if(load_string(f, svf_user, 63)) - goto fail; - if(load_string(f, svf_pass, 63)) - goto fail; - svf_login = !!svf_user[0]; - if(fread(&tmp, 1, 1, f) != 1) - goto fail; - sdl_scale = (tmp == 2) ? 2 : 1; - if(fread(&tmp, 1, 1, f) != 1) - goto fail; - cmode = tmp%7; - if(fread(&tmp, 1, 1, f) != 1) - goto fail; - svf_admin = tmp; - if(fread(&tmp, 1, 1, f) != 1) - goto fail; - svf_mod = tmp; - if(load_string(f, http_proxy, 255)) - goto fail; - if(fread(sig, 1, 3, f) != 3) - goto fail; - last_major = sig[0]; - last_minor = sig[1]; - update_flag = sig[2]; -fail: - fclose(f); -} - -void dim_copy(pixel *dst, pixel *src) -{ - int i,r,g,b; - for(i=0; i0) - r--; - if(g>0) - g--; - if(b>0) - b--; - dst[i] = PIXRGB(r,g,b); - } -} - -int zoom_en = 0; -int zoom_x=(XRES-ZSIZE_D)/2, zoom_y=(YRES-ZSIZE_D)/2; -int zoom_wx=0, zoom_wy=0; -void render_zoom(pixel *img) -{ - int x, y, i, j; - pixel pix; - drawrect(img, zoom_wx-2, zoom_wy-2, ZSIZE*ZFACTOR+2, ZSIZE*ZFACTOR+2, 192, 192, 192, 255); - drawrect(img, zoom_wx-1, zoom_wy-1, ZSIZE*ZFACTOR, ZSIZE*ZFACTOR, 0, 0, 0, 255); - clearrect(img, zoom_wx, zoom_wy, ZSIZE*ZFACTOR, ZSIZE*ZFACTOR); - for(j=0; j #include #include #include "misc.h" +#include "defines.h" +#include "interface.h" +#include "graphics.h" //Signum function #ifdef WIN32 @@ -80,4 +84,114 @@ void strlist_free(struct strlist **list) *list = (*list)->next; free(item); } +} + +void save_presets(int do_update) +{ + FILE *f=fopen("powder.def", "wb"); + unsigned char sig[4] = {0x50, 0x44, 0x65, 0x66}; + unsigned char tmp = sdl_scale; + if(!f) + return; + fwrite(sig, 1, 4, f); + save_string(f, svf_user); + save_string(f, svf_pass); + fwrite(&tmp, 1, 1, f); + tmp = cmode; + fwrite(&tmp, 1, 1, f); + tmp = svf_admin; + fwrite(&tmp, 1, 1, f); + tmp = svf_mod; + fwrite(&tmp, 1, 1, f); + save_string(f, http_proxy_string); + tmp = SAVE_VERSION; + fwrite(&tmp, 1, 1, f); + tmp = MINOR_VERSION; + fwrite(&tmp, 1, 1, f); + tmp = do_update; + fwrite(&tmp, 1, 1, f); + fclose(f); +} + +void load_presets(void) +{ + FILE *f=fopen("powder.def", "rb"); + unsigned char sig[4], tmp; + if(!f) + return; + fread(sig, 1, 4, f); + if(sig[0]!=0x50 || sig[1]!=0x44 || sig[2]!=0x65 || sig[3]!=0x66) + { + if(sig[0]==0x4D && sig[1]==0x6F && sig[2]==0x46 && sig[3]==0x6F) + { + if(fseek(f, -3, SEEK_END)) + { + remove("powder.def"); + return; + } + if(fread(sig, 1, 3, f) != 3) + { + remove("powder.def"); + goto fail; + } + last_major = sig[0]; + last_minor = sig[1]; + update_flag = sig[2]; + } + fclose(f); + remove("powder.def"); + return; + } + if(load_string(f, svf_user, 63)) + goto fail; + if(load_string(f, svf_pass, 63)) + goto fail; + svf_login = !!svf_user[0]; + if(fread(&tmp, 1, 1, f) != 1) + goto fail; + sdl_scale = (tmp == 2) ? 2 : 1; + if(fread(&tmp, 1, 1, f) != 1) + goto fail; + cmode = tmp%7; + if(fread(&tmp, 1, 1, f) != 1) + goto fail; + svf_admin = tmp; + if(fread(&tmp, 1, 1, f) != 1) + goto fail; + svf_mod = tmp; + if(load_string(f, http_proxy_string, 255)) + goto fail; + if(fread(sig, 1, 3, f) != 3) + goto fail; + last_major = sig[0]; + last_minor = sig[1]; + update_flag = sig[2]; +fail: + fclose(f); +} + +void save_string(FILE *f, char *str) +{ + int li = strlen(str); + unsigned char lb[2]; + lb[0] = li; + lb[1] = li >> 8; + fwrite(lb, 2, 1, f); + fwrite(str, li, 1, f); +} + +int load_string(FILE *f, char *str, int max) +{ + int li; + unsigned char lb[2]; + fread(lb, 2, 1, f); + li = lb[0] | (lb[1] << 8); + if(li > max) + { + str[0] = 0; + return 1; + } + fread(str, li, 1, f); + str[li] = 0; + return 0; } \ No newline at end of file diff --git a/misc.h b/misc.h index e27909336..dbc2b8457 100644 --- a/misc.h +++ b/misc.h @@ -1,5 +1,7 @@ #ifndef UTILS_H #define UTILS_H +#include +#include //Signum function #ifdef WIN32 @@ -34,4 +36,12 @@ int strlist_find(struct strlist **list, char *str); void strlist_free(struct strlist **list); +void save_presets(int do_update); + +void load_presets(void); + +void save_string(FILE *f, char *str); + +int load_string(FILE *f, char *str, int max); + #endif \ No newline at end of file diff --git a/version.h b/version.h index 4f3791138..41e9672df 100755 --- a/version.h +++ b/version.h @@ -20,8 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define SAVE_VERSION 41 -#define MINOR_VERSION 3 -#define IDENT_VERSION "S" //Change this if you're not Simon! It should be a single letter. + #endif