void Registry::setString(StringRange valueName, StringRange value, Registry::ValueKind kind) { assert("Empty Registry" && *this); assert("Invalid Registry::ValueKind" && (kind == ValueKind::string || kind == ValueKind::expandString || kind == ValueKind::multiString)); checkResult(RegSetValueExW(_handle, valueName.c_str(), 0, kind , reinterpret_cast<const BYTE*>(value.c_str()), value.length() * sizeof(wchar_t))); }
Registry::Registry(StringRange path, bool writable) : _handle(nullptr) { assert("Empty path" && !path.empty()); int rootKeyNameEnd = String::refer(path).indexOf(L'\\'); StringRange subKeyName = L""; if (rootKeyNameEnd == -1) { rootKeyNameEnd = path.length(); } else { subKeyName = StringRange(path.c_str() + rootKeyNameEnd + 1); } if (!rootKeyNameEnd) { assert("Invalid Registry root key name" && false); } else if (!String::compare(path, 0, L"HKEY_CLASSES_ROOT", 0, rootKeyNameEnd)) { *this = Registry::classesRoot(); } else if (!String::compare(path, 0, L"HKEY_CURRENT_CONFIG", 0, rootKeyNameEnd)) { *this = Registry::currentConfig(); } else if (!String::compare(path, 0, L"HKEY_CURRENT_USER", 0, rootKeyNameEnd)) { *this = Registry::currentUser(); } else if (!String::compare(path, 0, L"HKEY_LOCAL_MACHINE", 0, rootKeyNameEnd)) { *this = Registry::localMachine(); } else if (!String::compare(path, 0, L"HKEY_USERS", 0, rootKeyNameEnd)) { *this = Registry::users(); } else { assert("Invalid Registry root key name" && false); } if (!subKeyName.empty()) { *this = openKey(subKeyName, writable); } }
static void normalise_path(std::string &result, const StringRange &path) { StringRange part(path.begin, path.end); if (!path.Empty() && (path[0] == '/')) { result += '/'; ++part.begin; } const size_t initial_result_length = result.size(); while (true) { part.end = part.FindChar('/'); // returns part.end if the char is not found if (part.Empty() || (part == ".")) { // skip this part } else if (part == "..") { // pop the last component if (result.size() <= initial_result_length) throw std::invalid_argument(path.ToString()); size_t pos = result.rfind('/'); if (pos == std::string::npos) { pos = 0; } assert(pos >= initial_result_length); result.erase(pos); } else { // push the new component if (result.size() > initial_result_length) result += '/'; result.append(part.begin, part.Size()); } if (part.end == path.end) { break; } assert(*part.end == '/'); part.begin = part.end + 1; part.end = path.end; } }
Registry Registry::createKey(StringRange keyName, bool writable) { assert("Empty Registry" && *this); assert("Empty keyName" && !keyName.empty()); Registry key; checkResult(RegCreateKeyExW(_handle, keyName.c_str(), 0, nullptr, REG_OPTION_NON_VOLATILE , writable ? KEY_ALL_ACCESS : KEY_READ, nullptr, &key._handle, nullptr)); return key; }
Registry Registry::openKey(StringRange keyName, bool writable) const { assert("Empty Registry" && *this); assert("Empty kKeyName" && !keyName.empty()); Registry key; checkResult(RegOpenKeyExW(_handle, keyName.c_str(), 0 , writable ? KEY_ALL_ACCESS : KEY_READ, &key._handle)); return key; }
float IniConfig::Float(const std::string §ion, const std::string &key, float defval) const { SectionMapType::const_iterator secIt = m_map.find(section); if (secIt == m_map.end()) return defval; MapType::const_iterator it = secIt->second.find(key); if (it == secIt->second.end()) return defval; const StringRange val = StringRange(it->second.c_str(), it->second.size()).StripSpace(); if (val.Empty()) return defval; char *end = 0; float x = strtod(val.begin, &end); if (end != val.end) return defval; return x; }
void Registry::setBinary(StringRange valueName, ArrayRange<const unsigned char> value, Registry::ValueKind kind) { assert("Empty Registry" && *this); assert("Invalid Registry::ValueKind" && ValueKind::_validate(kind)); checkResult(RegSetValueExW(_handle, valueName.c_str(), 0, kind , value.empty() ? nullptr : value.begin(), value.size())); }
void Registry::removeKey(StringRange keyName, bool recursive) { assert("Empty Registry" && *this); assert("Empty keyName" && !keyName.empty()); if (recursive) { Registry key = openKey(keyName, true); if (key) { auto i = NamesIterator(key, true); while (i) { key.removeKey(*i, true); i.refresh(); } } } checkResult(RegDeleteKeyW(_handle, keyName.c_str())); }
vector<unsigned char> Registry::getBinary(StringRange valueName) const { assert("Empty Registry" && *this); DWORD type = REG_NONE; DWORD size = 0; LONG result = RegQueryValueExW(_handle, valueName.c_str(), nullptr, &type, nullptr, &size); vector<unsigned char> buffer; if (result == ERROR_SUCCESS && 0 < size) { buffer.resize(size); result = RegQueryValueExW(_handle, valueName.c_str(), nullptr, &type, buffer.data(), &size); } if (result == ERROR_FILE_NOT_FOUND) { throw ValueNotFoundException(); } checkResult(result); return buffer; }
void IniConfig::Read(const FileSystem::FileData &data) { StringRange buffer = data.AsStringRange(); buffer = buffer.StripUTF8BOM(); while (!buffer.Empty()) { StringRange line = buffer.ReadLine().StripSpace(); // if the line is a comment, skip it if (line.Empty() || (line[0] == '#')) continue; const char *kend = line.FindChar('='); // if there's no '=' sign, skip the line if (kend == line.end) { fprintf(stderr, "WARNING: ignoring invalid line in config file:\n '%.*s'\n", int(line.Size()), line.begin); continue; } StringRange key(line.begin, kend); StringRange value(kend + 1, line.end); // strip whitespace key.end = key.RFindNonSpace(); value = value.StripSpace(); m_map[key.ToString()] = value.ToString(); } }
unsigned __int64 Registry::getQword(StringRange valueName) const { assert("Empty Registry" && *this); DWORD type = REG_NONE; DWORD size = 0; LONG result = RegQueryValueExW(_handle, valueName.c_str(), nullptr, &type, nullptr, &size); unsigned __int64 value = 0; if (result == ERROR_SUCCESS) { if (type != REG_DWORD && size != sizeof(value)) { throw ValueKindMismatchException(); } result = RegQueryValueExW(_handle, valueName.c_str(), nullptr, &type, reinterpret_cast<LPBYTE>(&value), &size); } if (result == ERROR_FILE_NOT_FOUND) { throw ValueNotFoundException(); } checkResult(result); return value; }
void IniConfig::Read(const FileSystem::FileData &data) { StringRange buffer = data.AsStringRange(); buffer = buffer.StripUTF8BOM(); std::string section_name; MapType *section_map = 0; while (!buffer.Empty()) { StringRange line = buffer.ReadLine().StripSpace(); // if the line is a comment, skip it if (line.Empty() || (line[0] == '#')) continue; // check for a section header if ((line.Size() >= 2) && (line[0] == '[') && (line.end[-1] == ']')) { ++line.begin; --line.end; section_name = line.ToString(); section_map = 0; continue; } const char *kend = line.FindChar('='); // if there's no '=' sign, skip the line if (kend == line.end) { Output("WARNING: ignoring invalid line in config file:\n '%.*s'\n", int(line.Size()), line.begin); continue; } StringRange key(line.begin, kend); StringRange value(kend + 1, line.end); // strip whitespace key.end = key.RFindNonSpace(); value = value.StripSpace(); if (!section_map) section_map = &m_map[section_name]; (*section_map)[key.ToString()] = value.ToString(); } }
void Registry::getStringToBuffer(StringBuffer& buffer, StringRange valueName) const { assert("Empty Registry" && *this); DWORD type = REG_NONE; DWORD size = 0; LONG result = RegQueryValueExW(_handle, valueName.c_str(), nullptr, &type, nullptr, &size); if (result == ERROR_SUCCESS && 0 < size) { if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ) { throw ValueKindMismatchException(); } int length = size / sizeof(wchar_t); buffer.reserveAdditionally(length); result = RegQueryValueExW(_handle, valueName.c_str(), nullptr, &type, reinterpret_cast<LPBYTE>(buffer.end()), &size); buffer.expandLength(length - 1); } if (result == ERROR_FILE_NOT_FOUND) { throw ValueNotFoundException(); } checkResult(result); }
void DistanceFieldFont::ParseInfo(const StringRange &line) { std::stringstream ss(line.ToString()); std::string token; while (ss >> token != 0) { std::pair<std::string, std::string> pair; split_token(token, pair); if (pair.first == "size") { m_fontSize = get_value<float>(pair.second); return; } } }
void DistanceFieldFont::ParseCommon(const StringRange &line) { std::stringstream ss(line.ToString()); std::string token; while (ss >> token != 0) { std::pair<std::string, std::string> pair; split_token(token, pair); if (pair.first == "scaleW") m_sheetSize.x = get_value<float>(pair.second); else if (pair.first == "scaleH") m_sheetSize.y = get_value<float>(pair.second); } }
Registry::ValueKind Registry::getValueKind(StringRange valueName) const { assert("Empty Registry" && *this); ValueKind kind; const LONG result = RegQueryValueExW(_handle, valueName.c_str(), nullptr, reinterpret_cast<LPDWORD>(&kind), nullptr, nullptr); if (result == ERROR_FILE_NOT_FOUND) { return ValueKind::notFound; } else { checkResult(result); if (!ValueKind::_validate(kind)) { return ValueKind::unknown; } } return kind; }
//get font definitions from a line of xml, insert glyph information into the map void DistanceFieldFont::ParseChar(const StringRange &r) { std::stringstream ss(r.ToString()); std::string token; Uint32 id = 0; double x = 0.0; double y = 0.0; double uSize = 0.0; double vSize = 0.0; double xoffset = 0.0; double yoffset = 0.0; double advance = 0.0; while (ss >> token) { std::pair<std::string, std::string> pair; split_token(token, pair); //only care about some values if (pair.first == "id") id = get_value<Uint32>(pair.second); else if (pair.first == "x") x = get_value<double>(pair.second); else if (pair.first == "y") y = get_value<double>(pair.second); else if (pair.first == "width") uSize = get_value<double>(pair.second); else if (pair.first == "height") vSize = get_value<double>(pair.second); else if (pair.first == "xoffset") xoffset = get_value<float>(pair.second); else if (pair.first == "yoffset") yoffset = get_value<float>(pair.second); else if (pair.first == "xadvance") advance = get_value<float>(pair.second); } const float scale = 1.f/m_fontSize; Glyph g; g.uv = vector2f(float(x)/m_sheetSize.x, float(y)/m_sheetSize.y); g.uvSize = vector2f(float(uSize)/m_sheetSize.x, float(vSize)/m_sheetSize.y); g.size = vector2f(float(uSize), float(vSize)) * scale; g.offset = vector2f(float(xoffset), float(m_lineHeight-vSize-yoffset)) * scale; g.xAdvance = advance * scale; m_glyphs[id] = g; }
Cursor Resource::getCursor(StringRange name) { if (locale() != Locale::invariant() && !isId(name)) { auto handle = static_cast<HCURSOR>(LoadImageW(_module, getLocalName(name, _localeName), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); if (handle) { return Cursor(handle); } } auto handle = static_cast<HCURSOR>(LoadImageW(_module, name.c_str(), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); if (!handle) { const DWORD errorCode = GetLastError(); switch (errorCode) { case ERROR_NOT_ENOUGH_MEMORY : throw OutOfMemoryException(); case ERROR_RESOURCE_TYPE_NOT_FOUND : case ERROR_RESOURCE_NAME_NOT_FOUND : throw NotFoundException(); default : assert(L"Failed to LoadImageW" && false); break; } } return Cursor(handle); }
MemoryStream Resource::getRawData(StringRange name) { HRSRC resource = nullptr; if (locale() != Locale::invariant() && !isId(name)) { resource = FindResourceW(_module, getLocalName(name, _localeName), reinterpret_cast<LPWSTR>(RT_RCDATA)); } if (!resource) { resource = FindResourceW(_module, name.c_str(), reinterpret_cast<LPWSTR>(RT_RCDATA)); } if (!resource) { throw NotFoundException(); } HGLOBAL const global = LoadResource(_module, resource); assert("Failed to LoadResource" && global); void* const buffer = LockResource(global); assert("Failed to LockResource" && buffer); const DWORD size = SizeofResource(_module, resource); assert(size <= INT_MAX); return MemoryStream(buffer, 0, size, false); }
Icon Resource::getIcon(StringRange name, const Size& size) { if (locale() != Locale::invariant() && !isId(name)) { auto handle = static_cast<HICON>(LoadImageW(_module, getLocalName(name, _localeName), IMAGE_ICON, size.width, size.height, LR_SHARED)); if (handle) { return Icon(handle); } } auto handle = static_cast<HICON>(LoadImageW(_module, name.c_str(), IMAGE_ICON, size.width, size.height, LR_SHARED)); if (!handle) { const DWORD errorCode = GetLastError(); switch (errorCode) { case ERROR_NOT_ENOUGH_MEMORY : throw OutOfMemoryException(); case ERROR_RESOURCE_TYPE_NOT_FOUND : case ERROR_RESOURCE_NAME_NOT_FOUND : throw NotFoundException(); default : assert(L"Failed to LoadImageW" && false); break; } } return Icon(handle); }
static void normalise_path(std::string &result, const StringRange &path) { StringRange part(path.begin, path.begin); const char *c = path.begin; if ((c != path.end) && (*c == '/')) { result += '/'; ++c; ++part.begin; } const size_t initial_result_length = result.size(); while (true) { if ((*c == '/') || (c == path.end)) { part.end = c; if (part.Empty() || (part == ".")) { // skip this part } else if (part == "..") { // pop the last component if (result.size() <= initial_result_length) throw std::invalid_argument(path.ToString()); size_t pos = result.rfind('/', result.size()-2); ++pos; assert(pos >= initial_result_length); result.erase(pos); } else { // push the new component if (part.end != path.end) { assert(*part.end == '/'); ++part.end; } result.append(part.begin, part.Size()); } part.begin = c+1; } if (c == path.end) { break; } ++c; } }
Bitmap Resource::getBitmap(StringRange name) { if (locale() != Locale::invariant() && !isId(name)) { auto handle = static_cast<HBITMAP>(LoadImageW(_module, getLocalName(name, _localeName), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION)); // まずは BITMAP リソースから探す if (handle) { return Bitmap(handle, true); } } auto handle = static_cast<HBITMAP>(LoadImageW(_module, name.c_str(), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION)); // まずは BITMAP リソースから探す if (!handle) { const DWORD errorCode = GetLastError(); switch (errorCode) { case ERROR_NOT_ENOUGH_MEMORY : throw OutOfMemoryException(); case ERROR_RESOURCE_TYPE_NOT_FOUND : case ERROR_RESOURCE_NAME_NOT_FOUND : { // 無ければ RCDATA リソースから auto stream = getRawData(name); return Bitmap(stream); } break; default : assert("Failed to LoadImageW" && false); break; } } return Bitmap(handle, true); }
Shader(GLenum type, const std::string &filename, const std::string &defines) { RefCountedPtr<FileSystem::FileData> filecode = FileSystem::gameDataFiles.ReadFile(filename); if (!filecode.Valid()) Error("Could not load %s", filename.c_str()); std::string strCode(filecode->AsStringRange().ToString()); size_t found = strCode.find("#include"); while (found != std::string::npos) { // find the name of the file to include const size_t begFilename = strCode.find_first_of("\"", found + 8) + 1; const size_t endFilename = strCode.find_first_of("\"", begFilename + 1); const std::string incFilename = strCode.substr(begFilename, endFilename - begFilename); // check we haven't it already included it (avoids circular dependencies) const std::set<std::string>::const_iterator foundIt = previousIncludes.find(incFilename); if (foundIt != previousIncludes.end()) { Error("Circular, or multiple, include of %s\n", incFilename.c_str()); } else { previousIncludes.insert(incFilename); } // build path for include const std::string incPathBuffer = stringf("shaders/opengl/%0", incFilename); // read included file RefCountedPtr<FileSystem::FileData> incCode = FileSystem::gameDataFiles.ReadFile(incPathBuffer); assert(incCode.Valid()); if (incCode.Valid()) { // replace the #include and filename with the included files text strCode.replace(found, (endFilename + 1) - found, incCode->GetData(), incCode->GetSize()); found = strCode.find("#include"); } else { Error("Could not load %s", incPathBuffer.c_str()); } } // Store the modified text with the included files (if any) const StringRange code(strCode.c_str(), strCode.size()); // Build the final shader text to be compiled AppendSource(s_glslVersion); AppendSource(defines.c_str()); if (type == GL_VERTEX_SHADER) { AppendSource("#define VERTEX_SHADER\n"); } else { AppendSource("#define FRAGMENT_SHADER\n"); } AppendSource(code.StripUTF8BOM()); #if 0 static bool s_bDumpShaderSource = true; if (s_bDumpShaderSource) { const char SHADER_OUT_DIR_NAME[] = "shaders"; const char SHADER_OGL_OUT_DIR_NAME[] = "shaders/opengl"; FileSystem::userFiles.MakeDirectory(SHADER_OUT_DIR_NAME); FileSystem::userFiles.MakeDirectory(SHADER_OGL_OUT_DIR_NAME); const std::string outFilename(FileSystem::GetUserDir() + "/" + filename); FILE *tmp = fopen(outFilename.c_str(), "wb"); if(tmp) { Output("%s", filename); for( Uint32 i=0; i<blocks.size(); i++ ) { const char *block = blocks[i]; const GLint sizes = block_sizes[i]; if(block && sizes>0) { fprintf(tmp, "%.*s", sizes, block); } } fclose(tmp); } else { Output("Could not open file %s", outFilename.c_str()); } } #endif shader = glCreateShader(type); if(glIsShader(shader)!=GL_TRUE) throw ShaderException(); Compile(shader); // CheckGLSL may use OS::Warning instead of Error so the game may still (attempt to) run if (!check_glsl_errors(filename.c_str(), shader)) throw ShaderException(); };
void AppendSource(StringRange str) { blocks.push_back(str.begin); block_sizes.push_back(str.Size()); }
void Registry::removeValue(StringRange valueName) { assert("Empty Registry" && *this); checkResult(RegDeleteValueW(_handle, valueName.c_str())); }
void Registry::setQword(StringRange valueName, unsigned __int64 value) { assert("Empty Registry" && *this); checkResult(RegSetValueExW(_handle, valueName.c_str(), 0, ValueKind::qword , reinterpret_cast<const BYTE*>(&value), sizeof(value))); }
RadioButton::RadioButton(Control& parent, int x, int y, int width, int height, StringRange text, bool firstOfGroup) : _checkedChanging(false) { attachHandle(CreateWindowExW(0, L"BUTTON", text.c_str() , WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | BS_AUTORADIOBUTTON | TextAlign::middleLeft | (firstOfGroup ? WS_GROUP : 0) , x, y, width, height, parent, nullptr,nullptr, nullptr)); size(getPreferredSize(width, height)); }