PStream StartSavegame(const String &filename, const String &user_text, const Bitmap *user_image) { Stream *out = Common::File::CreateFile(filename); if (!out) return PStream(); // Initialize and write Vista header RICH_GAME_MEDIA_HEADER vistaHeader; memset(&vistaHeader, 0, sizeof(RICH_GAME_MEDIA_HEADER)); memcpy(&vistaHeader.dwMagicNumber, RM_MAGICNUMBER, sizeof(int)); vistaHeader.dwHeaderVersion = 1; vistaHeader.dwHeaderSize = sizeof(RICH_GAME_MEDIA_HEADER); vistaHeader.dwThumbnailOffsetHigherDword = 0; vistaHeader.dwThumbnailOffsetLowerDword = 0; vistaHeader.dwThumbnailSize = 0; convert_guid_from_text_to_binary(game.guid, &vistaHeader.guidGameId[0]); uconvert(game.gamename, U_ASCII, (char*)&vistaHeader.szGameName[0], U_UNICODE, RM_MAXLENGTH); uconvert(user_text, U_ASCII, (char*)&vistaHeader.szSaveName[0], U_UNICODE, RM_MAXLENGTH); vistaHeader.szLevelName[0] = 0; vistaHeader.szComments[0] = 0; // MS Windows Vista rich media header vistaHeader.WriteToFile(out); // Savegame signature out->Write(SavegameSource::Signature.GetCStr(), SavegameSource::Signature.GetLength()); // CHECKME: what is this plugin hook suppose to mean, and if it is called here correctly pl_run_plugin_hooks(AGSE_PRESAVEGAME, 0); // Write descrition block WriteDescription(out, user_text, user_image); return PStream(out); }
/* sys_directx_message: * Displays a message. */ static void sys_directx_message(AL_CONST char *msg) { char *tmp1 = _AL_MALLOC_ATOMIC(ALLEGRO_MESSAGE_SIZE); char tmp2[WND_TITLE_SIZE*2]; HWND allegro_wnd = win_get_window(); while ((ugetc(msg) == '\r') || (ugetc(msg) == '\n')) msg += uwidth(msg); MessageBoxW(allegro_wnd, (unsigned short *)uconvert(msg, U_CURRENT, tmp1, U_UNICODE, ALLEGRO_MESSAGE_SIZE), (unsigned short *)uconvert(wnd_title, U_ASCII, tmp2, U_UNICODE, sizeof(tmp2)), MB_OK); _AL_FREE(tmp1); }
/*! \brief Return the name of 'significant' directories. * * \param dir Enumerated constant for directory type \sa DATA_DIR et al. * \param file File name below that directory. * \returns the combined path */ const char *kqres (int dir, const char *file) { HINSTANCE SHFolder; SHGETFOLDERPATH SHGetFolderPath; char *home; if (!init_path) { WCHAR tmp[PATH_MAX]; home = NULL; /* Get home directory; this bit originally written by SH */ SHFolder = LoadLibrary ("shfolder.dll"); if (SHFolder != NULL) { SHGetFolderPath = (void *) GetProcAddress (SHFolder, "SHGetFolderPathW"); if (SHGetFolderPath != NULL) { /* Get the "Application Data" folder for the current user */ if (SHGetFolderPath (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, tmp) = S_OK) { home = uconvert(tmp, U_UNICODE, NULL, U_UTF8, 0); } } FreeLibrary (SHFolder); } /* Do not get fooled by a corrupted $HOME */ if (home != NULL && strlen (home) < PATH_MAX) { sprintf (user_dir, "%s\\KQ", home); /* Always try to make the directory, just to be sure. */ mkdir (user_dir); } else { strcpy (user_dir, "."); } /* Now the data directory */ strcpy (game_dir, "."); init_path = 1; } switch (dir) { case DATA_DIR: return get_resource_file_path(game_dir, "data", file); break; case MUSIC_DIR: return get_resource_file_path(game_dir, "music", file); break; case MAP_DIR: return get_resource_file_path(game_dir, "maps", file); break; case SAVE_DIR: case SETTINGS_DIR: return get_resource_file_path(user_dir, "", file); break; case SCRIPT_DIR: return get_lua_file_path(file); break; default: return NULL; } }
extern "C" void be_sys_message(AL_CONST char *msg) { char filename[MAXPATHLEN]; char *title; char tmp[ALLEGRO_MESSAGE_SIZE]; char tmp2[ALLEGRO_MESSAGE_SIZE]; get_executable_name(filename, sizeof(filename)); title = get_filename(filename); BAlert *alert = new BAlert(title, uconvert(msg, U_CURRENT, tmp, U_UTF8, ALLEGRO_MESSAGE_SIZE), uconvert(get_config_text("Ok"), U_CURRENT, tmp2, U_UTF8, ALLEGRO_MESSAGE_SIZE)); alert->SetShortcut(0, B_ESCAPE); be_app->ShowCursor(); alert->Go(); be_app->HideCursor(); }
/* _al_file_time: * Returns the timestamp of the specified file. */ time_t _al_file_time(AL_CONST char *filename) { struct _stat s; char tmp[1024]; if (get_filename_encoding() != U_UNICODE) { if (_stat(uconvert(filename, U_CURRENT, tmp, U_ASCII, sizeof(tmp)), &s) != 0) { *allegro_errno = errno; return 0; } } else { if (_wstat((wchar_t*)uconvert(filename, U_CURRENT, tmp, U_UNICODE, sizeof(tmp)), &s) != 0) { *allegro_errno = errno; return 0; } } return s.st_mtime; }
/* _al_file_time: * Returns the timestamp of the specified file. */ time_t _al_file_time(AL_CONST char *filename) { struct stat s; char tmp[1024]; if (stat(uconvert(filename, U_CURRENT, tmp, U_UTF8, sizeof(tmp)), &s) != 0) { *allegro_errno = errno; return 0; } return s.st_mtime; }
/* _al_file_size_ex: * Measures the size of the specified file. */ uint64_t _al_file_size_ex(AL_CONST char *filename) { struct _stat s; char tmp[1024]; if (!_al_win_unicode_filenames) { if (_stat(uconvert(filename, U_CURRENT, tmp, U_ASCII, sizeof(tmp)), &s) != 0) { *allegro_errno = errno; return 0; } } else { if (_wstat((wchar_t*)uconvert(filename, U_CURRENT, tmp, U_UNICODE, sizeof(tmp)), &s) != 0) { *allegro_errno = errno; return 0; } } return s.st_size; }
int eof_system(const char * command) { #ifdef ALLEGRO_WINDOWS wchar_t wcommand[1024] = {0}; if(command == NULL) return -1; (void) uconvert(command, U_UTF8, (char *)(&wcommand[0]), U_UNICODE, 2048); return _wsystem(wcommand); #else if(command == NULL) return -1; return system(command); #endif }
int eof_mkdir(const char * dir) { #ifdef ALLEGRO_WINDOWS wchar_t wdir[1024] = {0}; if(dir == NULL) return -1; (void) uconvert(dir, U_UTF8, (char *)(&wdir[0]), U_UNICODE, 2048); return _wmkdir(wdir); #else if(dir == NULL) return -1; return mkdir(dir, 0777); #endif }
/* _xwin_sysdrv_message: * Displays a message. Uses xmessage if possible, and stdout if not. */ static void _xwin_sysdrv_message(AL_CONST char *msg) { char buf[ALLEGRO_MESSAGE_SIZE+1]; char *msg2; size_t len; pid_t pid; int status; /* convert message to ASCII */ msg2 = uconvert(msg, U_CURRENT, buf, U_ASCII, ALLEGRO_MESSAGE_SIZE); /* xmessage interprets some strings beginning with '-' as command-line * options. To avoid this we make sure all strings we pass to it have * newlines on the end. This is also useful for the fputs() case. */ len = strlen(msg2); ASSERT(len < ALLEGRO_MESSAGE_SIZE); if ((len == 0) || (msg2[len-1] != '\n')) strcat(msg2, "\n"); /* fork a child */ pid = fork(); switch (pid) { case -1: /* fork error */ fputs(msg2, stdout); break; case 0: /* child process */ execlp("xmessage", "xmessage", "-buttons", "OK:101", "-default", "OK", "-center", msg2, (char *)NULL); /* if execution reaches here, it means execlp failed */ _exit(EXIT_FAILURE); break; default: /* parent process */ waitpid(pid, &status, 0); if ((!WIFEXITED(status)) || (WEXITSTATUS(status) != 101)) /* ok button */ { fputs(msg2, stdout); } break; } }
/* sys_linux_message: * Display a message on our original console. */ static void sys_linux_message (const char *msg) { char *tmp; int ret; ASSERT(msg); tmp = al_malloc(ALLEGRO_MESSAGE_SIZE); msg = uconvert(msg, U_UTF8, tmp, U_ASCII, ALLEGRO_MESSAGE_SIZE); do { ret = write(STDERR_FILENO, msg, strlen(msg)); if ((ret < 0) && (errno != EINTR)) break; } while (ret < (int)strlen(msg)); __al_linux_got_text_message = true; al_free(tmp); }
/* scancode_to_name: * Converts the given scancode to a description of the key. */ static AL_CONST char *key_directx_scancode_to_name(const int scancode) { static char name[256]; TCHAR str[256]; WCHAR wstr[256]; ASSERT(scancode >= 0 && scancode < KEY_MAX); if (GetKeyNameText(reverse_mapping[scancode], str, sizeof str)) { /* let Windows translate from the current encoding into UTF16 */ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, sizeof wstr); /* translate from utf16 to Allegro's current encoding */ uconvert((char *)wstr, U_UNICODE, name, U_CURRENT, sizeof name); /* why oh why doesn't everybody just use UTF8/16 */ return name; } else return _keyboard_common_names[scancode]; }
/* directx_wnd_proc: * Window procedure for the Allegro window class. */ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT ps; if (message == msg_call_proc) return ((int (*)(void))wparam) (); if (message == msg_suicide) { DestroyWindow(wnd); return 0; } /* See get_reverse_mapping() in wkeybd.c to see what this is for. */ if (FALSE && (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)) { static char name[256]; TCHAR str[256]; WCHAR wstr[256]; GetKeyNameText(lparam, str, sizeof str); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, sizeof wstr); uconvert((char *)wstr, U_UNICODE, name, U_CURRENT, sizeof name); _TRACE(PREFIX_I" key[%s] = 0x%08lx;\n", name, lparam & 0x1ff0000); } switch (message) { case WM_CREATE: if (!user_wnd_proc) allegro_wnd = wnd; break; case WM_DESTROY: if (user_wnd_proc) { exit_window_modules(NULL); _win_reset_switch_mode(); } else { PostQuitMessage(0); } allegro_wnd = NULL; break; case WM_SETCURSOR: if (!user_wnd_proc || _mouse_installed) { mouse_set_syscursor(); return 1; /* not TRUE */ } break; case WM_ACTIVATE: if (LOWORD(wparam) == WA_INACTIVE) { _win_switch_out(); } else { /* Ignore the WM_ACTIVATE event if the window is minimized. */ if (HIWORD(wparam)) break; if (gfx_driver && !gfx_driver->windowed) { /* 1.2s delay to let Windows complete the switch in fullscreen mode */ SetTimer(allegro_wnd, SWITCH_TIMER, 1200, NULL); } else { /* no delay in windowed mode */ _win_switch_in(); } } break; case WM_TIMER: if (wparam == SWITCH_TIMER) { KillTimer(allegro_wnd, SWITCH_TIMER); _win_switch_in(); return 0; } break; case WM_ENTERSIZEMOVE: if (win_gfx_driver && win_gfx_driver->enter_sysmode) win_gfx_driver->enter_sysmode(); break; case WM_EXITSIZEMOVE: if (win_gfx_driver && win_gfx_driver->exit_sysmode) win_gfx_driver->exit_sysmode(); break; case WM_MOVE: if (GetActiveWindow() == allegro_wnd) { if (!IsIconic(allegro_wnd)) { wnd_x = (short) LOWORD(lparam); wnd_y = (short) HIWORD(lparam); if (win_gfx_driver && win_gfx_driver->move) win_gfx_driver->move(wnd_x, wnd_y, wnd_width, wnd_height); } else if (win_gfx_driver && win_gfx_driver->iconify) { win_gfx_driver->iconify(); } } break; case WM_SIZE: wnd_width = LOWORD(lparam); wnd_height = HIWORD(lparam); break; case WM_PAINT: if (!user_wnd_proc || win_gfx_driver) { BeginPaint(wnd, &ps); if (win_gfx_driver && win_gfx_driver->paint) win_gfx_driver->paint(&ps.rcPaint); EndPaint(wnd, &ps); return 0; } break; case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: /* Disable the default message-based key handler * in order to prevent conflicts on NT kernels. */ if (!user_wnd_proc || _keyboard_installed) return 0; break; case WM_SYSCOMMAND: if (wparam == SC_MONITORPOWER || wparam == SC_SCREENSAVE) { if (_screensaver_policy == ALWAYS_DISABLED || (_screensaver_policy == FULLSCREEN_DISABLED && gfx_driver && !gfx_driver->windowed)) return 0; } break; case WM_INITMENUPOPUP: wnd_sysmenu = TRUE; mouse_set_sysmenu(TRUE); if (win_gfx_driver && win_gfx_driver->enter_sysmode) win_gfx_driver->enter_sysmode(); break; case WM_MENUSELECT: if ((HIWORD(wparam) == 0xFFFF) && (!lparam)) { wnd_sysmenu = FALSE; mouse_set_sysmenu(FALSE); if (win_gfx_driver && win_gfx_driver->exit_sysmode) win_gfx_driver->exit_sysmode(); } break; case WM_MENUCHAR : return (MNC_CLOSE<<16)|(wparam&0xffff); case WM_CLOSE: if (!user_wnd_proc) { if (user_close_proc) (*user_close_proc)(); return 0; } break; } /* pass message to default window proc */ if (user_wnd_proc) return CallWindowProc(user_wnd_proc, wnd, message, wparam, lparam); else return DefWindowProc(wnd, message, wparam, lparam); }
/* al_findfirst: * Initiates a directory search. */ int al_findfirst(AL_CONST char *pattern, struct al_ffblk *info, int attrib) { struct FF_DATA *ff_data; struct stat s; int actual_attrib; char tmp[1024]; char *p; /* allocate ff_data structure */ ff_data = _AL_MALLOC(sizeof(struct FF_DATA)); if (!ff_data) { *allegro_errno = ENOMEM; return -1; } memset(ff_data, 0, sizeof *ff_data); info->ff_data = (void *) ff_data; /* if the pattern contains no wildcard, we use stat() */ if (!ustrpbrk(pattern, uconvert("?*", U_ASCII, tmp, U_CURRENT, sizeof(tmp)))) { /* start the search */ errno = *allegro_errno = 0; if (stat(uconvert(pattern, U_CURRENT, tmp, U_UTF8, sizeof(tmp)), &s) == 0) { /* get file attributes */ actual_attrib = ff_get_attrib(ff_get_filename(uconvert(pattern, U_CURRENT, tmp, U_UTF8, sizeof(tmp))), &s); /* does it match ? */ if ((actual_attrib & ~attrib) == 0) { info->attrib = actual_attrib; info->time = s.st_mtime; info->size = s.st_size; /* overflows at 2GB */ ff_data->size = s.st_size; ustrzcpy(info->name, sizeof(info->name), get_filename(pattern)); return 0; } } _AL_FREE(ff_data); info->ff_data = NULL; *allegro_errno = (errno ? errno : ENOENT); return -1; } ff_data->attrib = attrib; do_uconvert(pattern, U_CURRENT, ff_data->dirname, U_UTF8, sizeof(ff_data->dirname)); p = ff_get_filename(ff_data->dirname); _al_sane_strncpy(ff_data->pattern, p, sizeof(ff_data->pattern)); if (p == ff_data->dirname) _al_sane_strncpy(ff_data->dirname, "./", FF_MAXPATHLEN); else *p = 0; /* nasty bodge, but gives better compatibility with DOS programs */ if (strcmp(ff_data->pattern, "*.*") == 0) _al_sane_strncpy(ff_data->pattern, "*", FF_MAXPATHLEN); /* start the search */ errno = *allegro_errno = 0; ff_data->dir = opendir(ff_data->dirname); if (!ff_data->dir) { *allegro_errno = (errno ? errno : ENOENT); _AL_FREE(ff_data); info->ff_data = NULL; return -1; } if (al_findnext(info) != 0) { al_findclose(info); return -1; } return 0; }
/* al_findfirst: * Initiates a directory search. */ int al_findfirst(AL_CONST char *pattern, struct al_ffblk *info, int attrib) { struct FF_DATA *ff_data; char tmp[1024]; /* allocate ff_data structure */ ff_data = _AL_MALLOC(sizeof(struct FF_DATA)); if (!ff_data) { *allegro_errno = ENOMEM; return -1; } /* attach it to the info structure */ info->ff_data = (void *) ff_data; /* Windows defines specific flags for NTFS permissions: * FA_TEMPORARY 0x0100 * FA_SPARSE_FILE 0x0200 * FA_REPARSE_POINT 0x0400 * FA_COMPRESSED 0x0800 * FA_OFFLINE 0x1000 * FA_NOT_CONTENT_INDEXED 0x2000 * FA_ENCRYPTED 0x4000 * so we must set them in the mask by default; moreover, * in order to avoid problems with flags added in the * future, we simply set all bits past the first byte. */ ff_data->attrib = attrib | 0xFFFFFF00; /* start the search */ errno = *allegro_errno = 0; if (get_filename_encoding() != U_UNICODE) { ff_data->handle = _findfirst(uconvert(pattern, U_CURRENT, tmp, U_ASCII, sizeof(tmp)), &ff_data->data.a); if (ff_data->handle < 0) { *allegro_errno = errno; _AL_FREE(ff_data); info->ff_data = NULL; return -1; } if (ff_data->data.a.attrib & ~ff_data->attrib) { if (al_findnext(info) != 0) { al_findclose(info); return -1; } else return 0; } } else { ff_data->handle = _wfindfirst((wchar_t*)uconvert(pattern, U_CURRENT, tmp, U_UNICODE, sizeof(tmp)), &ff_data->data.w); if (ff_data->handle < 0) { *allegro_errno = errno; _AL_FREE(ff_data); info->ff_data = NULL; return -1; } if (ff_data->data.w.attrib & ~ff_data->attrib) { if (al_findnext(info) != 0) { al_findclose(info); return -1; } else return 0; } } fill_ffblk(info); return 0; }
/* _xwin_keyboard_handler: * Keyboard "interrupt" handler. */ void _xwin_keyboard_handler(XKeyEvent *event, int dga2_hack) { int keycode; if (!xkeyboard_installed) return; if (_xwin_keyboard_callback) (*_xwin_keyboard_callback)(event->type == KeyPress ? 1 : 0, event->keycode); keycode = _xwin.keycode_to_scancode[event->keycode]; if (keycode == -1) keycode = find_unknown_key_assignment(event->keycode); if (dga2_hack) dga2_update_shifts(event); else update_shifts(event); /* Special case the pause key. */ if (keycode == KEY_PAUSE) { /* Allegro ignore's releasing of the pause key. */ if (event->type == KeyRelease) return; if (pause_key) { event->type = KeyRelease; pause_key = 0; } else { pause_key = 1; } } if (event->type == KeyPress) { /* Key pressed. */ int len; char buffer[16]; char buffer2[16]; int unicode = 0, r = 0; #if defined (ALLEGRO_XWINDOWS_WITH_XIM) && defined(X_HAVE_UTF8_STRING) if (xic) { len = Xutf8LookupString(xic, event, buffer, sizeof buffer, NULL, NULL); } else #endif { /* XLookupString is supposed to only use ASCII. */ len = XLookupString(event, buffer, sizeof buffer, NULL, NULL); } buffer[len] = '\0'; uconvert(buffer, U_UTF8, buffer2, U_UNICODE, sizeof buffer2); unicode = *(unsigned short *)buffer2; #ifdef ALLEGRO_XWINDOWS_WITH_XIM r = XFilterEvent((XEvent *)event, _xwin.window); #endif if (keycode || unicode) { /* If we have a keycode, we want it to go to Allegro immediately, so the * key[] array is updated, and the user callbacks are called. OTOH, a key * should not be added to the keyboard buffer (parameter -1) if it was * filtered out as a compose key, or if it is a modifier key. */ if (r || keycode >= KEY_MODIFIERS) unicode = -1; else { /* Historically, Allegro expects to get only the scancode when Alt is * held down. */ if (_key_shifts & KB_ALT_FLAG) unicode = 0; } _handle_key_press(unicode, keycode); /* Detect Ctrl-Alt-End. */ if (keycode == KEY_END && (_key_shifts & KB_CTRL_FLAG) && (_key_shifts & KB_ALT_FLAG) && (three_finger_flag)) { #ifndef ALLEGRO_HAVE_LIBPTHREAD if (_unix_bg_man == &_bg_man_sigalrm) { _sigalrm_request_abort(); } else #endif { TRACE(PREFIX_W "Three finger combo detected. SIGTERMing " "pid %d\n", main_pid); kill(main_pid, SIGTERM); } } } } else { /* Key release. */ _handle_key_release(keycode); } }