Bitmap *Bitmap::Load(const std::string& filename) { std::vector<IBitmapCodec *>codecs = IBitmapCodec::GetAllCodecs(); std::string errMsg; for(size_t i = 0; i < codecs.size(); i++) { IBitmapCodec *codec = codecs[i]; if(codec->CanLoad() && codec->CheckExtension(filename)) { // give it a try. // open error shouldn't be handled here StreamHandle str = FileManager::OpenForReading(filename.c_str()); try { return codec->Load(str); } catch(const std::exception& ex) { errMsg += codec->GetName(); errMsg += ":\n"; errMsg += ex.what(); errMsg += "\n\n"; } } } if(errMsg.empty()) { SPRaise("Bitmap codec not found for filename: %s", filename.c_str()); } else { SPRaise("No bitmap codec could load file successfully: %s\n%s\n", filename.c_str(), errMsg.c_str()); } }
virtual void Save(IStream *stream, Bitmap *bmp){ SPADES_MARK_FUNCTION(); int err; png_t png_s; if((err = png_open_write(&png_s, &WriteCallback, stream))){ SPRaise("Error while png_open_write: %s", png_error_string(err)); } // Create flipped buffer std::vector<std::uint8_t> buf(bmp->GetWidth() * bmp->GetHeight() * 4); { std::uint32_t *pixels = bmp->GetPixels(); auto width = bmp->GetWidth(); auto rowLengthBytes = width * sizeof(std::uint8_t) * 4; for(long y = bmp->GetHeight() - 1; y >= 0; --y) { std::memcpy(&buf[y*rowLengthBytes], pixels, rowLengthBytes); pixels += width; } } if((err = png_set_data(&png_s, bmp->GetWidth(), bmp->GetHeight(), 8, PNG_TRUECOLOR_ALPHA, buf.data()))){ SPRaise("Error while png_set_data: %s", png_error_string(err)); } }
void ScriptFunction::Load(asIScriptEngine *eng) { if(eng != lastEngine) { func = NULL; lastEngine = eng; } if(func == NULL){ asIScriptModule *module = eng->GetModule("Client"); eng->SetDefaultNamespace("spades"); module->SetDefaultNamespace("spades"); if(type.empty()) { func = eng->GetGlobalFunctionByDecl(decl.c_str()); if(!func){ func = module->GetFunctionByDecl(decl.c_str()); } if(!func){ SPRaise("Script function with signature '%s' not found.", decl.c_str()); } }else{ asITypeInfo *typ = eng->GetTypeInfoByName(type.c_str()); if(!typ){ typ = module->GetTypeInfoByName(type.c_str()); } if(!typ){ SPRaise("Script type '%s' not found.", type.c_str()); } func = typ->GetMethodByDecl(decl.c_str()); if(!func){ SPRaise("Script method of '%s' with signature '%s' not found.", type.c_str(), decl.c_str()); } } } }
void Run() override { try { std::unique_ptr<CURL, CURLEasyDeleter> cHandle{curl_easy_init()}; if (cHandle) { size_t (*curlWriteCallback)(void *, size_t, size_t, ServerListQuery *) = []( void *ptr, size_t size, size_t nmemb, ServerListQuery *self) -> size_t { size_t numBytes = size * nmemb; self->buffer.append(reinterpret_cast<char *>(ptr), numBytes); return numBytes; }; curl_easy_setopt(cHandle.get(), CURLOPT_USERAGENT, OpenSpades_VER_STR); curl_easy_setopt(cHandle.get(), CURLOPT_URL, cl_serverListUrl.CString()); curl_easy_setopt(cHandle.get(), CURLOPT_WRITEFUNCTION, curlWriteCallback); curl_easy_setopt(cHandle.get(), CURLOPT_WRITEDATA, this); if (0 == curl_easy_perform(cHandle.get())) { ProcessResponse(); } else { SPRaise("HTTP request error."); } } else { SPRaise("Failed to create cURL object."); } } catch (std::exception &ex) { std::unique_ptr<MainScreenServerList> lst{new MainScreenServerList()}; lst->message = ex.what(); ReturnResult(std::move(lst)); } catch (...) { std::unique_ptr<MainScreenServerList> lst{new MainScreenServerList()}; lst->message = "Unknown error."; ReturnResult(std::move(lst)); } }
void DeflateStream::DeflateEnd() { SPADES_MARK_FUNCTION(); if(mode != CompressModeCompress){ SPRaise("DeflareEnd called when decompressing"); } if(!valid){ SPRaise("State is invalid"); } char outputBuffer[chunkSize]; zstream.avail_in = 0; do{ zstream.avail_out = chunkSize; zstream.next_out = (Bytef*)outputBuffer; int ret = deflate(&zstream, Z_FINISH); if(ret == Z_STREAM_ERROR) { valid = false; deflateEnd(&zstream); SPRaise("Error while deflating: %s", zError(ret)); } int got = chunkSize - zstream.avail_out; baseStream->Write(outputBuffer, got); }while(zstream.avail_out == 0); deflateEnd(&zstream); valid = false; }
void DeflateStream::CompressBuffer() { SPADES_MARK_FUNCTION(); SPAssert(mode == CompressModeCompress); char outputBuffer[chunkSize]; if(!valid){ SPRaise("State is invalid"); } zstream.avail_in = (unsigned int) buffer.size(); zstream.next_in = (Bytef*)buffer.data(); do{ zstream.avail_out = chunkSize; zstream.next_out = (Bytef*)outputBuffer; int ret = deflate(&zstream, Z_NO_FLUSH); if(ret == Z_STREAM_ERROR) { valid = false; deflateEnd(&zstream); SPRaise("Error while deflating: %s", zError(ret)); } int got = chunkSize - zstream.avail_out; baseStream->Write(outputBuffer, got); }while(zstream.avail_out == 0); SPAssert(zstream.avail_in == 0); std::vector<char>().swap(buffer); }
Bitmap *Bitmap::Load(IStream *stream) { std::vector<IBitmapCodec *>codecs = IBitmapCodec::GetAllCodecs(); auto pos = stream->GetPosition(); std::string errMsg; for(size_t i = 0; i < codecs.size(); i++) { IBitmapCodec *codec = codecs[i]; if(codec->CanLoad()) { // give it a try. // open error shouldn't be handled here try { stream->SetPosition(pos); return codec->Load(stream); } catch(const std::exception& ex) { errMsg += codec->GetName(); errMsg += ":\n"; errMsg += ex.what(); errMsg += "\n\n"; } } } if(errMsg.empty()) { SPRaise("Bitmap codec not found for stream"); } else { SPRaise("No bitmap codec could load file successfully: [stream]\n%s\n", errMsg.c_str()); } }
Runner::Runner(): m_videoWidth(r_videoWidth), m_videoHeight(r_videoHeight){ if(m_videoWidth < 1 || m_videoWidth > 16384) SPRaise("Value of r_videoWidth is invalid."); if(m_videoHeight < 1 || m_videoHeight > 16384) SPRaise("Value of r_videoHeight is invalid."); }
void MemoryStream::WriteByte(int byte) { SPADES_MARK_FUNCTION(); if(canWrite){ SPRaise("Write prohibited"); } if(position >= length){ SPRaise("Attempted to write beyond the specified memory range."); }else { memory[(size_t)(position++)] = (unsigned char)byte; } }
virtual SDL_Surface *LoadSdlImage(const std::string &data) { StringSdlRWops ops(data); int flags = IMG_INIT_PNG | IMG_INIT_JPG; int initted = IMG_Init(flags); if ((initted & flags) != flags) { SPRaise("IMG_Init failed: %s", IMG_GetError()); } auto *s = IMG_Load_RW(ops, 0); if (s == nullptr) { SPRaise("IMG_Load_RW failed: %s", IMG_GetError()); } return s; }
void MemoryStream::Write(const void *data, size_t bytes) { SPADES_MARK_FUNCTION(); if(canWrite){ SPRaise("Write prohibited"); } if(position + (uint64_t)bytes > length || position + (uint64_t)bytes < position){ // integer overflow check SPRaise("Attempted to write beyond the specified memory range."); }else { memcpy(memory + (size_t)position, data, bytes); } }
void DeflateStream::WriteByte(int byte){ SPADES_MARK_FUNCTION(); if(mode != CompressModeCompress){ SPRaise("Attempted to write when decompressing"); } if(!valid){ SPRaise("State is invalid"); } if(buffer.size() >= bufferSize){ CompressBuffer(); } buffer.push_back((char)byte); }
IModel *GetResult() { if(!error.empty()){ SPRaise("Error while RegisterImageDispatch:\n%s", error.c_str()); }else{ return result; } }
void CheckError(void){ ALenum e; e = qalGetError(); if(e != AL_NO_ERROR) { SPRaise("OpenAL error %d: %s", (int)e, DescribeError(e)); } }
static void *GPA(const char *str) { if(!alLibrary){ auto paths = spades::Split(s_alDriver, ";"); std::string errors; for (const std::string &path: paths) { auto trimmedPath = spades::TrimSpaces(path); try { alLibrary = new spades::DynamicLibrary(trimmedPath.c_str()); if (alLibrary) { SPLog("'%s' loaded", trimmedPath.c_str()); break; } } catch (const std::exception &ex) { errors += trimmedPath; errors += ":\n"; errors += ex.what(); } } if (!alLibrary) { SPRaise("Failed to load a OpenAL driver.\n%s", errors.c_str()); } } if(qalGetProcAddress){ void *v = qalGetProcAddress(str); if(v) return v; } return alLibrary->GetSymbol(str); }
static void RaiseFBStatusError(IGLDevice::Enum status) { std::string type; switch(status){ case IGLDevice::FramebufferComplete: type = "GL_FRAMEBUFFER_COMPLETE"; break; case IGLDevice::FramebufferUndefined: type = "GL_FRAMEBUFFER_UNDEFINED"; break; case IGLDevice::FramebufferIncompleteAttachment: type = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break; case IGLDevice:: FramebufferIncompleteMissingAttachment: type = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break; case IGLDevice:: FramebufferIncompleteDrawBuffer: type = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break; case IGLDevice:: FramebufferIncompleteReadBuffer: type = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break; case IGLDevice:: FramebufferIncompleteMultisample: type = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break; case IGLDevice:: FramebufferIncompleteLayerTargets: type = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; break; default: // IGLDevice::Enum contains values unrelevant to framebuffer status error causing static analyzer to say something type = "Unknown"; } SPRaise("OpenGL Framebuffer completeness check failed: %s", type.c_str()); }
Bitmap *GetResult() { if(!error.empty()){ SPRaise("Error while CreateImageDispatch:\n%s", error.c_str()); }else{ return result; } }
DeflateStream::DeflateStream(IStream *stream, CompressMode mode, bool ac) { SPADES_MARK_FUNCTION(); this->baseStream = stream; this->mode = mode; autoClose = ac; zstream.zalloc = Z_NULL; zstream.zfree = Z_NULL; zstream.opaque = Z_NULL; position = 0; int ret; if(mode == CompressModeCompress) { ret = deflateInit(&zstream, 5); }else if(mode == CompressModeDecompress){ ret = inflateInit(&zstream); }else{ SPInvalidEnum("mode", mode); } if(ret != Z_OK){ SPRaise("Failed to initialize zlib deflator/inflator: %s", zError(ret)); } valid = true; reachedEOF = false; bufferPos = 0; }
void StdStream::WriteByte(int byte) { SPADES_MARK_FUNCTION(); if (fputc(byte, handle) != 0) { SPRaise("I/O error."); } }
void StdStream::Write(const void *buf, size_t bytes) { SPADES_MARK_FUNCTION(); if (fwrite(buf, 1, bytes, handle) < bytes) { SPRaise("I/O error."); } }
void Client::TakeMapShot(){ try{ std::string name = MapShotPath(); { std::unique_ptr<IStream> stream(FileManager::OpenForWriting(name.c_str())); try{ GameMap *map = GetWorld()->GetMap(); if(map == nullptr){ SPRaise("No map loaded"); } map->Save(stream.get()); }catch(...){ throw; } } std::string msg; msg = _Tr("Client", "Map saved: {0}", name); ShowAlert(msg, AlertType::Notice); }catch(const Exception& ex){ std::string msg; msg = _Tr("Client", "Saving map failed: "); msg += ex.GetShortMessage(); ShowAlert(msg, AlertType::Error); SPLog("Saving map failed: %s", ex.what()); }catch(const std::exception& ex){ std::string msg; msg = _Tr("Client", "Saving map failed: "); msg += ex.what(); ShowAlert(msg, AlertType::Error); SPLog("Saving map failed: %s", ex.what()); } }
virtual Bitmap *Load(IStream *stream) { SPADES_MARK_FUNCTION(); // read all std::string data = stream->ReadAllBytes(); auto deleter = [](SDL_Surface *s) { SDL_FreeSurface(s); }; // copy to buffer std::unique_ptr<SDL_Surface, decltype(deleter)> imgraw(LoadSdlImage(data), deleter); if (imgraw == nullptr) { SPRaise("SDL surface was not loaded."); } std::unique_ptr<SDL_Surface, decltype(deleter)> img( SDL_ConvertSurfaceFormat(imgraw.get(), SDL_PIXELFORMAT_ABGR8888, 0), deleter); if (img == nullptr) { SPRaise("SDL surface was loaded, but format conversion failed."); } const unsigned char *inPixels = (const unsigned char *)img->pixels; int width = img->w; int height = img->h; int pitch = img->pitch; Handle<Bitmap> bmp; bmp.Set(new Bitmap(width, height), false); try { unsigned char *outPixels = (unsigned char *)bmp->GetPixels(); if (pitch == width * 4) { // if the pitch matches the requirement of Bitmap, // just use it memcpy(outPixels, inPixels, pitch * height); } else { // convert for (int y = 0; y < height; y++) { memcpy(outPixels, inPixels, width * 4); outPixels += width * 4; inPixels += pitch; } } return bmp.Unmanage(); } catch (...) { throw; } }
GLProgram *GLProgramManager::CreateProgram(const std::string &name) { SPADES_MARK_FUNCTION(); SPLog("Loading GLSL program '%s'", name.c_str()); std::string text = FileManager::ReadAllBytes(name.c_str()); std::vector<std::string> lines = SplitIntoLines(text); GLProgram *p = new GLProgram(device, name); for (size_t i = 0; i < lines.size(); i++) { std::string text = TrimSpaces(lines[i]); if (text.empty()) break; if (text == "*shadow*") { std::vector<GLShader *> shaders = GLShadowShader::RegisterShader(this, settings, false); for (size_t i = 0; i < shaders.size(); i++) p->Attach(shaders[i]); continue; } else if (text == "*shadow-lite*") { std::vector<GLShader *> shaders = GLShadowShader::RegisterShader(this, settings, false, true); for (size_t i = 0; i < shaders.size(); i++) p->Attach(shaders[i]); continue; } else if (text == "*shadow-variance*") { std::vector<GLShader *> shaders = GLShadowShader::RegisterShader(this, settings, true); for (size_t i = 0; i < shaders.size(); i++) p->Attach(shaders[i]); continue; } else if (text == "*dlight*") { std::vector<GLShader *> shaders = GLDynamicLightShader::RegisterShader(this); for (size_t i = 0; i < shaders.size(); i++) p->Attach(shaders[i]); continue; } else if (text == "*shadowmap*") { std::vector<GLShader *> shaders = GLShadowMapShader::RegisterShader(this); for (size_t i = 0; i < shaders.size(); i++) p->Attach(shaders[i]); continue; } else if (text[0] == '*') { SPRaise("Unknown special shader: %s", text.c_str()); } else if (text[0] == '#') { continue; } GLShader *s = CreateShader(text); p->Attach(s); } Stopwatch sw; p->Link(); SPLog("Successfully linked GLSL program '%s' in %.3fms", name.c_str(), sw.GetTime() * 1000.); // p->Validate(); return p; }
void StdStream::SetPosition(uint64_t pos) { SPADES_MARK_FUNCTION(); if (pos > 0x7fffffffULL) { SPRaise("Currently StdStream doesn't support 64-bit offset."); } fseek(handle, (long)pos, SEEK_SET); }
void DeflateStream::Write(const void *data, size_t bytes) { SPADES_MARK_FUNCTION(); if(mode != CompressModeCompress){ SPRaise("Attempted to write when decompressing"); } if(!valid){ SPRaise("State is invalid"); } if(buffer.size() >= bufferSize){ CompressBuffer(); } const char *dt = reinterpret_cast<const char *>(data); buffer.insert(buffer.end(), dt, dt + bytes); }
uint64_t DeflateStream::GetLength() { SPADES_MARK_FUNCTION(); if(mode == CompressModeCompress){ return position; }else{ SPRaise("Cannot retrieve uncompressed data length"); } }
void SDLRunner::Run() { SPADES_MARK_FUNCTION(); SDL_Init(SDL_INIT_VIDEO); try{ { std::string pkg = PACKAGE_STRING; #if !NDEBUG pkg.append( " DEBUG build" ); #endif #ifdef OPENSPADES_COMPILER_STR pkg.append( " " OPENSPADES_COMPILER_STR ); //add compiler to window title #endif SDL_WM_SetCaption(pkg.c_str(), pkg.c_str()); } SDL_Surface *surface; int sdlFlags = SDL_OPENGL | SDL_DOUBLEBUF; if(r_fullscreen) sdlFlags |= SDL_FULLSCREEN; // OpenGL core profile: supported by SDL 1.3 or later //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, r_depthBits); surface = SDL_SetVideoMode(r_videoWidth, r_videoHeight, r_colorBits, sdlFlags); if(!surface){ std::string msg = SDL_GetError(); SPRaise("Failed to initialize video device: %s", msg.c_str()); } SDL_WM_GrabInput(SDL_GRAB_ON); SDL_EnableUNICODE(1); SDL_ShowCursor(0); { SDLGLDevice glDevice(surface); Handle<draw::GLRenderer> renderer(new draw::GLRenderer(&glDevice), false); audio::ALDevice audio; RunClientLoop(renderer, &audio); } }catch(...){ SDL_Quit(); throw; } SDL_Quit(); }
void CheckError(const char *source, const char *fun, int line){ ALenum e; e = qalGetError(); if(e != AL_NO_ERROR) { if(s_alErrorFatal) SPRaise("[%s:%d] : %s : OpenAL error %d: %s", source, line, fun, (int)e, DescribeError(e)); else SPLog("[%s:%d] : %s : OpenAL error %d: %s", source, line, fun, (int)e, DescribeError(e)); } }
Bitmap::Bitmap(uint32_t *pixels, int w, int h): pixels(pixels), w(w), h(h), autoDelete(false) { SPADES_MARK_FUNCTION(); if(w < 1 || h < 1 || w > 8192 || h > 8192) { SPRaise("Invalid dimension: %dx%d", w, h); } SPAssert(pixels != NULL); }
virtual void Save(IStream *stream, Bitmap *bmp){ SPADES_MARK_FUNCTION(); jpge::params params; params.m_quality = core_jpegQuality; if(params.m_quality < 1 || params.m_quality > 100) { SPRaise("Invalid core_jpegQuality"); } OutputStream outStream(stream); jpge::jpeg_encoder encoder; if(!encoder.init(&outStream, bmp->GetWidth(), bmp->GetHeight(), 3, params)) { SPRaise("JPEG encoder initialization failed."); } auto *pixels = bmp->GetPixels(); std::vector<uint8_t> lineBuffer; int w = bmp->GetWidth(); int h = bmp->GetHeight(); lineBuffer.resize(w * 3); for(jpge::uint pass = 0; pass < encoder.get_total_passes(); pass++) { for(int y = 0; y < h; y++) { auto *pix = pixels + (h - 1 - y) * w; for(auto *out = lineBuffer.data(), *end = out + w * 3; out != end;) { auto p = *(pix++); *(out++) = static_cast<uint8_t>(p); *(out++) = static_cast<uint8_t>(p >> 8); *(out++) = static_cast<uint8_t>(p >> 16); } if(!encoder.process_scanline(lineBuffer.data())) { SPRaise("JPEG encoder processing failed."); } } if(!encoder.process_scanline(nullptr)) { SPRaise("JPEG encoder processing failed."); } } encoder.deinit(); }