SafePtr< SurfacePainter > CreateSurfacePainter( LockableSurface *p_surface ) { if (!p_surface) { assert(0); APP_WARNING( Error("No Surface to paint on !!!"), "Creator< SurfacePainter >"); } Surf::Ptr surf_ptr; p_surface->Lock( Surface::COLOR, &surf_ptr ); if (!surf_ptr.ptr) { return 0; } SurfacePainter *painter = 0; __PIXEL_SWITCH( surf_ptr.format, __CreateSpecializedSurfacePainter( p_surface, surf_ptr.ptr, surf_ptr.pitch, pix, painter), pix ); if (!painter) { APP_WARNING( Error("Format %i is not supported", surf_ptr.format), "Creator< SurfacePainter >"); } return painter; }
//------------------------------------------------------------------------------------------------ // Name: initialize // Desc: Sets up the sprite manager for use. This must be called before //------------------------------------------------------------------------------------------------ bool SpriteManager::initialize(LPDIRECT3DDEVICE9 d3dDevice) { // Make sure the sprite renderer doesn't already exist if (APP_WARNING(mySpriteRenderer != 0)("SpriteManager - multiple initialization")) return false; // Create the rendering sprite if (APP_ERROR(FAILED(D3DXCreateSprite(d3dDevice, &mySpriteRenderer)))("Unable to create sprite renderer for GUI")) return false; // Success return true; }
//------------------------------------------------------------------------------------------------ // Name: obtainD3DTexture // Desc: Loads the image denoted by this class using the specified device //------------------------------------------------------------------------------------------------ bool PackImage::obtainD3DTexture(LPDIRECT3DDEVICE9 pd3dDevice, DWORD options, LPDIRECT3DTEXTURE9* ppd3dTexture) const { // Fail without a device or if something is wrong with the output pointer if (!pd3dDevice || !ppd3dTexture) return false; // Get the pack from which to load this image dc::dcTable<ResourcePack>::Element* packElement = ((PackImage*)this)->myResourcePack.getReferencedResource(); if (!packElement) return false; ResourcePack* pack = packElement->getImplementation(); if (!pack) return false; // Obtain the image in the pack dcBuffer buffer; if (APP_ERROR(!pack->openResource(myResourceIndex.getValue(), &buffer)) ("Failed to open image %i in pack file", myResourceIndex)) return false; // Obtain options flags bool managed = (options & D3DTEX_MANAGED) != 0; bool mipmap = (options & D3DTEX_MIPMAP) != 0; bool systemmem = (options & D3DTEX_SYSTEMMEM) != 0; D3DPOOL pool = systemmem ? D3DPOOL_SYSTEMMEM : (managed ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT); // Holds return codes HRESULT hr; // Save a NULL first (just in case something goes wrong) *ppd3dTexture = NULL; // The destination for the texture interface LPDIRECT3DTEXTURE9 pd3dTexture; // Load the texture hr = D3DXCreateTextureFromFileInMemoryEx(pd3dDevice, buffer.getDataPointer(), buffer.getDataSize(), D3DX_DEFAULT, D3DX_DEFAULT, mipmap ? D3DX_DEFAULT : 1, 0, D3DFMT_UNKNOWN, pool, D3DX_DEFAULT, D3DX_FILTER_POINT, 0, NULL, NULL, &pd3dTexture); // TODO: // buffer.destroy(); // If there is a problem, there's not much more we can do if (APP_WARNING(FAILED(hr))("Couldn't load PackImage %i", myResourceIndex)) return false; // Assign the output texture *ppd3dTexture = pd3dTexture; // Success return true; }
//------------------------------------------------------------------------------------------------ // Name: loadPreview // Desc: Generates a preview for this image //------------------------------------------------------------------------------------------------ bool Image::loadPreview(LPDIRECT3DDEVICE9 pd3dDevice, Image::Preview* preview) { // This is a problem if (APP_ERROR(!pd3dDevice || !preview)("Invalid parameter to Image::loadPreview")) return false; // Set the source image preview->image = this; preview->d3dTexture = NULL; // Load the texture if (APP_WARNING(!obtainD3DTexture(pd3dDevice, D3DTEX_MIPMAP|D3DTEX_MANAGED, &preview->d3dTexture)) ("Couldn't load texture for resource %s", getPathString().c_str())) return false; // Successfully loaded the preview return true; }
bool SegmentImage(LPDIRECT3DTEXTURE9 texture, int subimage_width, int subimage_height, int rows, int columns, int selected_index, LPDIRECT3DTEXTURE9* segment) { D3DSURFACE_DESC desc; HRESULT hr = texture->GetLevelDesc(0, &desc); CONFIRM(SUCCEEDED(hr)) else return false; // Locate the source rectangle UINT sii = selected_index; // The sub-image index (sii) UINT sixc = sii % columns; // sub-image x-coordinate UINT siyc = sii / columns; // sub-image y-coordinate RECT sourceRect = { (sixc+0) * subimage_width, (siyc+0) * subimage_height, (sixc+1) * subimage_width, (siyc+1) * subimage_height }; // Create a texture for the sub-image LPDIRECT3DTEXTURE9 subimageTexture = NULL; { LPDIRECT3DDEVICE9 d3d_device; texture->GetDevice(&d3d_device); hr = D3DXCreateTexture(d3d_device, subimage_width, subimage_height, -1, 0, desc.Format, desc.Pool, &subimageTexture); SAFE_RELEASE(d3d_device); // If we can't make this texture, something is wrong, but we can't do much about it if (APP_WARNING(FAILED(hr))("Unable to create sub-image texture")) { return false; } //D3DSURFACE_DESC desc; //subimageTexture->GetLevelDesc(0, &desc); //DEBUG_INFO("creating image: %lu, %lu; actual size: %lu, %lu", // subimage_width, // subimage_height, // desc.Width, // desc.Height); } DWORD format_byte_size = 4; switch (desc.Format) { default: DEBUG_ERROR("Unknown image format"); return false; case D3DFMT_A8R8G8B8: case D3DFMT_X8R8G8B8: format_byte_size = sizeof(D3DCOLOR); break; case D3DFMT_A8P8: case D3DFMT_R5G6B5: case D3DFMT_X1R5G5B5: case D3DFMT_X4R4G4B4: format_byte_size = sizeof(WORD); break; } // Copy the texture D3DLOCKED_RECT sourceLR, destLR; texture->LockRect(0, &sourceLR, &sourceRect, D3DLOCK_READONLY); subimageTexture->LockRect(0, &destLR, NULL, 0); BYTE* sourceBits = (BYTE*)sourceLR.pBits; BYTE* destBits = (BYTE*)destLR.pBits; // Copy each row for (long y = 0; y < subimage_height; ++y) { memcpy(&destBits[destLR.Pitch*y], &sourceBits[sourceLR.Pitch*y], subimage_width*format_byte_size); } // Unlock the source and destination texture->UnlockRect(0); subimageTexture->UnlockRect(0); // Generate mipmaps, if necessary // TODO: this generates an error...why?! //if (mipmap) // subimageTexture->GenerateMipSubLevels(); // Save the sub-image as the output texture *segment = subimageTexture; return true; }
//----[ obtainD3DTexture ]--------------------------------------------------- bool D3DXImage::obtainD3DTexture(LPDIRECT3DDEVICE9 pd3dDevice, LPDIRECT3DTEXTURE9* ppd3dTexture) const { #define D3DTEX_MANAGED 0x01 /* create in managed pool */ #define D3DTEX_MIPMAP 0x02 /* generate a mipmap chain */ #define D3DTEX_SYSTEMMEM 0x04 /* create in system memory; overrides D3DTEX_MANAGED */ DWORD options = D3DTEX_MIPMAP|D3DTEX_MANAGED; // Fail without a device or if something is wrong with the output pointer if (APP_WARNING(!pd3dDevice || !ppd3dTexture)("Invalid parameter to obtainD3DTexture")) return false; // Obtain options flags bool managed = (options & D3DTEX_MANAGED) != 0; bool mipmap = (options & D3DTEX_MIPMAP) != 0; bool systemmem = (options & D3DTEX_SYSTEMMEM) != 0; D3DPOOL pool = systemmem ? D3DPOOL_SYSTEMMEM : (managed ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT); // Holds return codes HRESULT hr; // Save a NULL first (just in case something goes wrong) *ppd3dTexture = NULL; // Determine the color key to use D3DCOLOR d3dColorKey = myColorKey.isEnabled() ? myColorKey.getD3DColor() : 0; // The destination for the texture interface LPDIRECT3DTEXTURE9 pd3dTexture; // Load information about the image D3DXIMAGE_INFO imageInfo; if (APP_WARNING(hr = D3DXGetImageInfoFromFile(mySourceFile.getValue().c_str(), &imageInfo)) ("Failed to get image info from D3DXImage source file %s", mySourceFile.getValue().c_str())) return false; // Get the target image format //D3DFORMAT targetFormat = imageInfo.Format; //// Add at least 1 bit of alpha to whatever format we're in //if (myColorKey.isEnabled()) //{ // switch(imageInfo.Format) // { // // These special formats have lower-BPP alpha formats // case D3DFMT_P8: targetFormat = D3DFMT_A8P8; break; // case D3DFMT_R5G6B5: // case D3DFMT_X1R5G5B5: targetFormat = D3DFMT_A1R5G5B5; break; // case D3DFMT_X4R4G4B4: targetFormat = D3DFMT_A4R4G4B4; break; // // Convert all other formats into standard 32-bit color // default: targetFormat = D3DFMT_A8R8G8B8; break; // } //} // Always load in 32-bit with 8 bit alpha D3DFORMAT targetFormat = D3DFMT_A8R8G8B8; // Load the texture hr = D3DXCreateTextureFromFileEx(pd3dDevice, mySourceFile.getValue().c_str(), D3DX_DEFAULT, D3DX_DEFAULT, mipmap ? D3DX_DEFAULT : 1, 0, targetFormat, pool, D3DX_DEFAULT, D3DX_FILTER_POINT, d3dColorKey, NULL, NULL, &pd3dTexture); // If there is a problem, there's not much more we can do if (APP_WARNING(FAILED(hr))("Couldn't load D3DXImage source file %s", mySourceFile.getValue().c_str())) return false; // Check to see if there is a sub-image if ((mySubImageRows.getValue() > 1) || (mySubImageColumns.getValue() > 1)) { LPDIRECT3DTEXTURE9 segment = NULL; if (SegmentImage(pd3dTexture, imageInfo.Width / mySubImageColumns.getValue(), imageInfo.Height / mySubImageRows.getValue(), mySubImageRows.getValue(), mySubImageColumns.getValue(), mySubImage.getValue(), &segment)) { SAFE_RELEASE(pd3dTexture); pd3dTexture = segment; } else { DEBUG_INFO("Failed to segment image; using entire texture"); } } //// rescale the RGB color channels to be in [0, 128] //DWORD number_of_levels = pd3dTexture->GetLevelCount(); //for (DWORD level = 0; level < number_of_levels; ++level) { // D3DLOCKED_RECT lr; // pd3dTexture->LockRect(level, &lr, NULL, 0); // D3DSURFACE_DESC level_desc; // pd3dTexture->GetLevelDesc(level, &level_desc); // D3DCOLOR* src_bits = (D3DCOLOR*)lr.pBits; // DWORD added_pitch = lr.Pitch / sizeof(D3DCOLOR) - level_desc.Width; // for (int y = 0; y < level_desc.Height; ++y) { // for (int x = 0; x < level_desc.Width; ++x) { // D3DCOLOR c = *src_bits; // c = D3DCOLOR_ARGB((c>>24)&0xFF, // ((c>>16)&0xFF)>>1, // ((c>> 8)&0xFF)>>1, // ((c>> 0)&0xFF)>>1); // *src_bits = c; // ++src_bits; // } // src_bits += added_pitch; // } // pd3dTexture->UnlockRect(level); //} *ppd3dTexture = pd3dTexture; return true; }
//------------------------------------------------------------------------------------------------ // Name: acquireGraphics // Desc: //------------------------------------------------------------------------------------------------ bool EvidyonClient::acquireGraphics() { // Objects used to check for errors and clean up created interfaces if we encounter a problem. Cleanup cleanup; // Create Direct3D d3d_ = Direct3DCreate9(D3D_SDK_VERSION); if (APP_FATAL(!d3d_)("Direct3D version higher than 9.0c not found!")) return false; // Add the Direct3D interface to the cleanup list cleanup.addInterface((IUnknown**)&d3d_ ); // Create a class for the window WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MainWindowMsgProc, 0L, 0L, GetModuleHandle(NULL), LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)), LoadCursor(NULL, IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, STRING_WINDOWCLASS, NULL }; RegisterClassEx(&wc); // Get the windowing flag from the config file bool windowed = config_.getSetting("Graphics", "Fullscreen", 0) != 1; // Generate the device bool createdDevice = createD3DDevice(windowed, REQUIRED_NUMBER_OF_BLEND_MATRICES); // Get rid of the window class UnregisterClass(STRING_WINDOWCLASS, wc.hInstance); // Fail if we couldn't create the device if (APP_FATAL(!createdDevice )("Couldn't initialize the Direct3D device")) return false; // Add the created device to the cleanup list cleanup.addInterface((IUnknown**)&d3d_device_); // Initialize the device APP_ERROR(FAILED(d3d_device_->SetRenderState(D3DRS_ZENABLE, TRUE)))("Couldn't enable the Z-buffer"); APP_WARNING(FAILED(d3d_device_->SetRenderState(D3DRS_AMBIENT, 0xFFFFFFFF)))("Failed to set ambient lighting"); APP_WARNING(FAILED(d3d_device_->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x08)))("Failed to set D3DRS_ALPHAREF"); APP_WARNING(FAILED(d3d_device_->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL)))("Failed to set D3DRS_ALPHAFUNC"); APP_WARNING(FAILED(d3d_device_->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)))("Failed to set D3DRS_SRCBLEND"); APP_WARNING(FAILED(d3d_device_->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA)))("Failed to set D3DRS_DESTBLEND"); //APP_WARNING(FAILED(d3d_device_->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT)))("Failed to set D3DRS_SHADEMODE"); // Clear the cleanup structure so we keep everything that was made cleanup.clear(); // Configure the FPS rate double maximumFPS = config_.getSetting("Graphics", "MaximumFramesPerSecond", 60); if (maximumFPS < 5.0) maximumFPS = 5.0; if (maximumFPS > 60) maximumFPS = 60; myConfiguredFramePeriod = 1.0 / maximumFPS; myNextRenderingTime = dcxWin32Clock::getAccurateSystemTime() + myConfiguredFramePeriod; myTargetFPS = maximumFPS; // Success! return true; }
//------------------------------------------------------------------------------------------------ // Name: acquireGraphics // Desc: Implements a robust algorithm to create the Direct3D device //------------------------------------------------------------------------------------------------ bool EvidyonClient::createD3DDevice(bool windowed, unsigned int requiredNumberOfBlendMatrices) { // Get the main Direct3D object from the display structure IDirect3D9* d3d = d3d_; { // Display the adapter that we are using D3DADAPTER_IDENTIFIER9 identifier; if (!APP_WARNING(FAILED(d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier)))("Failed to get adapter information")) DEBUG_INFO("Using \"%s\"", identifier.Description); } // Set up the structure used to create the Direct3D device. D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); // Initialize some parts of the parameters d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; d3dpp.BackBufferCount = 1; //d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; // Set up the rest of the parameters based on the windowed mode if (windowed) { d3dpp.Windowed = TRUE; d3dpp.BackBufferWidth = config_.getSetting("Graphics", "ResolutionX", 800); d3dpp.BackBufferHeight = config_.getSetting("Graphics", "ResolutionY", 600); d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // Create the application's window RECT rc = { 0, 0, d3dpp.BackBufferWidth, d3dpp.BackBufferHeight }; AdjustWindowRect(&rc, WS_POPUPWINDOW|WS_CAPTION, FALSE); d3dpp.hDeviceWindow = CreateWindow(STRING_WINDOWCLASS, STRING_WINDOWTITLE, WS_POPUPWINDOW|WS_CAPTION|WS_MINIMIZEBOX, 50, 50, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, GetModuleHandle(NULL), NULL); } else { // Get the current display mode (this should always succeed) D3DDISPLAYMODE displayMode; if (APP_ERROR(FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))("Couldn't get current display mode")) return false; // Use the current display mode d3dpp.Windowed = FALSE; d3dpp.BackBufferWidth = config_.getSetting("Graphics", "ResolutionX", (int)displayMode.Width); d3dpp.BackBufferHeight = config_.getSetting("Graphics", "ResolutionY", (int)displayMode.Height); switch (config_.getSetting("Graphics", "ColorDepth", 16)) { default: case 16: d3dpp.BackBufferFormat = D3DFMT_R5G6B5; break; case 15: d3dpp.BackBufferFormat = D3DFMT_X1R5G5B5; break; case 24: d3dpp.BackBufferFormat = D3DFMT_R8G8B8; break; case 32: d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; break; } // Create the application's window d3dpp.hDeviceWindow = CreateWindow(STRING_WINDOWCLASS, STRING_WINDOWTITLE, WS_POPUP, 0, 0, d3dpp.BackBufferWidth, d3dpp.BackBufferHeight, NULL, NULL, GetModuleHandle(NULL), NULL); } // Make sure a window was created if (APP_ERROR(d3dpp.hDeviceWindow == NULL)("Unable to create application window")) { // Try again in windowed mode if this was fullscreen; otherwise, fail if (!windowed) return createD3DDevice(true, requiredNumberOfBlendMatrices); else return false; } // Should we force the rendering into software mode? bool forceSoftwareMode = config_.getSetting("Graphics", "ForceSoftwareRendering", 0) == 1; // Parameters that will be used to create the device bool createHardwareDevice = !forceSoftwareMode; // Use D3DCREATE_HARDWARE_VERTEXPROCESSING; otherwise, D3DCREATE_SOFTWARE_VERTEXPROCESSING bool createPureDevice = false; // Set the D3DCREATE_PUREDEVICE flag. Only valid if createHardwareDevice is true. bool createMixedDevice = false; // Set the D3DCREATE_MIXED_VERTEXPROCESSING flag. Only valid if createHardwareDevice is false. // Get device capabilities so we can determine what kind of device to make D3DCAPS9 devCaps; if (!APP_ERROR(FAILED(d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &devCaps)))("Couldn't get device capibilities")) { // Determine whether or not we can use a pure hardware device createPureDevice = createHardwareDevice && ((devCaps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0); if (APP_WARNING(devCaps.MaxVertexBlendMatrices < 4 || devCaps.MaxVertexBlendMatrixIndex + 1 < requiredNumberOfBlendMatrices) ("This computer's hardware doesn't support indexed blended animation; using software device to compensate")) { createHardwareDevice = false; createMixedDevice = false; //createMixedDevice = true; } } createPureDevice = false; // Build the flags for the device creation procedure DWORD createFlags = createHardwareDevice ? (D3DCREATE_HARDWARE_VERTEXPROCESSING | (createPureDevice ? D3DCREATE_PUREDEVICE : 0)) : (createMixedDevice ? D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING); // Create the Direct3D device here IDirect3DDevice9* d3dDevice; if (APP_ERROR(FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, createFlags, &d3dpp, &d3dDevice)))("Failed to create optimal Direct3D device")) { // Set up the most generic-possible flags and attempt to create again d3dpp.PresentationInterval = 0; createFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; createMixedDevice = false; // Try to create again if (APP_FATAL(FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, createFlags, &d3dpp, &d3dDevice)))("Failed to create fallback Direct3D device")) { // If we were creating in fullscreen mode, try again in windowed mode if (!windowed) { // Kill the window we made DestroyWindow(d3dpp.hDeviceWindow); // Inidicate what's going to happen DEBUG_INFO("Failed to create a fullscreen device; trying windowed mode"); // Try again in windowed mode return createD3DDevice(true, requiredNumberOfBlendMatrices); } } else { // Let the user know that we recovered DEBUG_INFO("Recovered from failure to create optimal D3D device by resorting to fallback settings"); } } // Save the device and parameters as output d3d_device_ = d3dDevice; myMainWindow = d3dpp.hDeviceWindow; myUsingMixedDeviceFlag = createMixedDevice; myUsingSoftwareDeviceFlag = (createFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == D3DCREATE_SOFTWARE_VERTEXPROCESSING; memcpy_s(&d3d_params_, sizeof(d3d_params_), &d3dpp, sizeof(d3dpp)); // Success return true; }
//------------------------------------------------------------------------------------------------ // Name: render // Desc: Draws all of the sprites in this manager to the screen //------------------------------------------------------------------------------------------------ bool SpriteManager::render() { // Whether or not the sprite-rendering segment has been entered. This little flag saves a // lot of state changing when there are no sprites! bool enteredSpriteRendering = false; // Render each of the layers in order for (int layer = 0; layer < (int)LAYER_COUNT; ++layer) { // Make sure that we've entered the rendering phase if (!enteredSpriteRendering && myLayers[layer].size() > 0) { // Set up the sprite for rendering HRESULT hr = mySpriteRenderer->Begin(D3DXSPRITE_ALPHABLEND|D3DXSPRITE_DO_NOT_ADDREF_TEXTURE); if (APP_WARNING(FAILED(hr))("Unable to initialize sprite manager for rendering")) return false; // Successfully initialized rendering enteredSpriteRendering = true; } // Render each of the sprites in this layer for (size_t spriteIndex = 0; spriteIndex < myLayers[layer].size(); ++spriteIndex) { // Get the sprite at this index Sprite* sprite = myLayers[layer].get(spriteIndex); // This pointer is to the transformation matrix that should be used to render the sprite D3DXMATRIX* transform = &sprite->transform; // If this layer has an offset, build the combined transform D3DXMATRIX combinedTransform; if (!D3DXMatrixIsIdentity(&myLayerOffsets[layer])) { // Multiply the matrices D3DXMatrixMultiply(&combinedTransform, &myLayerOffsets[layer], &sprite->transform); // Set the transformation matrix transform = &combinedTransform; } // Set the sprite's transformation matrix APP_WARNING(FAILED(mySpriteRenderer->SetTransform(transform)))("Couldn't set sprite's transform"); // The source image region to use (NULL is everything) RECT* srcRect; // Whether or not we should use a source region if (sprite->srcRegion.right <= sprite->srcRegion.left || sprite->srcRegion.bottom <= sprite->srcRegion.top) srcRect = 0; else srcRect = &sprite->srcRegion; // Render the sprite HRESULT hr = mySpriteRenderer->Draw(sprite->texture, srcRect, NULL, sprite->positionOffset, sprite->color); if (APP_WARNING(FAILED(hr))("Sprite rendering failed!")) break; } } // If we rendered things, the renderer should be closed if (enteredSpriteRendering) mySpriteRenderer->End(); // Success return true; }
bool downloadUpdates( const char* downloadWebsite, const std::list<EvidyonUpdateFile>& filesAndSizes ) { // Hide the combo box, show the progress bar ComboBox_Enable( getDisplayModeCombo(), FALSE ); ShowWindow( getProgressBar(), SW_SHOWDEFAULT ); std::vector<std::pair<std::string,std::string>> tempFilesToLocalFiles; // Initialize the progress bar. All files are scaled to 65535 since the 32-bit range // doesn't seem to be working correctly. Progress_SetRange( getProgressBar(), 0, 65535 ); // Repeat for each of the files for (std::list<EvidyonUpdateFile>::const_iterator p = filesAndSizes.begin(); p != filesAndSizes.end(); ++p) { // Update the display window { // Get the number of bytes char bytes[16]; if( p->file_size > 1000 ) { sprintf_s( bytes, "%lu KB", p->file_size / 1000 ); } else if( p->file_size > 1000000 ) { sprintf_s( bytes, "%lu MB", p->file_size / 1000000 ); } else { sprintf_s( bytes, "%lu bytes", p->file_size ); } std::string text = "Downloading "; text.append( p->file_name ); text.append( " - " ); text.append( bytes ); appendStatusLine( text.c_str() ); } // Get the file's name on the website std::string fileUrl = downloadWebsite; fileUrl.append( p->file_name ); // Get the file's local name std::string fileLocalName = "~"; fileLocalName.append( p->file_name ); // Open the local file HANDLE hDestination; hDestination = CreateFile( fileLocalName.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); CONFIRM( hDestination ) else return false; // Add to the list of local files tempFilesToLocalFiles.push_back( std::pair<std::string,std::string>( fileLocalName, p->file_name ) ); // Download this file dcx::dcxWin32InternetStream reader; if( !reader.open( "EvidyonClient", fileUrl.c_str() ) ) { CloseHandle( hDestination ); return false; } // Reset the progress bar Progress_SetPos( getProgressBar(), 0 ); char buffer[512]; size_t bytesRead = 0; size_t bytes; while( reader.scan( buffer, sizeof(buffer), &bytes ) && !reader.end() ) { // Write this data into the output file DWORD bytesWritten; BOOL success = WriteFile( hDestination, buffer, bytes, &bytesWritten, NULL ); // Exit if the data couldn't be written or the user exited the launcher if( !dcx::dcxWin32StdMessagePump( myMainWindow ) || APP_WARNING( !success || !bytesWritten )( "Couldn't write data to temporary file" ) ) break; // Add to the number of bytes that were read bytesRead += bytes; // Update the progress bar Progress_SetPos( getProgressBar(), (WORD)(((double)bytesRead / (double)p->file_size) * 65535) ); } bool completed = reader.end(); // Get rid of the output file and internet connection reader.close(); CloseHandle( hDestination ); // If we didn't finish the download, fail if( APP_ERROR( !completed )( "Didn't complete download of %s", fileUrl.c_str() ) ) return false; } // Delete original files and copy files over for( std::vector<std::pair<std::string,std::string>>::iterator i = tempFilesToLocalFiles.begin(); i != tempFilesToLocalFiles.end(); ++i ) { // Copy over the existing file if (CopyFile( i->first.c_str(), i->second.c_str(), FALSE )) { // Erase the temporary file DeleteFile( i->first.c_str() ); } } // Max out the bar Progress_SetPos( getProgressBar(), 65535 ); // Success return true; }