diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-08 17:39:03 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-08 17:39:03 (GMT) |
| commit | b0ea52690ba56a0d0602ad8674b7e5ab2ba3e778 (patch) | |
| tree | 7d72e0509f4d2643d3be837a337d088ca5949c73 /src/Misc.cpp | |
| download | powder-b0ea52690ba56a0d0602ad8674b7e5ab2ba3e778.zip powder-b0ea52690ba56a0d0602ad8674b7e5ab2ba3e778.tar.gz | |
Initial
Diffstat (limited to 'src/Misc.cpp')
| -rw-r--r-- | src/Misc.cpp | 664 |
1 files changed, 664 insertions, 0 deletions
diff --git a/src/Misc.cpp b/src/Misc.cpp new file mode 100644 index 0000000..44770d1 --- /dev/null +++ b/src/Misc.cpp @@ -0,0 +1,664 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <regex.h> +#include <sys/types.h> +#include <math.h> +#include "misc.h" +#include "Config.h" +//#include "interface.h" +//#include "graphics.h" +//#include "powder.h" +//#include <icondoc.h> +//#include <update.h> +#if defined WIN32 +#include <shlobj.h> +#include <shlwapi.h> +#include <windows.h> +#else +#include <unistd.h> +#endif +#ifdef MACOSX +#include <ApplicationServices/ApplicationServices.h> +#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=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; +} + +unsigned clamp_flt(float f, float min, float max) //TODO: Also inline/macro +{ + if (f<min) + return 0; + if (f>max) + return 255; + return (int)(255.0f*(f-min)/(max-min)); +} + +float restrict_flt(float f, float min, float max) //TODO Inline or macro or something +{ + if (f<min) + return min; + if (f>max) + 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; +} + +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"))<MAX_PATH) + { + strappend(AppDataPath, APPDATA_SUBDIR); + _mkdir(AppDataPath); + strappend(AppDataPath, "\\Powder Toy"); + _mkdir(AppDataPath); + } else { + returnval = 0; + goto finalise; + }*/ + sprintf(opencommand, "\"%s\" open \"%%1\" ddir \"%s\"", currentfilename, AppDataPath); + + //Create extension entry + rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.cps", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL); + if (rresult != ERROR_SUCCESS) { + returnval = 0; + goto finalise; + } + rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1); + if (rresult != ERROR_SUCCESS) { + RegCloseKey(newkey); + returnval = 0; + goto finalise; + } + RegCloseKey(newkey); + + rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.stm", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL); + if (rresult != ERROR_SUCCESS) { + returnval = 0; + goto finalise; + } + rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1); + if (rresult != ERROR_SUCCESS) { + RegCloseKey(newkey); + returnval = 0; + goto finalise; + } + RegCloseKey(newkey); + + //Create program entry + rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL); + if (rresult != ERROR_SUCCESS) { + returnval = 0; + goto finalise; + } + rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"Powder Toy Save", strlen("Powder Toy Save")+1); + if (rresult != ERROR_SUCCESS) { + RegCloseKey(newkey); + returnval = 0; + goto finalise; + } + RegCloseKey(newkey); + + //Set DefaultIcon + rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL); + if (rresult != ERROR_SUCCESS) { + returnval = 0; + goto finalise; + } + rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)iconname, strlen(iconname)+1); + if (rresult != ERROR_SUCCESS) { + RegCloseKey(newkey); + returnval = 0; + goto finalise; + } + RegCloseKey(newkey); + + //Set Launch command + rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\shell\\open\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL); + if (rresult != ERROR_SUCCESS) { + returnval = 0; + goto finalise; + } + rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)opencommand, strlen(opencommand)+1); + if (rresult != ERROR_SUCCESS) { + RegCloseKey(newkey); + returnval = 0; + goto finalise; + } + RegCloseKey(newkey); + + returnval = 1; + finalise: + + if(iconname) free(iconname); + if(opencommand) free(opencommand); + if(currentfilename) free(currentfilename); + + return returnval; +#elif defined(LIN32) || defined(LIN64) + char *currentfilename = exe_name(); + FILE *f; + char *mimedata = +"<?xml version=\"1.0\"?>\n" +" <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n" +" <mime-type type=\"application/vnd.powdertoy.save\">\n" +" <comment>Powder Toy save</comment>\n" +" <glob pattern=\"*.cps\"/>\n" +" <glob pattern=\"*.stm\"/>\n" +" </mime-type>\n" +"</mime-info>\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 = 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 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}; |
