#include #include #include #include #include #include #include "Config.h" #include "Misc.h" #include "icondoc.h" #if defined WIN32 #include #include #include #else #include #endif #ifdef MACOSX #include #endif char *clipboard_text = NULL; char *exe_name(void) { #if defined WIN32 char *name= (char *)malloc(64); DWORD max=64, res; while ((res = GetModuleFileName(NULL, name, max)) >= max) { #elif defined MACOSX char *fn=malloc(64),*name=malloc(PATH_MAX); uint32_t max=64, res; if (_NSGetExecutablePath(fn, &max) != 0) { fn = realloc(fn, max); _NSGetExecutablePath(fn, &max); } if (realpath(fn, name) == NULL) { free(fn); free(name); return NULL; } res = 1; #else char fn[64], *name=(char *)malloc(64); size_t max=64, res; sprintf(fn, "/proc/self/exe"); memset(name, 0, max); while ((res = readlink(fn, name, max)) >= max-1) { #endif #ifndef MACOSX max *= 2; name = (char *)realloc(name, max); memset(name, 0, max); } #endif if (res <= 0) { free(name); return NULL; } return name; } //Signum function int isign(float i) //TODO: INline or macro { if (i<0) return -1; if (i>0) return 1; return 0; } TPT_INLINE unsigned clamp_flt(float f, float min, float max) //TODO: Also inline/macro { if (fmax) return 255; return (int)(255.0f*(f-min)/(max-min)); } TPT_INLINE float restrict_flt(float f, float min, float max) //TODO Inline or macro or something { if (fmax) return max; return f; } char *mystrdup(char *s) { char *x; if (s) { x = (char*)malloc(strlen(s)+1); strcpy(x, s); return x; } return s; } void strlist_add(struct strlist **list, char *str) { struct strlist *item = (struct strlist*)malloc(sizeof(struct strlist)); item->str = mystrdup(str); item->next = *list; *list = item; } int strlist_find(struct strlist **list, char *str) { struct strlist *item; for (item=*list; item; item=item->next) if (!strcmp(item->str, str)) return 1; return 0; } void strlist_free(struct strlist **list) { struct strlist *item; while (*list) { item = *list; *list = (*list)->next; free(item); } } void clean_text(char *text, int vwidth) { int i = 0; if(strlen(text)*10 > vwidth){ text[vwidth/10] = 0; } for(i = 0; i < strlen(text); i++){ if(! (text[i]>=' ' && text[i]<127)){ text[i] = ' '; } } } int sregexp(const char *str, char *pattern) { int result; regex_t patternc; if (regcomp(&patternc, pattern, 0)!=0) return 1; result = regexec(&patternc, str, 0, NULL, 0); regfree(&patternc); return result; } 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; } void strcaturl(char *dst, char *src) { char *d; unsigned char *s; for (d=dst; *d; d++) ; for (s=(unsigned char *)src; *s; s++) { if ((*s>='0' && *s<='9') || (*s>='a' && *s<='z') || (*s>='A' && *s<='Z')) *(d++) = *s; else { *(d++) = '%'; *(d++) = hex[*s>>4]; *(d++) = hex[*s&15]; } } *d = 0; } std::string URLEscape(std::string source) { char * src = (char *)source.c_str(); char * dst = (char *)calloc((source.length()*3)+2, 1); char *d; unsigned char *s; for (d=dst; *d; d++) ; for (s=(unsigned char *)src; *s; s++) { if ((*s>='0' && *s<='9') || (*s>='a' && *s<='z') || (*s>='A' && *s<='Z')) *(d++) = *s; else { *(d++) = '%'; *(d++) = hex[*s>>4]; *(d++) = hex[*s&15]; } } *d = 0; std::string finalString(dst); free(dst); return finalString; } void strappend(char *dst, char *src) { char *d; unsigned char *s; for (d=dst; *d; d++) ; for (s=(unsigned char *)src; *s; s++) { *(d++) = *s; } *d = 0; } void *file_load(char *fn, int *size) { FILE *f = fopen(fn, "rb"); void *s; if (!f) return NULL; fseek(f, 0, SEEK_END); *size = ftell(f); fseek(f, 0, SEEK_SET); s = malloc(*size); if (!s) { fclose(f); return NULL; } fread(s, *size, 1, f); fclose(f); return s; } int cpu_check(void) { #ifdef MACOSX return 0; #else #ifdef X86 unsigned af,bf,cf,df; x86_cpuid(0, af, bf, cf, df); if (bf==0x68747541 && cf==0x444D4163 && df==0x69746E65) amd = 1; x86_cpuid(1, af, bf, cf, df); #ifdef X86_SSE if (!(df&(1<<25))) return 1; #endif #ifdef X86_SSE2 if (!(df&(1<<26))) return 1; #endif #ifdef X86_SSE3 if (!(cf&1)) return 1; #endif #endif #endif return 0; } matrix2d m2d_multiply_m2d(matrix2d m1, matrix2d m2) { matrix2d result = { m1.a*m2.a+m1.b*m2.c, m1.a*m2.b+m1.b*m2.d, m1.c*m2.a+m1.d*m2.c, m1.c*m2.b+m1.d*m2.d }; return result; } vector2d m2d_multiply_v2d(matrix2d m, vector2d v) { vector2d result = { m.a*v.x+m.b*v.y, m.c*v.x+m.d*v.y }; return result; } matrix2d m2d_multiply_float(matrix2d m, float s) { matrix2d result = { m.a*s, m.b*s, m.c*s, m.d*s, }; return result; } vector2d v2d_multiply_float(vector2d v, float s) { vector2d result = { v.x*s, v.y*s }; return result; } vector2d v2d_add(vector2d v1, vector2d v2) { vector2d result = { v1.x+v2.x, v1.y+v2.y }; return result; } vector2d v2d_sub(vector2d v1, vector2d v2) { vector2d result = { v1.x-v2.x, v1.y-v2.y }; return result; } matrix2d m2d_new(float me0, float me1, float me2, float me3) { matrix2d result = {me0,me1,me2,me3}; return result; } vector2d v2d_new(float x, float y) { vector2d result = {x, y}; return result; } void clipboard_push_text(char * text) { #ifdef MACOSX PasteboardRef newclipboard; if (PasteboardCreate(kPasteboardClipboard, &newclipboard)!=noErr) return; if (PasteboardClear(newclipboard)!=noErr) return; PasteboardSynchronize(newclipboard); CFDataRef data = CFDataCreate(kCFAllocatorDefault, text, strlen(text)); PasteboardPutItemFlavor(newclipboard, (PasteboardItemID)1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0); #elif defined WIN32 if (OpenClipboard(NULL)) { HGLOBAL cbuffer; char * glbuffer; EmptyClipboard(); cbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text)+1); glbuffer = (char*)GlobalLock(cbuffer); strcpy(glbuffer, text); GlobalUnlock(cbuffer); SetClipboardData(CF_TEXT, cbuffer); CloseClipboard(); } #elif (defined(LIN32) || defined(LIN64)) && defined(SDL_VIDEO_DRIVER_X11) if (clipboard_text!=NULL) { free(clipboard_text); clipboard_text = NULL; } clipboard_text = mystrdup(text); sdl_wminfo.info.x11.lock_func(); XSetSelectionOwner(sdl_wminfo.info.x11.display, XA_CLIPBOARD, sdl_wminfo.info.x11.window, CurrentTime); XFlush(sdl_wminfo.info.x11.display); sdl_wminfo.info.x11.unlock_func(); #else printf("Not implemented: put text on clipboard \"%s\"\n", text); #endif } char * clipboard_pull_text() { #ifdef MACOSX #elif defined WIN32 if (OpenClipboard(NULL)) { HANDLE cbuffer; char * glbuffer; cbuffer = GetClipboardData(CF_TEXT); glbuffer = (char*)GlobalLock(cbuffer); GlobalUnlock(cbuffer); CloseClipboard(); if(glbuffer!=NULL){ return mystrdup(glbuffer); } else { return ""; } } #elif (defined(LIN32) || defined(LIN64)) && defined(SDL_VIDEO_DRIVER_X11) #else printf("Not implemented: get text from clipboard\n"); return ""; #endif } int register_extension() { #if defined WIN32 int returnval; LONG rresult; HKEY newkey; char *currentfilename = exe_name(); char *iconname = NULL; char *opencommand = NULL; //char AppDataPath[MAX_PATH]; char *AppDataPath = NULL; iconname = (char*)malloc(strlen(currentfilename)+6); sprintf(iconname, "%s,-102", currentfilename); //Create Roaming application data folder /*if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, AppDataPath))) { returnval = 0; goto finalise; }*/ //AppDataPath = _getcwd(NULL, 0); //Move Game executable into application data folder //TODO: Implement opencommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath)); /*if((strlen(AppDataPath)+strlen(APPDATA_SUBDIR "\\Powder Toy"))\n" " \n" " \n" " Powder Toy save\n" " \n" " \n" " \n" "\n"; f = fopen("powdertoy-save.xml", "wb"); if (!f) return 0; fwrite(mimedata, 1, strlen(mimedata), f); fclose(f); char *desktopfiledata_tmp = "[Desktop Entry]\n" "Type=Application\n" "Name=Powder Toy\n" "Comment=Physics sandbox game\n" "MimeType=application/vnd.powdertoy.save;\n" "NoDisplay=true\n"; char *desktopfiledata = (char *)malloc(strlen(desktopfiledata_tmp)+strlen(currentfilename)+100); strcpy(desktopfiledata, desktopfiledata_tmp); strappend(desktopfiledata, "Exec="); strappend(desktopfiledata, currentfilename); strappend(desktopfiledata, " open %f\n"); f = fopen("powdertoy-tpt.desktop", "wb"); if (!f) return 0; fwrite(desktopfiledata, 1, strlen(desktopfiledata), f); fclose(f); system("xdg-mime install powdertoy-save.xml"); system("xdg-desktop-menu install powdertoy-tpt.desktop"); f = fopen("powdertoy-save-32.png", "wb"); if (!f) return 0; fwrite(icon_doc_32_png, 1, sizeof(icon_doc_32_png), f); fclose(f); f = fopen("powdertoy-save-16.png", "wb"); if (!f) return 0; fwrite(icon_doc_16_png, 1, sizeof(icon_doc_16_png), f); fclose(f); system("xdg-icon-resource install --noupdate --context mimetypes --size 32 powdertoy-save-32.png application-vnd.powdertoy.save"); system("xdg-icon-resource install --noupdate --context mimetypes --size 16 powdertoy-save-16.png application-vnd.powdertoy.save"); system("xdg-icon-resource forceupdate"); system("xdg-mime default powdertoy-tpt.desktop application/vnd.powdertoy.save"); unlink("powdertoy-save-32.png"); unlink("powdertoy-save-16.png"); unlink("powdertoy-save.xml"); unlink("powdertoy-tpt.desktop"); return 1; #elif defined MACOSX return 0; #endif } void HSV_to_RGB(int h,int s,int v,int *r,int *g,int *b)//convert 0-255(0-360 for H) HSV values to 0-255 RGB { float hh, ss, vv, c, x; int m; hh = h/60.0f;//normalize values ss = s/255.0f; vv = v/255.0f; c = vv * ss; x = c * ( 1 - fabs(fmod(hh,2.0) -1) ); if(hh<1){ *r = (int)(c*255.0); *g = (int)(x*255.0); *b = 0; } else if(hh<2){ *r = (int)(x*255.0); *g = (int)(c*255.0); *b = 0; } else if(hh<3){ *r = 0; *g = (int)(c*255.0); *b = (int)(x*255.0); } else if(hh<4){ *r = 0; *g = (int)(x*255.0); *b = (int)(c*255.0); } else if(hh<5){ *r = (int)(x*255.0); *g = 0; *b = (int)(c*255.0); } else if(hh<6){ *r = (int)(c*255.0); *g = 0; *b = (int)(x*255.0); } m = (int)((vv-c)*255.0); *r += m; *g += m; *b += m; } void OpenURI(std::string uri) { #ifdef WIN32 ShellExecute(0, "OPEN", uri.c_str(), NULL, NULL, 0); #elif MACOSX char *cmd = malloc(7+uri.length()); strcpy(cmd, "open "); strappend(cmd, uri.c_str()); system(cmd); #elif LIN32 char *cmd = (char*)malloc(11+uri.length()); strcpy(cmd, "xdg-open "); strappend(cmd, (char*)uri.c_str()); system(cmd); #elif LIN64 char *cmd = (char*)malloc(11+uri.length()); strcpy(cmd, "xdg-open "); strappend(cmd, (char*)uri.c_str()); system(cmd); #else printf("Cannot open browser\n"); #endif } void RGB_to_HSV(int r,int g,int b,int *h,int *s,int *v)//convert 0-255 RGB values to 0-255(0-360 for H) HSV { float rr, gg, bb, a,x,c,d; rr = r/255.0f;//normalize values gg = g/255.0f; bb = b/255.0f; a = fmin(rr,gg); a = fmin(a,bb); x = fmax(rr,gg); x = fmax(x,bb); if (a==x)//greyscale { *h = 0; *s = 0; *v = (int)(a*255.0); } else { c = (rr==a) ? gg-bb : ((bb==a) ? rr-gg : bb-rr); d = (rr==a) ? 3 : ((bb==a) ? 1 : 5); *h = (int)(60.0*(d - c/(x - a))); *s = (int)(255.0*((x - a)/x)); *v = (int)(255.0*x); } } void membwand(void * destv, void * srcv, size_t destsize, size_t srcsize) { size_t i; unsigned char * dest = (unsigned char*)destv; unsigned char * src = (unsigned char*)srcv; for(i = 0; i < destsize; i++){ dest[i] = dest[i] & src[i%srcsize]; } } vector2d v2d_zero = {0,0}; matrix2d m2d_identity = {1,0,0,1};