Clean up Client::DoInstallation

Also Factor out app constants that mods might change into Meson options and clean up format::URLEncode in the process, convert app and document icon data in arrays to actual images, actualize AppStream data for possible future packaging, add alternative command line format for opening filesystem saves and ptsave URLs, fix a memory leak in Platform::GetCwd, and add format::URLDecode.
This commit is contained in:
Tamás Bálint Misius 2022-09-08 06:52:23 +02:00
parent 04e899e824
commit a674498a96
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
24 changed files with 360 additions and 663 deletions

View File

@ -2,7 +2,7 @@
#include "Config.h"
const char *const introTextData =
"\blThe Powder Toy - Version " MTOS(SAVE_VERSION) "." MTOS(MINOR_VERSION) " - https://powdertoy.co.uk, irc.libera.chat #powder\n"
"\bl" APPNAME " - Version " MTOS(SAVE_VERSION) "." MTOS(MINOR_VERSION) " - https://powdertoy.co.uk, irc.libera.chat #powder\n"
"\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\xEE\x81\xA9\n"
"\n"
"\bgControl+C/V/X are Copy, Paste and cut respectively.\n"

View File

@ -1,310 +0,0 @@
/**
* Powder Toy - Main source
*
* Copyright (c) 2008 - 2010 Stanislaw Skowronek.
* Copyright (c) 2010 Simon Robertshaw
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
const unsigned char icon_doc_32_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a,
0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93,
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04,
0x06, 0x11, 0x21, 0x0c, 0xfc, 0x0b, 0x2f, 0xdf, 0x00, 0x00, 0x04, 0x65, 0x49, 0x44, 0x41, 0x54,
0x58, 0xc3, 0xb5, 0x96, 0x7f, 0x4c, 0xd4, 0x65, 0x1c, 0xc7, 0x5f, 0xcf, 0x73, 0xdf, 0xe3, 0x7e,
0x90, 0x8b, 0x98, 0xb8, 0x36, 0x12, 0xb8, 0x38, 0x69, 0x03, 0x4c, 0x64, 0xec, 0x6a, 0xa2, 0xd3,
0xb5, 0x74, 0x78, 0x4c, 0x42, 0x33, 0x51, 0xda, 0x5c, 0xe3, 0x97, 0x72, 0x79, 0xcc, 0x5c, 0xfd,
0x53, 0xcb, 0x50, 0x69, 0x93, 0xda, 0x9a, 0x3a, 0x0d, 0x0d, 0x99, 0xf3, 0x9f, 0x3b, 0x98, 0x89,
0x72, 0x14, 0x64, 0xb2, 0x62, 0x2b, 0x56, 0xad, 0x56, 0x20, 0xbf, 0x06, 0x3a, 0xe1, 0x1c, 0x8b,
0xed, 0x86, 0x89, 0x77, 0x96, 0x7f, 0x30, 0xf6, 0xed, 0x0f, 0xb9, 0x1b, 0xe6, 0x1d, 0x7c, 0x39,
0xe8, 0xb3, 0x3d, 0x7b, 0xbe, 0xcf, 0xb3, 0xef, 0xf3, 0x7c, 0x5f, 0xcf, 0xfb, 0xf3, 0xe3, 0xf9,
0x0a, 0x9e, 0xb4, 0xd5, 0x40, 0x0a, 0x0b, 0x37, 0x3f, 0x30, 0x0a, 0x78, 0x17, 0xb2, 0x48, 0x09,
0x33, 0x97, 0x52, 0x52, 0x52, 0xe2, 0x11, 0x42, 0xa0, 0xaa, 0x2a, 0x42, 0x08, 0x80, 0xd0, 0xb3,
0xaa, 0xaa, 0xa1, 0x17, 0x55, 0x55, 0x45, 0x55, 0x55, 0xcc, 0x66, 0x33, 0x05, 0x05, 0x05, 0x3e,
0xa7, 0xd3, 0x59, 0x73, 0xf3, 0xe6, 0xcd, 0xd6, 0x19, 0x90, 0xa8, 0x01, 0xa4, 0x10, 0x82, 0xce,
0xce, 0x4e, 0x4d, 0x1b, 0x5c, 0xe8, 0xed, 0x61, 0x6f, 0x7a, 0x26, 0x89, 0x89, 0x89, 0x2b, 0xda,
0xdb, 0xdb, 0x3f, 0xcd, 0xcb, 0xcb, 0xd3, 0xdf, 0xba, 0x75, 0xab, 0x59, 0x2b, 0x84, 0x0c, 0x33,
0xa7, 0x9f, 0x7d, 0xca, 0xf9, 0xec, 0xfc, 0xa9, 0xd3, 0x08, 0x21, 0x68, 0x68, 0x68, 0xc0, 0xe7,
0xf3, 0x19, 0x3a, 0x3a, 0x3a, 0x6a, 0xad, 0x56, 0xeb, 0x0e, 0xad, 0x6e, 0x94, 0x91, 0x14, 0xd0,
0xd2, 0x00, 0xba, 0xea, 0xeb, 0x11, 0x42, 0x30, 0x35, 0x35, 0x45, 0x57, 0x57, 0x17, 0x89, 0x89,
0x89, 0x4a, 0x5b, 0x5b, 0x5b, 0xad, 0xc5, 0x62, 0x79, 0x5d, 0x0b, 0x84, 0x24, 0x4a, 0xeb, 0x77,
0x55, 0x86, 0x20, 0x84, 0x10, 0x48, 0x29, 0x19, 0x1e, 0x1e, 0x46, 0x4a, 0x49, 0x52, 0x52, 0x92,
0xd2, 0xda, 0xda, 0x7a, 0x5c, 0x0b, 0x44, 0xd4, 0x00, 0x19, 0xc5, 0x75, 0xa1, 0x8f, 0x03, 0x48,
0x29, 0x19, 0x1f, 0x1f, 0x0f, 0xc1, 0x58, 0x2c, 0x16, 0xa5, 0xb9, 0xb9, 0x79, 0x5e, 0x25, 0xa2,
0x06, 0x98, 0x6d, 0x41, 0x97, 0x04, 0x01, 0x14, 0x45, 0x41, 0x51, 0x14, 0x52, 0x53, 0x53, 0x75,
0x4d, 0x4d, 0x4d, 0xb5, 0xc9, 0xc9, 0xc9, 0x11, 0x21, 0x16, 0x05, 0x30, 0xe0, 0x7e, 0xfb, 0x31,
0x08, 0x9f, 0xcf, 0x47, 0x42, 0x42, 0x02, 0xf1, 0xf1, 0xf1, 0x58, 0xad, 0x56, 0xb2, 0xb3, 0xb3,
0x71, 0x3a, 0x9d, 0x3a, 0x87, 0xc3, 0x71, 0x24, 0x21, 0x21, 0xe1, 0x9d, 0x70, 0x10, 0x32, 0xd2,
0x89, 0xe6, 0x8d, 0x01, 0xb7, 0x83, 0xf4, 0x3d, 0x67, 0x1e, 0x5b, 0xa3, 0xd7, 0xeb, 0x31, 0x9b,
0xcd, 0xc4, 0xc6, 0xc6, 0x32, 0x3d, 0x3d, 0x4d, 0x20, 0x10, 0x60, 0x64, 0x64, 0x84, 0x93, 0x27,
0x4f, 0xc6, 0x66, 0x66, 0x66, 0x96, 0x6a, 0x06, 0x98, 0x2d, 0x6b, 0xb8, 0x76, 0x65, 0x70, 0x90,
0xcc, 0xe2, 0xba, 0xd0, 0x78, 0xc0, 0xed, 0x08, 0xf9, 0x3e, 0x26, 0x26, 0x06, 0xa3, 0xd1, 0x88,
0xc1, 0x60, 0xc0, 0x64, 0x32, 0x61, 0x30, 0x18, 0x1e, 0x15, 0x1c, 0x45, 0x89, 0x05, 0xe2, 0x16,
0xed, 0x82, 0x6a, 0xcf, 0x55, 0x76, 0xa4, 0xa7, 0x87, 0xc6, 0x6f, 0x1c, 0x3b, 0xfa, 0x44, 0x40,
0x06, 0x61, 0xa4, 0x94, 0xe8, 0x74, 0x3a, 0xf4, 0x7a, 0x3d, 0x26, 0x93, 0x09, 0x40, 0xa7, 0xa5,
0x12, 0x22, 0x65, 0x64, 0xae, 0xea, 0x82, 0xc2, 0xc7, 0xc6, 0x97, 0x3e, 0x3c, 0xfc, 0x84, 0x72,
0xb3, 0x4b, 0xb8, 0x94, 0x12, 0x55, 0x55, 0x31, 0x1a, 0x8d, 0x61, 0x0f, 0xac, 0xf0, 0x3f, 0xd8,
0x7f, 0x21, 0x66, 0x5c, 0x00, 0x20, 0x16, 0x1d, 0x03, 0x59, 0x7b, 0x76, 0xa3, 0xb5, 0x52, 0x06,
0x9b, 0x94, 0x32, 0x08, 0xc0, 0xa2, 0xb3, 0xa0, 0xa7, 0xb1, 0x29, 0xf4, 0x5c, 0x7a, 0xea, 0x04,
0xfd, 0x2e, 0x07, 0x73, 0xed, 0x11, 0xec, 0x75, 0x3a, 0x9d, 0xe6, 0xdb, 0x10, 0xad, 0x97, 0x51,
0x43, 0xd5, 0x41, 0x1a, 0xe6, 0x71, 0x45, 0xd0, 0x22, 0x01, 0x44, 0x5d, 0x07, 0xa2, 0xa9, 0x94,
0x0b, 0xaa, 0x84, 0x5a, 0xfd, 0xbb, 0xab, 0xe6, 0x98, 0xa6, 0x5b, 0x33, 0x52, 0x66, 0x45, 0xad,
0x40, 0xb5, 0xe7, 0x2a, 0xa5, 0xa7, 0x4e, 0x60, 0x2f, 0x2c, 0x5c, 0x7a, 0x05, 0xe6, 0x02, 0x08,
0x06, 0xdd, 0xd8, 0xa8, 0x97, 0x86, 0xaa, 0x83, 0xd8, 0x7a, 0xcf, 0x92, 0xb5, 0xbb, 0x48, 0x13,
0x84, 0x66, 0x80, 0xb9, 0x82, 0x70, 0x5f, 0xe7, 0x14, 0x17, 0x7a, 0x7b, 0xe8, 0xfc, 0xe6, 0x1a,
0xab, 0xf2, 0xed, 0x68, 0x0d, 0x97, 0x48, 0x7b, 0x2a, 0x0b, 0x91, 0xcc, 0xba, 0x75, 0x2b, 0x5d,
0xf5, 0xe7, 0xe9, 0xaa, 0x3f, 0xcf, 0x85, 0x1b, 0x3d, 0x20, 0xa0, 0xb8, 0xe6, 0x63, 0xfe, 0x0e,
0x04, 0xd8, 0x75, 0xec, 0x28, 0x97, 0x0e, 0x7f, 0xb4, 0x34, 0x0a, 0x44, 0x32, 0xcf, 0x5e, 0x0b,
0xd5, 0x9e, 0x16, 0x06, 0xdc, 0x0e, 0x6c, 0x7d, 0xe7, 0x98, 0xbc, 0x37, 0x49, 0x4e, 0x6e, 0x2e,
0x4f, 0x2d, 0x5b, 0x86, 0x7d, 0xfb, 0x76, 0xaa, 0x3d, 0x57, 0xb1, 0xda, 0xed, 0x54, 0x7b, 0x5a,
0x34, 0xef, 0xa9, 0x09, 0x20, 0xe8, 0xe3, 0x8a, 0xef, 0xa7, 0x00, 0x95, 0xa1, 0x35, 0x07, 0xb8,
0xfe, 0x5c, 0x11, 0x5b, 0xc6, 0x9a, 0x58, 0x99, 0x92, 0xc2, 0x2b, 0xf9, 0xf9, 0xd8, 0x7a, 0xcf,
0xd2, 0xe2, 0x72, 0x03, 0x2a, 0x63, 0xa3, 0xa3, 0xac, 0xaf, 0x28, 0xd7, 0xa4, 0x80, 0xa2, 0x45,
0xae, 0xee, 0xc6, 0x26, 0xd6, 0xee, 0x2e, 0xa2, 0xcc, 0xe9, 0xc4, 0x7b, 0xfb, 0x36, 0x69, 0xdd,
0xa7, 0x39, 0xf7, 0xbb, 0x09, 0xef, 0x6a, 0x1b, 0x65, 0x0f, 0xae, 0x71, 0xc4, 0xfb, 0x2c, 0x5f,
0xae, 0xd9, 0x42, 0x61, 0x31, 0xec, 0x7c, 0xf0, 0x2d, 0x30, 0xc4, 0x91, 0x95, 0x2b, 0x97, 0x46,
0x81, 0x0d, 0xfb, 0x2a, 0x38, 0x74, 0xf1, 0x22, 0x55, 0x1f, 0xbc, 0x8f, 0xad, 0xef, 0x2c, 0x77,
0xbc, 0x5e, 0xf6, 0x77, 0x4e, 0xb1, 0xaf, 0xa4, 0x14, 0x21, 0x04, 0xc3, 0x59, 0x07, 0x58, 0xb7,
0x69, 0x23, 0x57, 0x5c, 0x6e, 0x9e, 0x8e, 0x7b, 0x06, 0x21, 0x1e, 0x05, 0xea, 0x56, 0x0d, 0xe9,
0x39, 0x67, 0x1a, 0x0a, 0x21, 0xd8, 0x50, 0x51, 0x4e, 0xc0, 0xef, 0xa7, 0x2c, 0xe6, 0x17, 0x4a,
0x5e, 0xcc, 0x22, 0xa3, 0xb8, 0x8e, 0xa1, 0xbe, 0x3e, 0x02, 0x81, 0x00, 0x3f, 0xfc, 0xf6, 0x2b,
0xdf, 0xb5, 0xb5, 0xe1, 0xbd, 0x3b, 0x41, 0x5f, 0x77, 0x0f, 0x39, 0xb9, 0xeb, 0x38, 0x73, 0xbc,
0x96, 0x8c, 0xe2, 0x3a, 0x6c, 0xeb, 0xd7, 0x73, 0x67, 0x64, 0x84, 0x55, 0xf9, 0x76, 0xec, 0xef,
0xbd, 0x3b, 0x67, 0x5a, 0x47, 0x54, 0x20, 0xb7, 0xbc, 0x8c, 0x07, 0x7e, 0x3f, 0x69, 0x19, 0x19,
0xbc, 0xe9, 0xf9, 0x8b, 0x7e, 0x57, 0x25, 0xcd, 0x03, 0x03, 0x6c, 0xde, 0xb6, 0x0d, 0x57, 0x41,
0x3c, 0x83, 0x37, 0x7a, 0x71, 0xbf, 0xb6, 0x9c, 0x2d, 0x63, 0x8d, 0xe4, 0xbf, 0xba, 0x99, 0x43,
0xcb, 0x87, 0x10, 0x42, 0xd0, 0xef, 0xaa, 0xc4, 0x7f, 0x7f, 0x92, 0xfb, 0x93, 0x93, 0x6c, 0xcc,
0xcb, 0x23, 0xe0, 0xf7, 0xcf, 0x59, 0x09, 0x23, 0xfe, 0x0f, 0x7c, 0x51, 0xf8, 0x02, 0x8d, 0xe3,
0x71, 0xdc, 0x9b, 0xb8, 0xcb, 0x8a, 0xac, 0x2c, 0xba, 0x9f, 0xdf, 0xc4, 0x1f, 0x1d, 0xd7, 0x11,
0x42, 0xf0, 0xd9, 0xc4, 0x0a, 0xf6, 0xbf, 0xb5, 0x93, 0x31, 0x9d, 0x0e, 0xef, 0xf8, 0x9f, 0x74,
0x7b, 0x5a, 0x90, 0xf9, 0x0e, 0x3e, 0xa9, 0x85, 0xcf, 0xbf, 0xfe, 0x0a, 0x23, 0x0f, 0xc9, 0xb1,
0xbd, 0xc4, 0xda, 0xbb, 0x3f, 0xa2, 0xa6, 0xa6, 0xd1, 0x5d, 0xf2, 0x13, 0x6d, 0x97, 0x2f, 0x87,
0x4f, 0xcf, 0x30, 0x73, 0x2f, 0x03, 0x99, 0x80, 0x69, 0x89, 0xff, 0x53, 0x1e, 0x02, 0x7d, 0xc0,
0xcf, 0xf3, 0x01, 0x98, 0x81, 0x65, 0x33, 0xfd, 0x52, 0xda, 0x3f, 0x40, 0x60, 0xa6, 0x0f, 0xd9,
0xbf, 0x2f, 0x89, 0x69, 0x46, 0x25, 0x68, 0x1c, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
0x44, 0xae, 0x42, 0x60, 0x82
};
const unsigned char icon_doc_16_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff,
0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93,
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04,
0x06, 0x11, 0x21, 0x22, 0x20, 0xdd, 0x22, 0x10, 0x00, 0x00, 0x01, 0x95, 0x49, 0x44, 0x41, 0x54,
0x38, 0xcb, 0x95, 0x93, 0x3d, 0x4b, 0x82, 0x51, 0x14, 0xc7, 0x7f, 0xc7, 0x24, 0x4d, 0x7c, 0x96,
0x96, 0x50, 0x48, 0x14, 0x8a, 0x86, 0x16, 0x23, 0x28, 0xea, 0x23, 0xd8, 0xd0, 0xcb, 0x20, 0x86,
0x6b, 0x11, 0xb4, 0xd8, 0x10, 0x6d, 0x81, 0xbd, 0x7c, 0x02, 0x5b, 0xa2, 0x10, 0x47, 0x6b, 0x2a,
0xa7, 0x1c, 0x0b, 0x24, 0xb3, 0xa9, 0xf7, 0xa1, 0x25, 0xb2, 0x20, 0xe4, 0x59, 0xad, 0xd0, 0xb2,
0xdb, 0x50, 0x8f, 0x3c, 0xbe, 0x3c, 0x50, 0x07, 0x2e, 0xdc, 0x73, 0xef, 0x39, 0xff, 0xf3, 0x3b,
0x87, 0x7b, 0x45, 0x29, 0x05, 0x80, 0x88, 0x0c, 0x02, 0x1a, 0x16, 0xa6, 0x94, 0x3a, 0x6b, 0x77,
0x6e, 0x37, 0xed, 0xb5, 0x68, 0x34, 0x9a, 0x37, 0x1c, 0x8f, 0xcf, 0xc7, 0x4b, 0xb1, 0x08, 0x40,
0xa9, 0x54, 0x42, 0x44, 0xc6, 0xda, 0x89, 0x98, 0x05, 0x04, 0xa0, 0x50, 0x28, 0x10, 0xcf, 0x1c,
0x12, 0x9f, 0x9c, 0xaa, 0x5f, 0xf4, 0x0e, 0x05, 0xd1, 0x75, 0x3d, 0x2f, 0x22, 0xe3, 0x4a, 0xa9,
0xbc, 0x59, 0xc0, 0x66, 0x76, 0x44, 0x04, 0xa0, 0x21, 0x19, 0xe0, 0xfe, 0x34, 0x8f, 0xcb, 0xe5,
0x42, 0xd7, 0xf5, 0x53, 0x11, 0x19, 0xb3, 0x12, 0x10, 0x43, 0xa4, 0x79, 0x01, 0x38, 0x1c, 0x0e,
0xb3, 0xc8, 0x78, 0xdb, 0x16, 0x8c, 0xe0, 0xe0, 0x6c, 0x84, 0x8b, 0xf4, 0x5e, 0x03, 0x99, 0xd7,
0xeb, 0x05, 0x20, 0x10, 0x08, 0xd4, 0x8b, 0x35, 0x13, 0xd8, 0x8c, 0x8a, 0x97, 0x7b, 0xfb, 0xf5,
0xea, 0xf3, 0x5b, 0x09, 0x1e, 0x0e, 0x96, 0xd1, 0x34, 0x0d, 0x4d, 0xd3, 0xf0, 0xfb, 0xfd, 0x0d,
0x79, 0x2d, 0x04, 0x06, 0x85, 0x61, 0xc9, 0xd8, 0x12, 0x49, 0xc0, 0x6e, 0xff, 0x09, 0x75, 0x3a,
0x9d, 0x96, 0x04, 0xd2, 0x9c, 0xdc, 0xce, 0x7e, 0x63, 0xe4, 0x5f, 0x43, 0x0c, 0x6f, 0xac, 0xd3,
0x44, 0xf7, 0x37, 0x82, 0x78, 0x26, 0xc3, 0x5c, 0x22, 0x41, 0x68, 0x7a, 0xfa, 0x4f, 0x04, 0xf5,
0x21, 0xde, 0xa5, 0x17, 0x11, 0x11, 0x9e, 0x8b, 0x8f, 0x24, 0x63, 0x31, 0x46, 0x6f, 0xb6, 0x19,
0x9a, 0x8d, 0x98, 0x29, 0x6c, 0x96, 0x2d, 0x00, 0x2c, 0x1c, 0x7f, 0x92, 0xba, 0xbe, 0xe2, 0x24,
0x9b, 0xa5, 0x7f, 0x22, 0x64, 0xbe, 0x6a, 0x89, 0x6d, 0x79, 0xca, 0x7d, 0xa1, 0x10, 0xb9, 0x9d,
0x5d, 0x72, 0x3b, 0xbb, 0xa4, 0xae, 0xaf, 0x00, 0x88, 0x6e, 0x6e, 0xf2, 0x5a, 0x2e, 0x13, 0x5e,
0x5f, 0xe3, 0xe9, 0x28, 0x6b, 0x29, 0x40, 0xad, 0x56, 0x63, 0xb8, 0xf3, 0x8b, 0x81, 0x99, 0x19,
0xdc, 0x5f, 0x6f, 0x64, 0x57, 0x57, 0x78, 0xb3, 0xbb, 0xe9, 0xa9, 0x54, 0xa8, 0x54, 0x3f, 0xa8,
0xde, 0xde, 0xd1, 0xed, 0xf1, 0x34, 0xa2, 0x98, 0xbe, 0xf3, 0x08, 0xe0, 0x01, 0xba, 0x00, 0x37,
0xe0, 0x00, 0x3a, 0x0c, 0x6d, 0xa0, 0x02, 0x94, 0x81, 0x77, 0xe0, 0x45, 0x29, 0x75, 0x0e, 0xf0,
0x0d, 0xff, 0x1c, 0x7a, 0x37, 0x5c, 0xfd, 0x46, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
0x44, 0xae, 0x42, 0x60, 0x82
};
const unsigned char icon_desktop_48_png[] = {
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x57, 0x02, 0xF9,
0x87, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00,
0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00,
0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7,
0x6F, 0xA8, 0x64, 0x00, 0x00, 0x0A, 0x20, 0x49, 0x44, 0x41, 0x54, 0x68, 0x43, 0xED, 0x99, 0x7B,
0x8C, 0x54, 0xE5, 0x19, 0x87, 0xF7, 0x32, 0xB7, 0x9D, 0x85, 0x55, 0xA0, 0x08, 0x08, 0x08, 0x42,
0x65, 0x97, 0x4B, 0x54, 0x84, 0x5D, 0x6A, 0xB9, 0x2C, 0x48, 0xD1, 0x22, 0x82, 0x84, 0x22, 0x85,
0xCA, 0xC5, 0xD4, 0x96, 0x58, 0xA3, 0x98, 0x52, 0xB0, 0x50, 0xA4, 0x88, 0x97, 0x16, 0x42, 0xAC,
0xD2, 0x48, 0x6B, 0x49, 0x1A, 0xA9, 0xED, 0xC2, 0x2E, 0x36, 0xB5, 0xB1, 0x7F, 0x58, 0x42, 0x45,
0x88, 0x88, 0xB4, 0xB5, 0x2D, 0x88, 0xA1, 0x05, 0xE4, 0xD2, 0x05, 0x16, 0x90, 0xCB, 0xEE, 0xCC,
0x99, 0x99, 0x33, 0x73, 0xE6, 0xF2, 0xF6, 0x79, 0xCF, 0x39, 0x33, 0x3B, 0x80, 0x95, 0x59, 0x62,
0x22, 0x24, 0x98, 0x3C, 0xF9, 0x0E, 0x24, 0xB2, 0xCF, 0xEF, 0x3D, 0xBF, 0xEF, 0x3B, 0x67, 0x76,
0x8A, 0x8A, 0xAE, 0xFD, 0x77, 0x6D, 0x02, 0xD7, 0x26, 0x70, 0x75, 0x4F, 0xE0, 0xE9, 0x67, 0x7F,
0xFA, 0xD8, 0xF2, 0xE7, 0x56, 0xC8, 0xD5, 0xC0, 0xE2, 0xA7, 0x96, 0xCD, 0x67, 0xDA, 0x3E, 0x28,
0xCE, 0x4D, 0x5D, 0xC5, 0xF7, 0xEC, 0x3B, 0xF2, 0x85, 0xF1, 0xC8, 0xE2, 0xD5, 0xA2, 0x64, 0x1D,
0x3E, 0xEB, 0xCF, 0xEA, 0x8A, 0x78, 0x17, 0x37, 0x84, 0x93, 0xE1, 0x8B, 0x0E, 0xD0, 0x96, 0xE1,
0xB9, 0x01, 0xFA, 0xA1, 0xDD, 0xEE, 0xA2, 0x3B, 0x30, 0x74, 0xC8, 0x10, 0x19, 0x0D, 0x73, 0x61,
0x55, 0x4D, 0xB5, 0xAC, 0x1B, 0x5B, 0x2D, 0x75, 0xC3, 0x6B, 0xE4, 0xB5, 0x11, 0xAC, 0x77, 0x55,
0xCB, 0x86, 0x19, 0xC3, 0xA4, 0xFE, 0x51, 0x98, 0x3F, 0x4C, 0x1A, 0x96, 0xDE, 0x29, 0x0D, 0x2B,
0x46, 0x4A, 0xC3, 0xCF, 0xC6, 0x48, 0xC3, 0x8B, 0x63, 0x59, 0xBF, 0x26, 0x0D, 0x2F, 0x29, 0xFC,
0x79, 0x75, 0x2D, 0xEB, 0x28, 0x18, 0x01, 0x5F, 0x91, 0x86, 0x17, 0xF8, 0x7F, 0x16, 0xD4, 0x48,
0xFD, 0xDC, 0x6A, 0xA9, 0x9F, 0x09, 0x53, 0xF8, 0xB7, 0xEE, 0x63, 0x1D, 0xCF, 0x7A, 0x0F, 0xEB,
0xDD, 0x35, 0xB2, 0x7E, 0x34, 0xF0, 0x73, 0x36, 0xC0, 0xFA, 0x51, 0x35, 0x52, 0x37, 0xB2, 0x46,
0x1E, 0x9A, 0x33, 0xE7, 0x3C, 0x34, 0xA8, 0x1B, 0x60, 0x00, 0xF2, 0x15, 0x17, 0x05, 0xE8, 0x5F,
0x5C, 0x24, 0x3F, 0x2C, 0x2A, 0x91, 0x4D, 0xC5, 0xA5, 0x72, 0xCC, 0xEF, 0x93, 0x64, 0x77, 0xBF,
0x64, 0x6A, 0xCB, 0x24, 0xF3, 0x44, 0x50, 0x32, 0x7F, 0x08, 0x4A, 0xFA, 0x74, 0x7B, 0xC9, 0x64,
0x3A, 0x4B, 0x3A, 0x5D, 0x09, 0x23, 0xE0, 0x5E, 0x49, 0xA5, 0xEE, 0x96, 0x74, 0x6A, 0x92, 0xA4,
0xD2, 0xB3, 0xB8, 0xFE, 0x96, 0x24, 0x53, 0x13, 0x25, 0x95, 0x1C, 0x02, 0x83, 0x25, 0x99, 0xEC,
0x23, 0x49, 0xAB, 0x1C, 0xFC, 0x62, 0x1D, 0x0C, 0x88, 0xF5, 0x06, 0xAC, 0x0D, 0x48, 0x62, 0xBE,
0x5F, 0xE2, 0x8F, 0xF8, 0x25, 0xF1, 0x70, 0x40, 0xE2, 0xB3, 0xB9, 0x1E, 0xEF, 0x17, 0xB3, 0x06,
0x6E, 0xF5, 0x89, 0x59, 0xCD, 0x3A, 0x8C, 0x75, 0xA8, 0x5F, 0x06, 0x0C, 0x18, 0x60, 0x53, 0x59,
0x59, 0xA5, 0xB5, 0xB1, 0x2B, 0xF6, 0x99, 0x01, 0x5E, 0xF6, 0x7A, 0xE4, 0xB0, 0xD7, 0x2B, 0xE9,
0x00, 0xE2, 0x45, 0x3E, 0xC9, 0x54, 0xC0, 0x0A, 0x02, 0xB4, 0x54, 0xD8, 0xE2, 0x99, 0x4C, 0x57,
0xA4, 0x3B, 0x41, 0x0F, 0x18, 0x80, 0xF8, 0x40, 0xD6, 0xEE, 0xC8, 0xF7, 0x40, 0xBE, 0x1F, 0xD2,
0x7D, 0xA1, 0x07, 0xE2, 0xED, 0x20, 0xE8, 0x88, 0x27, 0x7D, 0x62, 0x35, 0xFA, 0x24, 0xB1, 0x11,
0x7E, 0x0C, 0x8F, 0xF9, 0x24, 0xFE, 0x03, 0xE4, 0x7F, 0x04, 0x4B, 0x91, 0xE7, 0x3A, 0x3E, 0x1D,
0xE9, 0x51, 0x48, 0xDF, 0xEE, 0x93, 0xD8, 0x70, 0x18, 0x0D, 0xB5, 0x3E, 0x19, 0x34, 0x68, 0x90,
0x44, 0xA3, 0x51, 0x88, 0x15, 0x16, 0x20, 0xD9, 0x35, 0x20, 0xE2, 0xF3, 0x8B, 0xA8, 0x3C, 0x48,
0x80, 0xB5, 0x21, 0x80, 0x78, 0x6F, 0xB8, 0x13, 0xD9, 0x5B, 0x20, 0x00, 0x1E, 0xE4, 0x09, 0x9A,
0xF6, 0xD9, 0xA4, 0xB8, 0x4E, 0xA5, 0x3C, 0x4C, 0x1F, 0x92, 0x5E, 0x1B, 0x4B, 0xD7, 0x04, 0xF2,
0x7B, 0xE0, 0xE7, 0x88, 0xCF, 0x04, 0xC4, 0x6C, 0xA6, 0x22, 0x3D, 0x93, 0xE9, 0x7F, 0xAF, 0x4C,
0xE2, 0x0F, 0x22, 0x3F, 0x16, 0x7A, 0x13, 0xA0, 0x1B, 0xF4, 0x41, 0xBE, 0x07, 0x74, 0xF4, 0x49,
0xFF, 0xFE, 0xFD, 0xDD, 0x00, 0xD1, 0xC2, 0x02, 0x48, 0x89, 0x17, 0x79, 0xAF, 0x33, 0x7D, 0xE5,
0x66, 0xD8, 0xC5, 0x1D, 0xC8, 0x0C, 0x96, 0x4C, 0xFA, 0x1E, 0xB8, 0xC9, 0x95, 0x0E, 0x30, 0x75,
0x0D, 0x02, 0x29, 0xAE, 0x53, 0x65, 0xC8, 0x07, 0x10, 0x57, 0xFC, 0x88, 0x33, 0xF9, 0x33, 0x88,
0xEF, 0x66, 0x7D, 0x91, 0x75, 0x0A, 0x54, 0x7A, 0x25, 0xD1, 0x1D, 0x98, 0x72, 0x7C, 0x2C, 0xCC,
0x20, 0xC0, 0x82, 0x32, 0x31, 0x1F, 0x08, 0x50, 0x17, 0x84, 0xBF, 0xEC, 0x97, 0x18, 0x77, 0x3C,
0x56, 0x0E, 0x5E, 0x9F, 0x44, 0xF9, 0xF9, 0x55, 0x95, 0x95, 0x52, 0x55, 0x55, 0x25, 0xFD, 0xFA,
0xF5, 0x2B, 0x2C, 0x80, 0x3D, 0x75, 0xA5, 0x98, 0x0A, 0x95, 0xC1, 0xE3, 0x4C, 0x39, 0xF1, 0x25,
0x49, 0x67, 0xEE, 0x42, 0x76, 0x32, 0x6B, 0x5F, 0x56, 0xA6, 0x9D, 0xF6, 0x23, 0xAD, 0x21, 0xCA,
0xA8, 0x0C, 0xA4, 0xA8, 0x0B, 0xB5, 0x49, 0xA9, 0xBC, 0x85, 0xEC, 0x49, 0xF8, 0x2B, 0x93, 0x7E,
0x1D, 0x9E, 0x80, 0x6A, 0xE8, 0x84, 0x74, 0x77, 0x56, 0xBA, 0x9D, 0xA0, 0x1E, 0xF1, 0xB9, 0x4C,
0x7D, 0x15, 0xF2, 0xCF, 0x05, 0xC5, 0x9C, 0xC5, 0xF5, 0x38, 0xA6, 0xCF, 0xC0, 0xA2, 0x1D, 0x40,
0x03, 0x94, 0xF8, 0xA4, 0x63, 0xC7, 0x8E, 0x52, 0x51, 0x51, 0x21, 0xC1, 0x60, 0xB0, 0xC0, 0x00,
0x74, 0x5F, 0x7A, 0x51, 0x99, 0xAF, 0x22, 0xFF, 0x14, 0x34, 0xFA, 0x11, 0xD6, 0xEA, 0x2C, 0x82,
0x65, 0x30, 0x1E, 0xE9, 0x8E, 0xAC, 0x04, 0x48, 0x97, 0x23, 0x8E, 0x74, 0x4A, 0xD7, 0x0A, 0xBB,
0xF3, 0x16, 0x01, 0xAC, 0xB3, 0xC8, 0xFF, 0x07, 0xDE, 0x85, 0x7A, 0x58, 0x88, 0xF4, 0x18, 0xA8,
0x82, 0x1A, 0xC4, 0x11, 0x8D, 0x4F, 0x47, 0xF6, 0x65, 0xE4, 0x0F, 0x96, 0x8B, 0x79, 0x84, 0x00,
0xEF, 0x04, 0x24, 0xF6, 0x3B, 0x58, 0x02, 0x33, 0xB8, 0x13, 0x83, 0x09, 0x40, 0x95, 0x74, 0xE3,
0xE6, 0x73, 0xC9, 0x4D, 0x9C, 0x99, 0x8B, 0x7C, 0x03, 0x95, 0xD9, 0xCD, 0x9A, 0xA0, 0x1E, 0x19,
0x36, 0x6A, 0x7A, 0x0D, 0xEB, 0x47, 0xD4, 0x67, 0x0F, 0x75, 0x79, 0x0D, 0x66, 0x20, 0x5C, 0x09,
0x9D, 0x99, 0x78, 0x7B, 0x47, 0x3E, 0xD5, 0x81, 0x00, 0x65, 0x62, 0xC5, 0x38, 0x65, 0xF6, 0x10,
0xE2, 0x5F, 0x4C, 0xF9, 0x6F, 0x08, 0x6F, 0x65, 0x7D, 0x85, 0x75, 0x1E, 0xD2, 0x73, 0x74, 0xEA,
0xF0, 0x7D, 0xF8, 0x05, 0x1C, 0x20, 0x80, 0x59, 0x26, 0x31, 0xB3, 0x02, 0xAE, 0x93, 0x58, 0x2C,
0x28, 0xD1, 0x73, 0x04, 0xD8, 0x5F, 0x26, 0xD1, 0x3A, 0xBF, 0x44, 0x1F, 0x77, 0x02, 0x44, 0xA2,
0x11, 0x89, 0x44, 0x22, 0x05, 0xDE, 0x81, 0x26, 0xA6, 0x2E, 0x7A, 0xE2, 0xF4, 0x42, 0x78, 0x34,
0xE2, 0x6B, 0x09, 0xD0, 0x02, 0x69, 0x17, 0x13, 0xE1, 0xFD, 0xF0, 0x12, 0xD2, 0x13, 0x08, 0x50,
0x89, 0x78, 0x67, 0x5B, 0x5E, 0xFB, 0x6F, 0x9D, 0x41, 0x7E, 0xAB, 0xD6, 0x87, 0xF5, 0x10, 0xF2,
0xC7, 0x60, 0x1B, 0xAC, 0x47, 0xB8, 0x0E, 0x7E, 0x0F, 0xEF, 0x52, 0x97, 0x26, 0xFA, 0x8F, 0xBC,
0x69, 0xD2, 0x77, 0xF3, 0x46, 0xB8, 0x9D, 0x00, 0x37, 0x49, 0x34, 0xD6, 0x9E, 0x95, 0xE9, 0x47,
0x7D, 0x12, 0xD9, 0x17, 0x70, 0x02, 0x20, 0x5F, 0x78, 0x80, 0xCC, 0x75, 0xC8, 0x8F, 0x84, 0x65,
0xB0, 0x05, 0x69, 0x33, 0x4F, 0x3E, 0x45, 0x6D, 0xD2, 0xC8, 0xB3, 0xA6, 0x4C, 0x02, 0xBC, 0x8D,
0xF4, 0x5C, 0xB8, 0x0D, 0xAE, 0x77, 0x8E, 0xCB, 0x83, 0x80, 0xA4, 0xF5, 0x3E, 0xD2, 0x84, 0x49,
0x98, 0x88, 0x32, 0x94, 0xF8, 0x61, 0x5D, 0xE1, 0x2C, 0xD7, 0x26, 0x01, 0x6C, 0xBC, 0xF6, 0xF4,
0xCD, 0xD8, 0x18, 0xA4, 0x9F, 0x46, 0x7E, 0x25, 0xE2, 0xDF, 0x86, 0x4A, 0x27, 0x40, 0xD4, 0xDB,
0xB6, 0x0A, 0xBD, 0xBD, 0x63, 0x37, 0xD3, 0x7F, 0x00, 0xF1, 0x37, 0x98, 0x7C, 0x18, 0xD2, 0xDC,
0x85, 0xEC, 0xE4, 0x75, 0x55, 0xF1, 0x6C, 0x00, 0xBD, 0x4E, 0x21, 0xBE, 0x03, 0x9E, 0x44, 0x7E,
0x0C, 0x9B, 0xB7, 0xB3, 0x58, 0x1F, 0x78, 0xEC, 0x69, 0x27, 0xF6, 0xBA, 0xF2, 0xD4, 0x30, 0x1E,
0x07, 0x4E, 0x25, 0x93, 0xD5, 0x86, 0x50, 0x4E, 0x75, 0x7A, 0xC2, 0x37, 0x90, 0xFF, 0x2D, 0xC2,
0x27, 0xC0, 0x80, 0x46, 0xF8, 0x25, 0xF2, 0xB5, 0x4C, 0xFD, 0xFA, 0x8B, 0x02, 0xA8, 0xE3, 0xFF,
0x7D, 0x90, 0xD9, 0x01, 0x32, 0x3B, 0x01, 0xF1, 0x4C, 0xA6, 0x55, 0xDE, 0x96, 0x26, 0x80, 0x3D,
0x79, 0xA4, 0x75, 0x4D, 0x2A, 0x49, 0xE4, 0x95, 0xF7, 0xC4, 0xB2, 0x96, 0xB1, 0xD6, 0x8A, 0xF5,
0x61, 0xB9, 0x58, 0x7F, 0x21, 0x40, 0x73, 0x50, 0x12, 0x89, 0x72, 0xC4, 0x83, 0x04, 0xE0, 0xAC,
0x8F, 0xB3, 0xEA, 0xB4, 0xE3, 0xDD, 0x90, 0x1F, 0xCC, 0xD4, 0xBF, 0x89, 0xFC, 0x6A, 0xE4, 0x3F,
0x00, 0x43, 0x62, 0xF6, 0xC3, 0x2A, 0xCB, 0x39, 0x02, 0xD4, 0x13, 0xE0, 0xDE, 0xB6, 0x07, 0x48,
0x23, 0xAE, 0x64, 0x27, 0x6F, 0x57, 0xC6, 0xAE, 0xCD, 0x85, 0x93, 0xD7, 0xE9, 0x23, 0x6F, 0x59,
0x70, 0x9C, 0x00, 0x1B, 0x24, 0x61, 0xCD, 0x96, 0x44, 0xB8, 0xAB, 0x24, 0x5A, 0x54, 0xBE, 0x8B,
0x24, 0xE2, 0x37, 0x13, 0xA0, 0x2F, 0xF2, 0x95, 0x88, 0x23, 0x6D, 0x8E, 0x23, 0xC4, 0x3C, 0xE4,
0x5F, 0xE7, 0xFA, 0x30, 0xE2, 0x31, 0x6A, 0x13, 0x43, 0xDE, 0xC1, 0x09, 0x40, 0xDF, 0xED, 0x4D,
0x7B, 0x40, 0x8C, 0xC8, 0x52, 0x77, 0x0F, 0x18, 0x62, 0x18, 0x86, 0x7D, 0x5D, 0xC0, 0x1D, 0x20,
0x40, 0x5A, 0xC9, 0x56, 0xC7, 0xE9, 0x7D, 0x76, 0xFA, 0xA9, 0x14, 0xD2, 0x8A, 0x3B, 0x7D, 0x8B,
0x00, 0x96, 0x75, 0x12, 0xFE, 0x84, 0xF4, 0xA3, 0x30, 0x10, 0x7A, 0x23, 0x3E, 0x0A, 0xA6, 0x20,
0xAF, 0xCC, 0x46, 0x7C, 0x21, 0xD2, 0xAF, 0xC2, 0x11, 0x26, 0x1F, 0x23, 0x04, 0xD2, 0x2E, 0xAD,
0x93, 0x8F, 0x48, 0xD4, 0xDD, 0xB0, 0x91, 0xC8, 0xC7, 0x84, 0x78, 0xC1, 0x96, 0x56, 0xF9, 0x70,
0xC1, 0x01, 0x54, 0x96, 0x0A, 0xD9, 0x01, 0x74, 0xEA, 0xB9, 0x3B, 0xD0, 0x5A, 0x1F, 0x47, 0x5E,
0x27, 0x9F, 0xA4, 0xFB, 0x1A, 0xA0, 0x59, 0xAC, 0xC4, 0x76, 0xC4, 0x57, 0xC2, 0x4C, 0x78, 0x18,
0xF9, 0x67, 0x11, 0x5F, 0x03, 0x6B, 0xA1, 0x8E, 0x3B, 0xB0, 0x0D, 0xF9, 0x13, 0x60, 0xB6, 0xCA,
0xBB, 0xEF, 0x38, 0x1A, 0x40, 0xA7, 0x9E, 0x5D, 0x23, 0x11, 0x03, 0xF9, 0x7F, 0x22, 0xFE, 0x4A,
0xDB, 0x2B, 0xD4, 0xBA, 0x69, 0xB3, 0x93, 0x77, 0xA6, 0xAF, 0xBD, 0x77, 0xBA, 0x7F, 0xE1, 0xF4,
0x2D, 0xAA, 0x03, 0x89, 0x66, 0xF8, 0x07, 0x6C, 0x44, 0x78, 0x33, 0x1C, 0x82, 0xE3, 0x70, 0x1A,
0xF9, 0xB0, 0x23, 0x9E, 0x93, 0x37, 0x73, 0xF5, 0xC9, 0x4E, 0x3F, 0xA2, 0x21, 0xDC, 0xE9, 0x1B,
0x91, 0x16, 0x89, 0x18, 0x1F, 0x12, 0xE0, 0x8F, 0x6D, 0x0F, 0x90, 0xAB, 0x8E, 0xBB, 0x69, 0xED,
0xBB, 0x60, 0x9F, 0x36, 0x6E, 0xE7, 0xDD, 0xDE, 0xEB, 0xE4, 0xED, 0x3B, 0xA0, 0x15, 0x4A, 0x24,
0x10, 0x77, 0x88, 0x27, 0x42, 0x48, 0x9B, 0x10, 0xA7, 0x36, 0x0A, 0xD7, 0xAC, 0x66, 0x4C, 0x27,
0x8F, 0x38, 0xF5, 0x71, 0xBA, 0xEF, 0xBC, 0x61, 0xE6, 0xD7, 0x47, 0x03, 0x18, 0x2E, 0x11, 0xE3,
0x28, 0x01, 0xB6, 0x5E, 0x4E, 0x80, 0xB8, 0xD3, 0x79, 0xFB, 0xC8, 0x74, 0x41, 0x5A, 0x4F, 0x1D,
0x27, 0x84, 0x8A, 0x6B, 0x6D, 0x5C, 0xF9, 0xBC, 0x00, 0xF1, 0x38, 0x01, 0x20, 0xA1, 0xF2, 0x1A,
0x42, 0xC5, 0xB3, 0x93, 0x67, 0xCD, 0x76, 0x5E, 0x4F, 0x9C, 0xEC, 0xA6, 0x8D, 0x44, 0x9C, 0xFA,
0xE4, 0xA6, 0x6F, 0xE8, 0xB5, 0x6E, 0xDA, 0x66, 0xD8, 0x91, 0xB7, 0x07, 0xC2, 0x85, 0x6D, 0xE2,
0x54, 0xFA, 0xF0, 0x79, 0x27, 0x4E, 0xB6, 0x3A, 0xCE, 0x89, 0xE3, 0x76, 0xDE, 0xEE, 0xBD, 0xD6,
0x46, 0xA7, 0x9F, 0xBD, 0xD6, 0xE9, 0x6B, 0x00, 0x95, 0x77, 0xA6, 0x6F, 0xE6, 0x02, 0xE4, 0x6D,
0x5A, 0x9D, 0xBA, 0x4E, 0x1F, 0xB4, 0x36, 0x76, 0xEF, 0x73, 0x1B, 0x17, 0x79, 0x36, 0xAB, 0x6E,
0x5A, 0xC3, 0x38, 0x0B, 0xDB, 0x6D, 0xE9, 0x70, 0x38, 0x6C, 0x53, 0xD0, 0x29, 0x94, 0x4A, 0xBF,
0x45, 0xE7, 0xCF, 0xE5, 0xA6, 0x9F, 0x5F, 0x1D, 0x67, 0xEA, 0x79, 0x93, 0xD7, 0x10, 0x56, 0x5E,
0x7D, 0xEC, 0x3B, 0x80, 0x78, 0x16, 0x7B, 0xFA, 0x5A, 0x19, 0x77, 0xFA, 0x7A, 0x5C, 0x22, 0xEE,
0x4C, 0x5F, 0x8F, 0x4B, 0x95, 0xCF, 0x06, 0x50, 0x69, 0x2A, 0x64, 0xA3, 0xA7, 0xCE, 0x61, 0xA4,
0xDF, 0xBC, 0x8C, 0x0A, 0x9D, 0x7E, 0x06, 0xF9, 0x6D, 0x60, 0x00, 0xD5, 0xB1, 0x8F, 0x4C, 0xA7,
0xFF, 0x96, 0x62, 0xD7, 0xC7, 0x9D, 0xFA, 0x85, 0xF2, 0x09, 0x67, 0xFA, 0x26, 0xF5, 0xC9, 0xDF,
0xB4, 0x7A, 0x64, 0xEA, 0x79, 0xAF, 0x53, 0x6F, 0x3D, 0xEF, 0xF3, 0xE5, 0x5D, 0x71, 0xED, 0xBF,
0x4E, 0x3F, 0x7C, 0x8C, 0x00, 0x5B, 0x08, 0xE0, 0x1C, 0xA3, 0xF9, 0x5C, 0xF2, 0x39, 0x90, 0xDA,
0xC5, 0x0B, 0x9A, 0xB5, 0x1C, 0xF1, 0x4D, 0x48, 0x7F, 0x92, 0x3B, 0xEF, 0xB5, 0xFB, 0xD9, 0xE9,
0xEB, 0xA9, 0x93, 0xDB, 0xB8, 0x76, 0xE7, 0xB3, 0xBD, 0x77, 0x6A, 0xA3, 0x1B, 0xD7, 0x09, 0xC0,
0xC4, 0xDD, 0x4D, 0x6B, 0xF7, 0x3F, 0x7F, 0xD3, 0xE6, 0xD5, 0x46, 0xA7, 0x6E, 0xF7, 0x5E, 0x09,
0xEB, 0xE6, 0x7D, 0x0B, 0xF9, 0x15, 0x62, 0x9C, 0x99, 0x76, 0x19, 0x01, 0x36, 0xF5, 0x94, 0xD4,
0xE9, 0xAF, 0xB3, 0x69, 0x17, 0x23, 0x5F, 0x07, 0xEF, 0xD3, 0xFD, 0x46, 0xE4, 0xE3, 0xEE, 0x89,
0xA3, 0xDD, 0x77, 0x6B, 0xE3, 0x6E, 0xDA, 0xFC, 0xDE, 0xE7, 0xE4, 0xDD, 0x87, 0x54, 0xF6, 0x81,
0xE5, 0x9C, 0x3A, 0x6E, 0xE7, 0xF5, 0xCC, 0xCF, 0x1D, 0x99, 0xF9, 0xBD, 0x6F, 0x66, 0xF2, 0xDB,
0x08, 0xF0, 0x3C, 0x01, 0xEE, 0x93, 0xF0, 0xDE, 0x9E, 0xAD, 0x7B, 0x20, 0x54, 0xE8, 0x1E, 0xD8,
0xC4, 0xE7, 0xDB, 0x46, 0x42, 0x58, 0xA3, 0x91, 0x9F, 0x09, 0x0B, 0x11, 0x5F, 0x01, 0x1B, 0x61,
0x27, 0x9D, 0x3F, 0x40, 0x80, 0xA3, 0xF6, 0xB9, 0x1F, 0x77, 0x2B, 0xD3, 0x1A, 0x40, 0xA7, 0x1E,
0x81, 0x53, 0x1C, 0x99, 0x27, 0xE8, 0xFB, 0x71, 0xA6, 0x7E, 0x14, 0x9A, 0xB8, 0xD6, 0x97, 0xB5,
0xE3, 0x4C, 0xFA, 0xBF, 0xB0, 0x0F, 0xF6, 0x82, 0x3E, 0x6D, 0x4F, 0xC2, 0x29, 0xA4, 0x9B, 0x98,
0xFE, 0x1E, 0xD6, 0x35, 0x84, 0x98, 0x24, 0xE1, 0xE6, 0x1B, 0x24, 0xFC, 0x8E, 0xC7, 0x0E, 0x10,
0x0A, 0x85, 0x6C, 0x0A, 0xDB, 0xC4, 0x6B, 0xF8, 0x20, 0xCE, 0xCB, 0x58, 0xF2, 0xA3, 0x76, 0x62,
0xED, 0xBF, 0x41, 0xAC, 0x8F, 0xFB, 0xF0, 0xF1, 0x70, 0xA0, 0x58, 0xC6, 0x08, 0x02, 0x4C, 0xA4,
0x3A, 0xD3, 0x91, 0x7F, 0x08, 0x16, 0x11, 0x60, 0x1D, 0xF5, 0xD9, 0x42, 0xEF, 0xFF, 0x4E, 0x6D,
0xDE, 0x83, 0x0D, 0x88, 0x2F, 0x21, 0xC0, 0x6C, 0xAA, 0x33, 0x4D, 0x62, 0xCD, 0xF7, 0xC3, 0x24,
0x89, 0x9E, 0x9D, 0x22, 0xD1, 0xA6, 0xA9, 0x30, 0x59, 0xA2, 0x9F, 0xDC, 0x2F, 0x91, 0xF0, 0x44,
0xA4, 0xA7, 0xC2, 0x3C, 0x58, 0x89, 0xF4, 0xAF, 0x61, 0x1D, 0x3C, 0xC7, 0xE4, 0x27, 0x10, 0xA4,
0x9B, 0x84, 0xF9, 0x54, 0x17, 0x7E, 0xF3, 0xE2, 0x4F, 0x64, 0x97, 0xDC, 0x03, 0xC9, 0x3B, 0x08,
0x30, 0x0B, 0x9E, 0xE4, 0xB7, 0x0A, 0xCF, 0x94, 0x4A, 0x72, 0x55, 0xA9, 0x58, 0xBF, 0x82, 0x7A,
0x8F, 0x58, 0x9B, 0x79, 0xCB, 0xDC, 0x02, 0xDB, 0x79, 0xA7, 0x3F, 0x50, 0x21, 0xF1, 0xD0, 0x8D,
0xC8, 0xDF, 0x0A, 0xC3, 0x90, 0xBE, 0x03, 0x79, 0x5E, 0x8F, 0xFF, 0xCD, 0x47, 0x44, 0x3E, 0x07,
0xC7, 0x7E, 0x52, 0x2A, 0xB1, 0xEF, 0x14, 0x4B, 0xF4, 0xBB, 0x25, 0x12, 0x7D, 0x10, 0x26, 0x70,
0x3D, 0x81, 0x75, 0x7A, 0xB1, 0x44, 0x16, 0x94, 0x48, 0xE4, 0x37, 0x5E, 0x31, 0x0E, 0x55, 0x20,
0xDD, 0x0B, 0x6E, 0x43, 0x7C, 0x08, 0xF4, 0x82, 0xA0, 0x84, 0x4F, 0x79, 0x24, 0xB4, 0xC3, 0x2F,
0xE1, 0x75, 0xFE, 0xB6, 0xEF, 0x81, 0x24, 0xBF, 0x91, 0x48, 0x7A, 0xA0, 0x82, 0x00, 0x5D, 0xF8,
0x60, 0xC2, 0xAF, 0x37, 0xAC, 0xBE, 0x5C, 0x0F, 0xE6, 0xB7, 0x09, 0xD5, 0x30, 0xCC, 0x23, 0xF1,
0xE1, 0x30, 0x0D, 0x96, 0x94, 0x8A, 0xF9, 0x6A, 0x89, 0x98, 0x7F, 0xF6, 0x88, 0xB9, 0x99, 0xEB,
0xD5, 0x48, 0x4F, 0xF4, 0x48, 0xAC, 0x0B, 0x1F, 0x54, 0xDA, 0xEB, 0x6F, 0x15, 0xBC, 0x36, 0xCD,
0xD0, 0x54, 0xE4, 0x91, 0x46, 0x88, 0x70, 0x6D, 0x14, 0x43, 0x27, 0x98, 0xEC, 0x11, 0x63, 0x7D,
0xA9, 0x18, 0x7C, 0x86, 0x30, 0x76, 0xB1, 0xEE, 0xF4, 0x48, 0xB8, 0xC1, 0x2B, 0xA1, 0xE5, 0x4C,
0x7F, 0x86, 0x4F, 0x42, 0xB5, 0x97, 0x11, 0xE0, 0xC2, 0x63, 0xEB, 0x4A, 0xFB, 0xF3, 0x25, 0x2B,
0xA4, 0xC2, 0xD9, 0xF3, 0xDE, 0xBE, 0xE6, 0x49, 0xAB, 0xA7, 0x8E, 0x5E, 0x3B, 0x9B, 0xB5, 0xF5,
0x69, 0xAB, 0x47, 0xA5, 0xFE, 0x7D, 0x4C, 0x5F, 0x13, 0xF2, 0xDF, 0x32, 0xF3, 0x4E, 0x9C, 0xDC,
0xC9, 0x93, 0x77, 0x6C, 0xB6, 0xBE, 0x22, 0x3B, 0x27, 0x4B, 0xD8, 0x70, 0x9E, 0xB4, 0x21, 0x7D,
0xE2, 0xBA, 0xA7, 0x4D, 0xFE, 0xC6, 0x6D, 0x61, 0x03, 0xB7, 0x84, 0x5A, 0x0A, 0xDB, 0xC4, 0xFA,
0x0F, 0x66, 0x5F, 0xD2, 0xF4, 0x5A, 0x5F, 0x17, 0x72, 0x01, 0xF2, 0x4E, 0x9D, 0xEC, 0xC3, 0x2A,
0x17, 0xE0, 0x53, 0xDF, 0xEF, 0x39, 0x36, 0x79, 0xD2, 0xB6, 0xBE, 0xE3, 0xEB, 0x6B, 0xB2, 0xF3,
0xC1, 0xC4, 0x79, 0x5D, 0x70, 0x03, 0x84, 0x79, 0xF2, 0xDA, 0x01, 0x42, 0x17, 0x04, 0x70, 0xA4,
0x35, 0x40, 0xA8, 0xA5, 0x0D, 0x01, 0xAE, 0xB4, 0xDA, 0xB4, 0xE9, 0x49, 0xAC, 0x1D, 0xBB, 0xD2,
0xF9, 0xD4, 0x0F, 0xF5, 0xF3, 0x17, 0x2C, 0x1A, 0x77, 0xB9, 0x5F, 0x2F, 0xF1, 0xF5, 0x94, 0x7C,
0x9E, 0x5C, 0xCA, 0x83, 0x3B, 0x32, 0x14, 0xFA, 0x42, 0x30, 0xF7, 0xFD, 0x00, 0x17, 0x5E, 0xE8,
0x0C, 0xB7, 0x80, 0x7E, 0x79, 0x50, 0x10, 0xC5, 0x45, 0x25, 0x03, 0x4B, 0x8A, 0x3D, 0x83, 0x3E,
0x4F, 0x0A, 0xF8, 0xD9, 0x2A, 0xDF, 0x01, 0x4A, 0xF3, 0x03, 0xE8, 0x17, 0x66, 0x1A, 0xA2, 0x1C,
0xF4, 0x9B, 0x8F, 0x2B, 0x19, 0x9D, 0xFC, 0x79, 0xF2, 0xF9, 0x41, 0xAE, 0x5D, 0x5F, 0x9B, 0xC0,
0xB5, 0x09, 0x5C, 0x85, 0x13, 0xF8, 0x1F, 0x36, 0x17, 0x75, 0x31, 0x45, 0xB2, 0x22, 0x02, 0x00,
0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
};

View File

@ -1,10 +1,6 @@
data_files = files(
data_files += files(
'hmap.cpp',
'icon.cpp',
'images.cpp',
)
data_files += to_array.process('font.bz2', extra_args: 'compressed_font_data')
powder_files += data_files
render_files += data_files
font_files += data_files

View File

@ -98,7 +98,7 @@ conf_data.set('ZLIB_WINAPI', false)
x86_sse_level_str = get_option('x86_sse')
if x86_sse_level_str == 'auto'
x86_sse_level = 20
if not is_x86 or not is_64bit or host_platform == 'darwin'
if not is_x86 or not is_64bit or host_platform == 'darwin' or (is_64bit and is_msvc)
x86_sse_level = 0
endif
elif x86_sse_level_str == 'sse3'
@ -329,23 +329,33 @@ conf_data.set('MOD_ID', get_option('mod_id'))
conf_data.set('DEBUG', is_debug)
conf_data.set('SNAPSHOT', get_option('snapshot'))
conf_data.set('SNAPSHOT_ID', get_option('snapshot_id'))
conf_data.set('SERVER', '"' + get_option('server') + '"')
conf_data.set('STATICSERVER', '"' + get_option('static_server') + '"')
conf_data.set('IDENT_PLATFORM', '"' + ident_platform + '"')
conf_data.set('SERVER', '"@0@"'.format(get_option('server')))
conf_data.set('STATICSERVER', '"@0@"'.format(get_option('static_server')))
conf_data.set('IDENT_PLATFORM', '"@0@"'.format(ident_platform))
conf_data.set('IDENT', '"@0@-@1@-@2@"'.format(host_arch, host_platform, host_libc).to_upper())
conf_data.set('APPNAME', get_option('app_name'))
conf_data.set('APPCOMMENT', get_option('app_comment'))
conf_data.set('APPEXE', get_option('app_exe'))
conf_data.set('APPID', get_option('app_id'))
conf_data.set('APPDATA', get_option('app_data'))
conf_data.set('APPVENDOR', get_option('app_vendor'))
if get_option('update_server') != ''
conf_data.set('UPDATESERVER', '"' + get_option('update_server') + '"')
conf_data.set('UPDATESERVER', '"@0@"'.format(get_option('update_server')))
else
conf_data.set('UPDATESERVER', false)
endif
resources_files = []
data_files = []
subdir('src')
subdir('data')
subdir('resources')
powder_files += data_files
render_files += data_files
font_files += data_files
if get_option('build_powder')
powder_deps = [
threads_dep,

View File

@ -129,3 +129,39 @@ option(
value: 'androidkey',
description: 'Signing key alias for signing an APK, only used for Android development'
)
option(
'app_name',
type: 'string',
value: 'The Powder Toy',
description: 'App name, used for desktop integration and the window title, change if you work on a mod'
)
option(
'app_comment',
type: 'string',
value: 'Physics sandbox game',
description: 'App comment, used for desktop integration, change if you work on a mod'
)
option(
'app_exe',
type: 'string',
value: 'powder',
description: 'App executable name, used for desktop integration, change if you work on a mod'
)
option(
'app_id',
type: 'string',
value: 'uk.co.powdertoy.tpt',
description: 'App ID, a D-Bus well-known name, used for desktop integration, change if you work on a mod'
)
option(
'app_data',
type: 'string',
value: 'The Powder Toy',
description: 'App data directory name, do not change even if you work on a mod, only if you know what you are doing'
)
option(
'app_vendor',
type: 'string',
value: 'powdertoy',
description: 'App vendor prefix, used for desktop integration, do not change even if you work on a mod, only if you know what you are doing'
)

View File

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<component type="desktop">
<id>@APPID@</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0</project_license>
<name>@APPNAME@</name>
<summary>@APPCOMMENT@</summary>
<content_rating type="oars-1.1">
<content_attribute id="social-chat">moderate</content_attribute>
</content_rating>
<launchable type="desktop-id">@APPID@.desktop</launchable>
<description>
<p>
Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more!
</p>
<p>
The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own we welcome your creations!
</p>
<p>
There is a Lua API you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development.
</p>
</description>
<screenshots>
<screenshot>
<image>https://powdertoy.co.uk/Themes/Next/Design/Images/Screen2.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://powdertoy.co.uk/</url>
<url type="bugtracker">https://github.com/The-Powder-Toy/The-Powder-Toy/issues</url>
<url type="help">https://powdertoy.co.uk/Wiki/W/Main_Page.html</url>
<releases>
<release date="@BSH_DATE@" version="@SAVE_VERSION@.@MINOR_VERSION@" />
</releases>
</component>

BIN
resources/cps16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

BIN
resources/cps32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
resources/exe48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,11 +1,20 @@
resources_files += files(
'icon.ico',
'document.ico',
)
if host_platform == 'windows'
powder_files += windows_mod.compile_resources(
'powder-res.rc',
depend_files: [ resources_files, 'resource.h' ],
depend_files: [
'icon.ico',
'document.ico',
'resource.h',
],
)
endif
data_files += to_array.process('cps16.png', extra_args: 'cps16_png')
data_files += to_array.process('cps32.png', extra_args: 'cps32_png')
data_files += to_array.process('exe48.png', extra_args: 'exe48_png')
data_files += to_array.process('save.xml', extra_args: 'save_xml')
data_files += to_array.process(configure_file(
input: 'powder.template.desktop',
output: 'powder.desktop',
configuration: conf_data,
), extra_args: 'powder_desktop')

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<component type="desktop">
<id>uk.co.powdertoy.tpt</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0</project_license>
<name>Powder Toy</name>
<summary>Physics sandbox game</summary>
<content_rating type="oars-1.1">
<content_attribute id="social-chat">moderate</content_attribute>
</content_rating>
<launchable type="desktop-id">powder.desktop</launchable>
<description>
<p>
The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own - we welcome your creations!
</p>
</description>
<screenshots>
<screenshot>
<image>http://powdertoy.co.uk/Themes/Next/Design/Images/Screen2.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://powdertoy.co.uk/</url>
<url type="bugtracker">https://github.com/The-Powder-Toy/The-Powder-Toy/issues</url>
<url type="help">https://powdertoy.co.uk/Wiki/W/Main_Page.html</url>
<releases>
<release date="2019-02-21" version="94.1" />
</releases>
</component>

View File

@ -1,9 +0,0 @@
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Name=Powder Toy
Comment=Physics sandbox game
Exec=powder
Icon=powder
Type=Application
Categories=Game;Simulation;

View File

@ -0,0 +1,8 @@
[Desktop Entry]
Name=@APPNAME@
Type=Application
Comment=@APPCOMMENT@
MimeType=application/vnd.powdertoy.save;x-scheme-handler/ptsave;
Categories=Game;Simulation;
Exec=@APPEXE@ %u
Icon=@APPEXE@

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/vnd.powdertoy.save">
<comment>Powder Toy save</comment>
<glob pattern="*.cps"/>

View File

@ -32,6 +32,12 @@
#mesondefine UPDATESERVER
#mesondefine IDENT_PLATFORM
#mesondefine IDENT
#define APPNAME "@APPNAME@"
#define APPCOMMENT "@APPCOMMENT@"
#define APPEXE "@APPEXE@"
#define APPID "@APPID@"
#define APPDATA "@APPDATA@"
#define APPVENDOR "@APPVENDOR@"
#ifdef WIN
# define PATH_SEP "\\"

View File

@ -10,35 +10,6 @@
#include "graphics/Graphics.h"
ByteString format::URLEncode(ByteString source)
{
char * src = (char *)source.c_str();
char * dst = new char[(source.length()*3)+2];
std::fill(dst, dst+(source.length()*3)+2, 0);
char *d;
for (d = dst; *d; d++) ;
for (unsigned char *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;
ByteString finalString(dst);
delete[] dst;
return finalString;
}
ByteString format::UnixtimeToDate(time_t unixtime, ByteString dateFormat)
{
struct tm * timeData;
@ -477,3 +448,57 @@ unsigned long format::CalculateCRC(unsigned char * data, int len)
{
return update_crc(0xffffffffL, data, len) ^ 0xffffffffL;
}
ByteString format::URLEncode(ByteString source)
{
ByteString result;
for (auto it = source.begin(); it < source.end(); ++it)
{
if (!((*it >= 'a' && *it <= 'z') ||
(*it >= 'A' && *it <= 'Z') ||
(*it >= '0' && *it <= '9')))
{
auto byte = uint8_t(*it);
result.append(1, '%');
result.append(1, hex[(byte >> 4) & 0xF]);
result.append(1, hex[ byte & 0xF]);
}
else
{
result.append(1, *it);
}
}
return result;
}
ByteString format::URLDecode(ByteString source)
{
ByteString result;
for (auto it = source.begin(); it < source.end(); ++it)
{
if (*it == '%' && it < source.end() + 2)
{
auto byte = uint8_t(0);
for (auto i = 0; i < 2; ++i)
{
it += 1;
auto *off = strchr(hex, tolower(*it));
if (!off)
{
return {};
}
byte = (byte << 4) | (off - hex);
}
result.append(1, byte);
}
else if (*it == '+')
{
result.append(1, ' ');
}
else
{
result.append(1, *it);
}
}
return result;
}

View File

@ -11,6 +11,7 @@ namespace format
const static char hex[] = "0123456789ABCDEF";
ByteString URLEncode(ByteString value);
ByteString URLDecode(ByteString value);
ByteString UnixtimeToDate(time_t unixtime, ByteString dateFomat = ByteString("%d %b %Y"));
ByteString UnixtimeToDateMini(time_t unixtime);
String CleanString(String dirtyString, bool ascii, bool color, bool newlines, bool numeric = false);

View File

@ -1,7 +1,6 @@
#include "Misc.h"
#include "Config.h"
#include "icondoc.h"
#include <cstring>
#include <sys/types.h>

View File

@ -222,7 +222,7 @@ void RecreateWindow()
SDL_DestroyWindow(sdl_window);
}
sdl_window = SDL_CreateWindow("The Powder Toy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOWW * scale, WINDOWH * scale,
sdl_window = SDL_CreateWindow(APPNAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOWW * scale, WINDOWH * scale,
flags);
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
SDL_RenderSetLogicalSize(sdl_renderer, WINDOWW, WINDOWH);

View File

@ -277,7 +277,7 @@ bool RecreateWindow()
SDL_DestroyWindow(sdl_window);
}
sdl_window = SDL_CreateWindow("The Powder Toy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOWW * scale, WINDOWH * scale,
sdl_window = SDL_CreateWindow(APPNAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOWW * scale, WINDOWH * scale,
flags);
if (!sdl_window)
{
@ -366,6 +366,10 @@ std::map<ByteString, ByteString> readArguments(int argc, char * argv[])
{
arguments["scripts"] = "true";
}
else if (!strncmp(argv[i], "file:", 5) && strlen(argv[i]) >= 7)
{
arguments["open"] = format::URLDecode(argv[i] + 7); // skip "file://"
}
else if (!strncmp(argv[i], "open", 5) && i+1<argc)
{
arguments["open"] = argv[i+1];
@ -376,6 +380,11 @@ std::map<ByteString, ByteString> readArguments(int argc, char * argv[])
arguments["ddir"] = argv[i+1];
i++;
}
else if (!strncmp(argv[i], "ptsave:", 7) && strlen(argv[i]) >= 8)
{
arguments["ptsave"] = argv[i];
break;
}
else if (!strncmp(argv[i], "ptsave", 7) && i+1<argc)
{
arguments["ptsave"] = argv[i+1];
@ -746,7 +755,7 @@ int main(int argc, char * argv[])
}
else
{
char *ddir = SDL_GetPrefPath(NULL, "The Powder Toy");
char *ddir = SDL_GetPrefPath(NULL, APPDATA);
#ifdef WIN
struct _stat s;
if (_stat("powder.pref", &s) != 0)

View File

@ -15,6 +15,14 @@
# include "common/macosx.h"
#endif
#ifdef LIN
# include "cps16.png.h"
# include "cps32.png.h"
# include "exe48.png.h"
# include "save.xml.h"
# include "powder.desktop.h"
#endif
#ifdef WIN
# ifndef NOMINMAX
# define NOMINMAX
@ -24,6 +32,7 @@
# include <shlwapi.h>
# include <windows.h>
# include <direct.h>
# include "resource.h"
#else
# include <sys/stat.h>
# include <unistd.h>
@ -150,262 +159,6 @@ bool Client::IsFirstRun()
return firstRun;
}
bool Client::DoInstallation()
{
#if defined(WIN)
CoInitializeEx(NULL, COINIT_MULTITHREADED);
wchar_t programsPath[MAX_PATH];
IShellLinkW *shellLink = NULL;
IPersistFile *shellLinkPersist = NULL;
int returnval = 0;
LONG rresult;
HKEY newkey;
ByteString currentfilename = Platform::ExecutableName();
ByteString iconname = currentfilename + ",-102";
ByteString AppDataPath = Platform::WinNarrow(_wgetcwd(NULL, 0));
ByteString opencommand = "\"" + currentfilename + "\" open \"%1\" ddir \"" + AppDataPath + "\"";
ByteString protocolcommand = "\"" + currentfilename + "\" ddir \"" + AppDataPath + "\" ptsave \"%1\"";
auto createKey = [](ByteString s, HKEY &k) {
return RegCreateKeyExW(HKEY_CURRENT_USER, Platform::WinWiden(s).c_str(), 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &k, NULL);
};
auto setValue = [](HKEY k, ByteString s) {
auto w = Platform::WinWiden(s);
return RegSetValueExW(k, NULL, 0, REG_SZ, (LPBYTE)&w[0], (w.size() + 1) * 2);
};
//Create protocol entry
rresult = createKey("Software\\Classes\\ptsave", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, "Powder Toy Save");
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
rresult = RegSetValueExW(newkey, (LPWSTR)L"URL Protocol", 0, REG_SZ, (LPBYTE)L"", 1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
//Set Protocol DefaultIcon
rresult = createKey("Software\\Classes\\ptsave\\DefaultIcon", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, iconname);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
//Set Protocol Launch command
rresult = createKey("Software\\Classes\\ptsave\\shell\\open\\command", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, protocolcommand);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
//Create extension entry
rresult = createKey("Software\\Classes\\.cps", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, "PowderToySave");
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
rresult = createKey("Software\\Classes\\.stm", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, "PowderToySave");
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
//Create program entry
rresult = createKey("Software\\Classes\\PowderToySave", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, "Powder Toy Save");
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
//Set DefaultIcon
rresult = createKey("Software\\Classes\\PowderToySave\\DefaultIcon", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, iconname);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
//Set Launch command
rresult = createKey("Software\\Classes\\PowderToySave\\shell\\open\\command", newkey);
if (rresult != ERROR_SUCCESS) {
goto finalise;
}
rresult = setValue(newkey, opencommand);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
goto finalise;
}
RegCloseKey(newkey);
if (SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, programsPath) != S_OK)
goto finalise;
if (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID *)&shellLink) != S_OK)
goto finalise;
shellLink->SetPath(Platform::WinWiden(currentfilename).c_str());
shellLink->SetWorkingDirectory(Platform::WinWiden(AppDataPath).c_str());
shellLink->SetDescription(L"The Powder Toy");
if (shellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&shellLinkPersist) != S_OK)
goto finalise;
shellLinkPersist->Save(Platform::WinWiden(Platform::WinNarrow(programsPath) + "\\The Powder Toy.lnk").c_str(), TRUE);
returnval = 1;
finalise:
if (shellLinkPersist)
shellLinkPersist->Release();
if (shellLink)
shellLink->Release();
CoUninitialize();
return returnval;
#elif defined(LIN)
#include "icondoc.h"
int success = 1;
ByteString filename = Platform::ExecutableName(), pathname = filename.SplitFromEndBy('/').Before();
filename.Substitute('\'', "'\\''");
filename = '\'' + filename + '\'';
FILE *f;
const 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);
const char *protocolfiledata_tmp =
"[Desktop Entry]\n"
"Type=Application\n"
"Name=Powder Toy\n"
"Comment=Physics sandbox game\n"
"MimeType=x-scheme-handler/ptsave;\n"
"NoDisplay=true\n"
"Categories=Game;Simulation\n"
"Icon=powdertoy.png\n";
ByteString protocolfiledata = ByteString::Build(protocolfiledata_tmp, "Exec=", filename, " ptsave %u\nPath=", pathname, "\n");
f = fopen("powdertoy-tpt-ptsave.desktop", "wb");
if (!f)
return 0;
fwrite(protocolfiledata.c_str(), 1, protocolfiledata.size(), f);
fclose(f);
success = system("xdg-desktop-menu install powdertoy-tpt-ptsave.desktop");
const char *desktopopenfiledata_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"
"Categories=Game;Simulation\n"
"Icon=powdertoy.png\n";
ByteString desktopopenfiledata = ByteString::Build(desktopopenfiledata_tmp, "Exec=", filename, " open %f\nPath=", pathname, "\n");
f = fopen("powdertoy-tpt-open.desktop", "wb");
if (!f)
return 0;
fwrite(desktopopenfiledata.c_str(), 1, desktopopenfiledata.size(), f);
fclose(f);
success = system("xdg-mime install powdertoy-save.xml") && success;
success = system("xdg-desktop-menu install powdertoy-tpt-open.desktop") && success;
const char *desktopfiledata_tmp =
"[Desktop Entry]\n"
"Version=1.0\n"
"Encoding=UTF-8\n"
"Name=Powder Toy\n"
"Type=Application\n"
"Comment=Physics sandbox game\n"
"Categories=Game;Simulation\n"
"Icon=powdertoy.png\n";
ByteString desktopfiledata = ByteString::Build(desktopfiledata_tmp, "Exec=", filename, "\nPath=", pathname, "\n");
f = fopen("powdertoy-tpt.desktop", "wb");
if (!f)
return 0;
fwrite(desktopfiledata.c_str(), 1, desktopfiledata.size(), f);
fclose(f);
success = system("xdg-desktop-menu install powdertoy-tpt.desktop") && success;
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);
f = fopen("powdertoy.png", "wb");
if (!f)
return 0;
fwrite(icon_desktop_48_png, 1, sizeof(icon_desktop_48_png), f);
fclose(f);
success = system("xdg-icon-resource install --noupdate --context mimetypes --size 32 powdertoy-save-32.png application-vnd.powdertoy.save") && success;
success = system("xdg-icon-resource install --noupdate --context mimetypes --size 16 powdertoy-save-16.png application-vnd.powdertoy.save") && success;
success = system("xdg-icon-resource install --noupdate --novendor --size 48 powdertoy.png") && success;
success = system("xdg-icon-resource forceupdate") && success;
success = system("xdg-mime default powdertoy-tpt-open.desktop application/vnd.powdertoy.save") && success;
success = system("xdg-mime default powdertoy-tpt-ptsave.desktop x-scheme-handler/ptsave") && success;
unlink("powdertoy.png");
unlink("powdertoy-save-32.png");
unlink("powdertoy-save-16.png");
unlink("powdertoy-save.xml");
unlink("powdertoy-tpt.desktop");
unlink("powdertoy-tpt-open.desktop");
unlink("powdertoy-tpt-ptsave.desktop");
return !success;
#else
return false;
#endif
}
void Client::SetMessageOfTheDay(String message)
{
messageOfTheDay = message;
@ -1820,3 +1573,148 @@ bool Client::WriteFile(std::vector<char> fileData, ByteString filename)
}
return true;
}
bool Client::DoInstallation()
{
bool ok = true;
#if defined(WIN)
auto deleteKey = [](ByteString path) {
RegDeleteKeyW(HKEY_CURRENT_USER, Platform::WinWiden(path).c_str());
};
auto createKey = [](ByteString path, ByteString value, ByteString extraKey = {}, ByteString extraValue = {}) {
auto ok = true;
auto wPath = Platform::WinWiden(path);
auto wValue = Platform::WinWiden(value);
auto wExtraKey = Platform::WinWiden(extraKey);
auto wExtraValue = Platform::WinWiden(extraValue);
HKEY k;
ok = ok && RegCreateKeyExW(HKEY_CURRENT_USER, wPath.c_str(), 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &k, NULL) == ERROR_SUCCESS;
ok = ok && RegSetValueExW(k, NULL, 0, REG_SZ, reinterpret_cast<const BYTE *>(wValue.c_str()), (wValue.size() + 1) * 2) == ERROR_SUCCESS;
if (wExtraKey.size())
{
ok = ok && RegSetValueExW(k, wExtraKey.c_str(), 0, REG_SZ, reinterpret_cast<const BYTE *>(wExtraValue.c_str()), (wExtraValue.size() + 1) * 2) == ERROR_SUCCESS;
}
RegCloseKey(k);
return ok;
};
CoInitializeEx(NULL, COINIT_MULTITHREADED);
auto exe = Platform::ExecutableName();
auto icon = exe + ",-" MTOS(IDI_DOC_ICON);
auto path = Platform::GetCwd();
auto open = ByteString::Build("\"", exe, "\" ddir \"", path, "\" \"file://%1\"");
auto ptsave = ByteString::Build("\"", exe, "\" ddir \"", path, "\" \"%1\"");
deleteKey("Software\\Classes\\ptsave");
deleteKey("Software\\Classes\\.cps");
deleteKey("Software\\Classes\\.stm");
deleteKey("Software\\Classes\\PowderToySave");
ok = ok && createKey("Software\\Classes\\ptsave", "Powder Toy Save", "URL Protocol", "");
ok = ok && createKey("Software\\Classes\\ptsave\\DefaultIcon", icon);
ok = ok && createKey("Software\\Classes\\ptsave\\shell\\open\\command", ptsave);
ok = ok && createKey("Software\\Classes\\.cps", "PowderToySave");
ok = ok && createKey("Software\\Classes\\.stm", "PowderToySave");
ok = ok && createKey("Software\\Classes\\PowderToySave", "Powder Toy Save");
ok = ok && createKey("Software\\Classes\\PowderToySave\\DefaultIcon", icon);
ok = ok && createKey("Software\\Classes\\PowderToySave\\shell\\open\\command", open);
IShellLinkW *shellLink = NULL;
IPersistFile *shellLinkPersist = NULL;
wchar_t programsPath[MAX_PATH];
ok = ok && SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, programsPath) == S_OK;
ok = ok && CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID *)&shellLink) == S_OK;
ok = ok && shellLink->SetPath(Platform::WinWiden(exe).c_str()) == S_OK;
ok = ok && shellLink->SetWorkingDirectory(Platform::WinWiden(path).c_str()) == S_OK;
ok = ok && shellLink->SetDescription(Platform::WinWiden(APPNAME).c_str()) == S_OK;
ok = ok && shellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&shellLinkPersist) == S_OK;
ok = ok && shellLinkPersist->Save(Platform::WinWiden(Platform::WinNarrow(programsPath) + "\\" APPNAME ".lnk").c_str(), TRUE) == S_OK;
if (shellLinkPersist)
{
shellLinkPersist->Release();
}
if (shellLink)
{
shellLink->Release();
}
CoUninitialize();
#elif defined(LIN)
auto desktopEscapeString = [](ByteString str) {
ByteString escaped;
for (auto ch : str)
{
auto from = " " "\n" "\t" "\r" "\\";
auto to = "s" "n" "t" "r" "\\";
if (auto off = strchr(from, ch))
{
escaped.append(1, '\\');
escaped.append(1, to[off - from]);
}
else
{
escaped.append(1, ch);
}
}
return escaped;
};
auto desktopEscapeExec = [](ByteString str) {
ByteString escaped;
for (auto ch : str)
{
if (strchr(" \t\n\"\'\\><~|&;$*?#()`", ch))
{
escaped.append(1, '\\');
}
escaped.append(1, ch);
}
return escaped;
};
if (ok)
{
ByteString desktopData(powder_desktop, powder_desktop + powder_desktop_size);
auto exe = Platform::ExecutableName();
auto path = exe.SplitFromEndBy('/').Before();
desktopData = desktopData.Substitute("Exec=" APPEXE, "Exec=" + desktopEscapeString(desktopEscapeExec(exe)));
desktopData += ByteString::Build("Path=", desktopEscapeString(path), "\n");
ByteString file = APPVENDOR "-" APPID ".desktop";
ok = ok && WriteFile(std::vector<char>(desktopData.begin(), desktopData.end()), file);
ok = ok && !system(ByteString::Build("xdg-desktop-menu install ", file).c_str());
ok = ok && !system(ByteString::Build("xdg-mime default ", file, " application/vnd.powdertoy.save").c_str());
ok = ok && !system(ByteString::Build("xdg-mime default ", file, " x-scheme-handler/ptsave").c_str());
Platform::RemoveFile(file);
}
if (ok)
{
ByteString file = APPVENDOR "-save.xml";
ok = ok && WriteFile(std::vector<char>(save_xml, save_xml + save_xml_size), file);
ok = ok && !system(ByteString::Build("xdg-mime install ", file).c_str());
Platform::RemoveFile(file);
}
if (ok)
{
ByteString file = APPVENDOR "-cps32.png";
ok = ok && WriteFile(std::vector<char>(cps32_png, cps32_png + cps32_png_size), file);
ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --context mimetypes --size 32 ", file, " application-vnd.powdertoy.save").c_str());
Platform::RemoveFile(file);
}
if (ok)
{
ByteString file = APPVENDOR "-cps16.png";
ok = ok && WriteFile(std::vector<char>(cps16_png, cps16_png + cps16_png_size), file);
ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --context mimetypes --size 16 ", file, " application-vnd.powdertoy.save").c_str());
Platform::RemoveFile(file);
}
if (ok)
{
ByteString file = APPVENDOR "-exe48.png";
ok = ok && WriteFile(std::vector<char>(exe48_png, exe48_png + exe48_png_size), file);
ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --size 48 ", file, " " APPVENDOR "-" APPEXE).c_str());
Platform::RemoveFile(file);
}
if (ok)
{
ok = ok && !system("xdg-icon-resource forceupdate");
}
#else
ok = false;
#endif
return ok;
}

View File

@ -38,8 +38,23 @@ std::string sharedCwd;
ByteString GetCwd()
{
char *cwd = getcwd(NULL, 0);
return cwd == nullptr ? "" : cwd;
ByteString cwd;
#if defined(WIN)
wchar_t *cwdPtr = _wgetcwd(NULL, 0);
if (cwdPtr)
{
cwd = WinNarrow(cwdPtr);
}
free(cwdPtr);
#else
char *cwdPtr = getcwd(NULL, 0);
if (cwdPtr)
{
cwd = cwdPtr;
}
free(cwdPtr);
#endif
return cwd;
}
ByteString ExecutableName()

View File

@ -256,9 +256,9 @@ void GameController::PlaceSave(ui::Point position)
void GameController::Install()
{
#if defined(MACOSX)
new InformationMessage("No installation necessary", "You don't need to install The Powder Toy on OS X", false);
new InformationMessage("No installation necessary", "You don't need to install " APPNAME " on OS X", false);
#elif defined(WIN) || defined(LIN)
new ConfirmPrompt("Install The Powder Toy", "Do you wish to install The Powder Toy on this computer?\nThis allows you to open save files and saves directly from the website.", { [] {
new ConfirmPrompt("Install " APPNAME, "Do you wish to install " APPNAME " on this computer?\nThis allows you to open save files and saves directly from the website.", { [] {
if (Client::Ref().DoInstallation())
{
new InformationMessage("Success", "Installation completed", false);
@ -269,7 +269,7 @@ void GameController::Install()
}
} });
#else
new ErrorMessage("Cannot install", "You cannot install The Powder Toy on this platform");
new ErrorMessage("Cannot install", "You cannot install " APPNAME " on this platform");
#endif
}

View File

@ -396,7 +396,7 @@ OptionsView::OptionsView():
if (!cwd.empty())
Platform::OpenURI(cwd);
else
fprintf(stderr, "cannot open data folder: getcwd(...) failed\n");
fprintf(stderr, "cannot open data folder: Platform::GetCwd(...) failed\n");
} });
scrollPanel->AddChild(dataFolderButton);