//! presents a surface in the client area bool CIrrDeviceSDL::present(video::IImage* surface, void* windowId, core::rect<s32>* srcClip) { SDL_Surface *sdlSurface = SDL_CreateRGBSurfaceFrom( surface->lock(), surface->getDimension().Width, surface->getDimension().Height, surface->getBitsPerPixel(), surface->getPitch(), surface->getRedMask(), surface->getGreenMask(), surface->getBlueMask(), surface->getAlphaMask()); if (!sdlSurface) return false; SDL_SetAlpha(sdlSurface, 0, 0); SDL_SetColorKey(sdlSurface, 0, 0); sdlSurface->format->BitsPerPixel=surface->getBitsPerPixel(); sdlSurface->format->BytesPerPixel=surface->getBytesPerPixel(); if ((surface->getColorFormat()==video::ECF_R8G8B8) || (surface->getColorFormat()==video::ECF_A8R8G8B8)) { sdlSurface->format->Rloss=0; sdlSurface->format->Gloss=0; sdlSurface->format->Bloss=0; sdlSurface->format->Rshift=16; sdlSurface->format->Gshift=8; sdlSurface->format->Bshift=0; if (surface->getColorFormat()==video::ECF_R8G8B8) { sdlSurface->format->Aloss=8; sdlSurface->format->Ashift=32; } else { sdlSurface->format->Aloss=0; sdlSurface->format->Ashift=24; } } else if (surface->getColorFormat()==video::ECF_R5G6B5) { sdlSurface->format->Rloss=3; sdlSurface->format->Gloss=2; sdlSurface->format->Bloss=3; sdlSurface->format->Aloss=8; sdlSurface->format->Rshift=11; sdlSurface->format->Gshift=5; sdlSurface->format->Bshift=0; sdlSurface->format->Ashift=16; } else if (surface->getColorFormat()==video::ECF_A1R5G5B5) { sdlSurface->format->Rloss=3; sdlSurface->format->Gloss=3; sdlSurface->format->Bloss=3; sdlSurface->format->Aloss=7; sdlSurface->format->Rshift=10; sdlSurface->format->Gshift=5; sdlSurface->format->Bshift=0; sdlSurface->format->Ashift=15; } SDL_Surface* scr = (SDL_Surface* )windowId; if (!scr) scr = Screen; if (scr) { if (srcClip) { SDL_Rect sdlsrcClip; sdlsrcClip.x = srcClip->UpperLeftCorner.X; sdlsrcClip.y = srcClip->UpperLeftCorner.Y; sdlsrcClip.w = srcClip->getWidth(); sdlsrcClip.h = srcClip->getHeight(); SDL_BlitSurface(sdlSurface, &sdlsrcClip, scr, NULL); } else SDL_BlitSurface(sdlSurface, NULL, scr, NULL); SDL_Flip(scr); } SDL_FreeSurface(sdlSurface); surface->unlock(); return (scr != 0); }
void CompoundSprite::redraw() const { // TODO OpenGL support if (Image::getLoadAsOpenGL()) { mWidth = at(0)->getWidth(); mHeight = at(0)->getHeight(); mOffsetX = 0; mOffsetY = 0; mNeedsRedraw = false; return; } mWidth = mHeight = mOffsetX = mOffsetY = 0; Sprite *s = NULL; SpriteConstIterator it = begin(), it_end = end(); int posX = 0; int posY = 0; for (it = begin(); it != it_end; ++it) { s = *it; if (s) { updateValues(mWidth, posX, s->getWidth() / 2, s->getWidth() / 2, s->getOffsetX()); updateValues(mHeight, posY, s->getHeight(), 0, s->getOffsetY()); } } if (mWidth == 0 && mHeight == 0) { mNeedsRedraw = false; return; } mOffsetX -= posX; mOffsetY -= posY; #if SDL_BYTEORDER == SDL_BIG_ENDIAN int rmask = 0xff000000; int gmask = 0x00ff0000; int bmask = 0x0000ff00; int amask = 0x000000ff; #else int rmask = 0x000000ff; int gmask = 0x0000ff00; int bmask = 0x00ff0000; int amask = 0xff000000; #endif SDL_Surface *surface = SDL_CreateRGBSurface(SDL_HWSURFACE, mWidth, mHeight, 32, rmask, gmask, bmask, amask); if (!surface) return; Graphics *graphics = new Graphics(); graphics->setBlitMode(Graphics::BLIT_GFX); graphics->setTarget(surface); graphics->_beginDraw(); for (it = begin(), it_end = end(); it != it_end; ++it) { s = *it; if (s) s->draw(graphics, posX - s->getWidth() / 2, posY - s->getHeight()); } // Uncomment to see buffer sizes /*graphics->fillRectangle(gcn::Rectangle(0, 0, 3, 3)); graphics->fillRectangle(gcn::Rectangle(mWidth - 3, 0, 3, 3)); graphics->fillRectangle(gcn::Rectangle(mWidth - 3, mHeight - 3, 3, 3)); graphics->fillRectangle(gcn::Rectangle(0, mHeight - 3, 3, 3));*/ delete graphics; SDL_Surface *surfaceA = SDL_CreateRGBSurface(SDL_HWSURFACE, mWidth, mHeight, 32, rmask, gmask, bmask, amask); SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE); SDL_BlitSurface(surface, NULL, surfaceA, NULL); delete mImage; delete mAlphaImage; mImage = Image::load(surface); SDL_FreeSurface(surface); mAlphaImage = Image::load(surfaceA); SDL_FreeSurface(surfaceA); mNeedsRedraw = false; }
void HUD_Lua_Class::draw_text(FontSpecifier *font, const char *text, float x, float y, float r, float g, float b, float a, float scale) { if (!m_drawing) return; if (!text || !strlen(text)) return; apply_clip(); #ifdef HAVE_OPENGL if (m_opengl) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(x, y + (font->Height * scale), 0); glScalef(scale, scale, 1.0); glColor4f(r, g, b, a); font->OGL_Render(text); glColor4f(1, 1, 1, 1); glPopMatrix(); } else #endif if (m_surface) { SDL_Rect rect; rect.x = static_cast<Sint16>(x) + m_wr.x; rect.y = static_cast<Sint16>(y) + m_wr.y; rect.w = font->TextWidth(text); rect.h = font->LineSpacing; // FIXME: draw_text doesn't support full RGBA transfer for proper scaling, // so draw blended but unscaled text instead #if 0 if (scale < 0.99 || scale > 1.01) { SDL_Surface *s2 = SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, m_surface->format->BitsPerPixel, m_surface->format->Rmask, m_surface->format->Gmask, m_surface->format->Bmask, m_surface->format->Amask); SDL_SetAlpha(s2, SDL_SRCALPHA, 0); font->Info->draw_text(s2, text, strlen(text), 0, font->Height, SDL_MapRGBA(m_surface->format, static_cast<unsigned char>(r * 255), static_cast<unsigned char>(g * 255), static_cast<unsigned char>(b * 255), static_cast<unsigned char>(a * 255)), font->Style); SDL_Rect srcrect; srcrect.x = 0; srcrect.y = 0; srcrect.w = ceilf(rect.w * scale); srcrect.h = ceilf(rect.h * scale); SDL_Surface *s3 = rescale_surface(s2, srcrect.w, srcrect.h); SDL_FreeSurface(s2); rect.w = srcrect.w; rect.h = srcrect.h; SDL_BlitSurface(s3, &srcrect, SDL_GetVideoSurface(), &rect); SDL_FreeSurface(s3); } else #endif { SDL_BlitSurface(SDL_GetVideoSurface(), &rect, m_surface, &rect); font->Info->draw_text(m_surface, text, strlen(text), rect.x, rect.y + font->Height, SDL_MapRGBA(m_surface->format, static_cast<unsigned char>(r * 255), static_cast<unsigned char>(g * 255), static_cast<unsigned char>(b * 255), static_cast<unsigned char>(a * 255)), font->Style); SDL_BlitSurface(m_surface, &rect, SDL_GetVideoSurface(), &rect); } } }
Image *Image::load(SDL_Surface *tmpImage) { #ifdef USE_OPENGL if (mUseOpenGL) { // Flush current error flag. glGetError(); int width = tmpImage->w; int height = tmpImage->h; int realWidth = powerOfTwo(width); int realHeight = powerOfTwo(height); if (realWidth < width || realHeight < height) { logger->log("Warning: image too large, cropping to %dx%d texture!", tmpImage->w, tmpImage->h); } // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); // Determine 32-bit masks based on byte order Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif SDL_Surface *oldImage = tmpImage; tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, 32, rmask, gmask, bmask, amask); if (!tmpImage) { logger->log("Error, image convert failed: out of memory"); return NULL; } SDL_BlitSurface(oldImage, NULL, tmpImage, NULL); GLuint texture; glGenTextures(1, &texture); OpenGLGraphics::bindTexture(mTextureType, texture); if (SDL_MUSTLOCK(tmpImage)) SDL_LockSurface(tmpImage); glTexImage2D(mTextureType, 0, 4, tmpImage->w, tmpImage->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (SDL_MUSTLOCK(tmpImage)) SDL_UnlockSurface(tmpImage); SDL_FreeSurface(tmpImage); GLenum error = glGetError(); if (error) { std::string errmsg = "Unknown error"; switch (error) { case GL_INVALID_ENUM: errmsg = "GL_INVALID_ENUM"; break; case GL_INVALID_VALUE: errmsg = "GL_INVALID_VALUE"; break; case GL_INVALID_OPERATION: errmsg = "GL_INVALID_OPERATION"; break; case GL_STACK_OVERFLOW: errmsg = "GL_STACK_OVERFLOW"; break; case GL_STACK_UNDERFLOW: errmsg = "GL_STACK_UNDERFLOW"; break; case GL_OUT_OF_MEMORY: errmsg = "GL_OUT_OF_MEMORY"; break; } logger->log("Error: Image GL import failed: %s", errmsg.c_str()); return NULL; } return new Image(texture, width, height, realWidth, realHeight); } #endif bool hasAlpha = false; Uint8* imageAlphas = new Uint8[tmpImage->w * tmpImage->h]; if (tmpImage->format->BitsPerPixel == 32) { // Figure out whether the image uses its alpha layer for (int i = 0; i < tmpImage->w * tmpImage->h; ++i) { Uint8 r, g, b, a; SDL_GetRGBA(((Uint32*) tmpImage->pixels)[i], tmpImage->format, &r, &g, &b, &a); imageAlphas[i] = a; if (a != 255) hasAlpha = true; } } SDL_Surface *image; // Convert the surface to the current display format if (hasAlpha) image = SDL_DisplayFormatAlpha(tmpImage); else image = SDL_DisplayFormat(tmpImage); if (!image) { logger->log("Error: Image convert failed."); delete [] imageAlphas; return NULL; } return new Image(image, imageAlphas); }
int RunModeTests(SDL_Surface * screen) { Uint32 then, now; Uint32 frames; float seconds; int i; Uint8 r, g, b; SDL_Surface *bmp, *bmpcc, *tmp; SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } /* First test fills and screen update speed */ printf("Running color fill and fullscreen update test\n"); then = SDL_GetTicks(); frames = 0; for (i = 0; i < 256; ++i) { r = i; g = 0; b = 0; SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b)); SDL_Flip(screen); ++frames; } for (i = 0; i < 256; ++i) { r = 0; g = i; b = 0; SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b)); SDL_Flip(screen); ++frames; } for (i = 0; i < 256; ++i) { r = 0; g = 0; b = i; SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b)); SDL_Flip(screen); ++frames; } now = SDL_GetTicks(); seconds = (float) (now - then) / 1000.0f; if (seconds > 0.0f) { printf("%d fills and flips in %2.2f seconds, %2.2f FPS\n", frames, seconds, (float) frames / seconds); } else { printf("%d fills and flips in zero seconds!n", frames); } /* clear the screen after fill test */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_Flip(screen); while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } /* run the generic blit test */ bmp = SDL_LoadBMP("sample.bmp"); if (!bmp) { printf("Couldn't load sample.bmp: %s\n", SDL_GetError()); return 0; } printf("Running freshly loaded blit test: %dx%d at %d bpp, flags: ", bmp->w, bmp->h, bmp->format->BitsPerPixel); PrintFlags(bmp->flags); printf("\n"); then = SDL_GetTicks(); frames = RunBlitTests(screen, bmp, NUM_BLITS); now = SDL_GetTicks(); seconds = (float) (now - then) / 1000.0f; if (seconds > 0.0f) { printf("%d blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS * frames, frames, seconds, (float) frames / seconds); } else { printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS * frames, frames); } /* clear the screen after blit test */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_Flip(screen); while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } /* run the colorkeyed blit test */ bmpcc = SDL_LoadBMP("sample.bmp"); if (!bmpcc) { printf("Couldn't load sample.bmp: %s\n", SDL_GetError()); return 0; } printf("Running freshly loaded cc blit test: %dx%d at %d bpp, flags: ", bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel); SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *) bmpcc->pixels); PrintFlags(bmpcc->flags); printf("\n"); then = SDL_GetTicks(); frames = RunBlitTests(screen, bmpcc, NUM_BLITS); now = SDL_GetTicks(); seconds = (float) (now - then) / 1000.0f; if (seconds > 0.0f) { printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS * frames, frames, seconds, (float) frames / seconds); } else { printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS * frames, frames); } /* clear the screen after cc blit test */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_Flip(screen); while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } /* run the generic blit test */ tmp = bmp; bmp = SDL_DisplayFormat(bmp); SDL_FreeSurface(tmp); if (!bmp) { printf("Couldn't convert sample.bmp: %s\n", SDL_GetError()); return 0; } printf("Running display format blit test: %dx%d at %d bpp, flags: ", bmp->w, bmp->h, bmp->format->BitsPerPixel); PrintFlags(bmp->flags); printf("\n"); then = SDL_GetTicks(); frames = RunBlitTests(screen, bmp, NUM_BLITS); now = SDL_GetTicks(); seconds = (float) (now - then) / 1000.0f; if (seconds > 0.0f) { printf("%d blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS * frames, frames, seconds, (float) frames / seconds); } else { printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS * frames, frames); } /* clear the screen after blit test */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_Flip(screen); while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } /* run the colorkeyed blit test */ tmp = bmpcc; bmpcc = SDL_DisplayFormat(bmpcc); SDL_FreeSurface(tmp); if (!bmpcc) { printf("Couldn't convert sample.bmp: %s\n", SDL_GetError()); return 0; } printf("Running display format cc blit test: %dx%d at %d bpp, flags: ", bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel); PrintFlags(bmpcc->flags); printf("\n"); then = SDL_GetTicks(); frames = RunBlitTests(screen, bmpcc, NUM_BLITS); now = SDL_GetTicks(); seconds = (float) (now - then) / 1000.0f; if (seconds > 0.0f) { printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS * frames, frames, seconds, (float) frames / seconds); } else { printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS * frames, frames); } /* clear the screen after cc blit test */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_Flip(screen); while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } /* run the alpha blit test only if screen bpp>8 */ if (bmp->format->BitsPerPixel > 8) { SDL_FreeSurface(bmp); bmp = SDL_LoadBMP("sample.bmp"); SDL_SetAlpha(bmp, SDL_SRCALPHA, 85); /* 85 - 33% alpha */ tmp = bmp; bmp = SDL_DisplayFormat(bmp); SDL_FreeSurface(tmp); if (!bmp) { printf("Couldn't convert sample.bmp: %s\n", SDL_GetError()); return 0; } printf ("Running display format alpha blit test: %dx%d at %d bpp, flags: ", bmp->w, bmp->h, bmp->format->BitsPerPixel); PrintFlags(bmp->flags); printf("\n"); then = SDL_GetTicks(); frames = RunBlitTests(screen, bmp, NUM_BLITS); now = SDL_GetTicks(); seconds = (float) (now - then) / 1000.0f; if (seconds > 0.0f) { printf ("%d alpha blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS * frames, frames, seconds, (float) frames / seconds); } else { printf("%d alpha blits / %d updates in zero seconds!\n", NUM_BLITS * frames, frames); } } /* clear the screen after alpha blit test */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_Flip(screen); while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } /* run the cc+alpha blit test only if screen bpp>8 */ if (bmp->format->BitsPerPixel > 8) { SDL_FreeSurface(bmpcc); bmpcc = SDL_LoadBMP("sample.bmp"); SDL_SetAlpha(bmpcc, SDL_SRCALPHA, 85); /* 85 - 33% alpha */ SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *) bmpcc->pixels); tmp = bmpcc; bmpcc = SDL_DisplayFormat(bmpcc); SDL_FreeSurface(tmp); if (!bmpcc) { printf("Couldn't convert sample.bmp: %s\n", SDL_GetError()); return 0; } printf ("Running display format cc+alpha blit test: %dx%d at %d bpp, flags: ", bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel); PrintFlags(bmpcc->flags); printf("\n"); then = SDL_GetTicks(); frames = RunBlitTests(screen, bmpcc, NUM_BLITS); now = SDL_GetTicks(); seconds = (float) (now - then) / 1000.0f; if (seconds > 0.0f) { printf ("%d cc+alpha blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS * frames, frames, seconds, (float) frames / seconds); } else { printf("%d cc+alpha blits / %d updates in zero seconds!\n", NUM_BLITS * frames, frames); } } SDL_FreeSurface(bmpcc); SDL_FreeSurface(bmp); while (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return 0; } return 1; }
void bliterEcran(SDL_Surface *ecran, Portion_Map chunk[][PROFONDEUR_MONDE], Camera camera, int largeurFenetre, int hauteurFenetre) { int memX(0), memY(0); SDL_Surface *caseLumineuse(0); caseLumineuse = SDL_CreateRGBSurface(SDL_HWSURFACE, TAILLE_BLOCK, TAILLE_BLOCK, 32, 0, 0, 0, 0); SDL_FillRect(caseLumineuse, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); for (int x(0); x < LARGEUR_MONDE; x++) // Affichage de la génération à l'écran { for (int y(0); y < PROFONDEUR_MONDE; y++) { for (int a(0); a < LARGEUR_PARTIE_MAP; a++) { for (int b(0); b < PROFONDEUR_PARTIE_MAP; b++) { memX = chunk[x][y].blocs[a][b].positionBloc.x; memY = chunk[x][y].blocs[a][b].positionBloc.y; chunk[x][y].blocs[a][b].positionBloc.x -= camera.posCamX; chunk[x][y].blocs[a][b].positionBloc.y -= camera.posCamY; if ((memX > camera.posCamX - TAILLE_BLOCK) && (memX < (camera.posCamX + largeurFenetre) + TAILLE_BLOCK)) { if ((memY > camera.posCamY - TAILLE_BLOCK) && (memY < (camera.posCamY + hauteurFenetre) + TAILLE_BLOCK)) { if (chunk[x][y].blocs[a][b].luminosite != 0) { if (chunk[x][y].blocs[a][b].type == TERRE) SDL_BlitSurface(surfTerre, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); else if (chunk[x][y].blocs[a][b].type == HERBE) SDL_BlitSurface(surfHerbe, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); else if (chunk[x][y].blocs[a][b].type == PIERRE) SDL_BlitSurface(surfPierre, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); else if (chunk[x][y].blocs[a][b].type == CHARBON) SDL_BlitSurface(surfCharbon, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); else if (chunk[x][y].blocs[a][b].type == FER) SDL_BlitSurface(surfFer, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); else if (chunk[x][y].blocs[a][b].type == BOIS) SDL_BlitSurface(surfBois, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); else if (chunk[x][y].blocs[a][b].type == BOIS_NATUREL) SDL_BlitSurface(surfBoisNaturel, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); else if (chunk[x][y].blocs[a][b].type == FEUILLE) SDL_BlitSurface(surfFeuille, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); if (chunk[x][y].blocs[a][b].casse == 0) {} else if (chunk[x][y].blocs[a][b].casse < chunk[x][y].blocs[a][b].casseMax / 4) { SDL_BlitSurface(casseUn, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); } else if (chunk[x][y].blocs[a][b].casse < (chunk[x][y].blocs[a][b].casseMax / 4) * 2) { SDL_BlitSurface(casseDeux, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); } else if (chunk[x][y].blocs[a][b].casse < (chunk[x][y].blocs[a][b].casseMax / 4) * 3) { SDL_BlitSurface(casseTrois, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); } else if (chunk[x][y].blocs[a][b].casse <= chunk[x][y].blocs[a][b].casseMax) { SDL_BlitSurface(casseQuatre, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); } } if (chunk[x][y].blocs[a][b].type != AIR) { if (chunk[x][y].blocs[a][b].luminosite < 0) { chunk[x][y].blocs[a][b].luminosite = 0; } else if (chunk[x][y].blocs[a][b].luminosite > 15) { chunk[x][y].blocs[a][b].luminosite = 15; } switch (chunk[x][y].blocs[a][b].luminosite) { case 0: SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 1: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 238); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 2: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 221); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 3: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 204); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 4: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 187); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 5: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 170); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 6: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 153); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 7: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 136); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 8: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 119); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 9: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 102); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 10: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 85); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 11: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 68); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 12: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 51); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 13: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 34); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; case 14: SDL_SetAlpha(caseLumineuse, SDL_SRCALPHA, 17); SDL_BlitSurface(caseLumineuse, NULL, ecran, &chunk[x][y].blocs[a][b].positionBloc); break; } } } } chunk[x][y].blocs[a][b].positionBloc.x = memX; chunk[x][y].blocs[a][b].positionBloc.y = memY; } } } } SDL_FreeSurface(caseLumineuse); }
int main(int argc, char *argv[]) { int i, done = 0, flip = 0; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) == 0) { fprintf(stderr, "Failed to init PNG support.\n"); exit(1); } Uint32 flags = SDL_HWSURFACE; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-fullscreen") == 0) { flags |= SDL_FULLSCREEN; SDL_ShowCursor(SDL_DISABLE); } if (strcmp(argv[i], "-doublebuf") == 0) { flags |= SDL_DOUBLEBUF; } if (strcmp(argv[i], "-flip") == 0) { flip = 1; } } SDL_Surface *screen = SDL_SetVideoMode(SCRN_WIDTH, SCRN_HEIGHT, SCRN_DEPTH, flags); if (screen == NULL) { fprintf(stderr, "Failed to set video mode.\n"); exit(1); } SDL_WM_SetCaption(TITLE, *argv); SDL_RWops *rw1 = SDL_RWFromMem(moire1_start, moire1_size); SDL_RWops *rw2 = SDL_RWFromMem(moire2_start, moire2_size); SDL_Surface *surface1 = IMG_LoadTyped_RW(rw1, 1, "png"); SDL_Surface *surface2 = IMG_LoadTyped_RW(rw2, 1, "png"); SDL_SetAlpha(surface1, SDL_RLEACCEL | SDL_SRCALPHA, 0); SDL_SetAlpha(surface2, SDL_RLEACCEL, 0); i = 0; while (!done) { static SDL_Event event; if (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: done = 1; break; case SDL_KEYDOWN: done = event.key.keysym.sym == SDLK_ESCAPE; break; } } else { int ms = SDL_GetTicks(); blit_all(screen, surface1, surface2, SPEED * ms / 1000); SDL_UpdateRect(screen, 0, 0, 0, 0); if (flip) { SDL_Flip(screen); } SDL_Delay(10); } } return 0; }
int HandleServerMessage(tSDL_vnc *vnc) { int i, num_pixels, num_rectangles, num_subrectangles, hx, hy, bx, by, cx, cy, rowindex, bitindex, byteindex; int result, bytes_to_read, bytes_read; tSDL_vnc_serverMessage serverMessage; tSDL_vnc_serverUpdate serverUpdate; tSDL_vnc_serverRectangle serverRectangle; tSDL_vnc_serverColormap serverColormap; tSDL_vnc_serverText serverText; tSDL_vnc_serverCopyrect serverCopyrect; tSDL_vnc_serverRRE serverRRE; tSDL_vnc_serverRREdata serverRREdata; tSDL_vnc_serverCoRRE serverCoRRE; tSDL_vnc_serverCoRREdata serverCoRREdata; tSDL_vnc_serverHextile serverHextile; tSDL_vnc_serverHextileBg serverHextileBg; tSDL_vnc_serverHextileFg serverHextileFg; tSDL_vnc_serverHextileSubrects serverHextileSubrects; tSDL_vnc_serverHextileColored serverHextileColored; tSDL_vnc_serverHextileRect serverHextileRect; unsigned char *target; unsigned int *uitarget; unsigned char *cursormask; SDL_Rect trec, srec; DBMESSAGE ("HandleServerMessage\n"); /* Read message type */ result = Recv(vnc->socket,&serverMessage,1,0); if (result==1) { switch (serverMessage.messagetype) { case 0: DBMESSAGE ("Message: update\n"); result = Recv(vnc->socket,&serverUpdate,3,0); if (result==3) { /* ??? Protocol sais U16, TightVNC server sends U8 */ serverUpdate.rectangles=serverUpdate.rectangles & 0x00ff; DBMESSAGE ("Number of rectangles: %u (%04x)\n",serverUpdate.rectangles,serverUpdate.rectangles); num_rectangles=0; while (num_rectangles<serverUpdate.rectangles) { num_rectangles++; result = Recv(vnc->socket,&serverRectangle,12,0); if (result==12) { serverRectangle.x=swap_16(serverRectangle.x); serverRectangle.y=swap_16(serverRectangle.y); serverRectangle.width=swap_16(serverRectangle.width); serverRectangle.height=swap_16(serverRectangle.height); serverRectangle.encoding=swap_32(serverRectangle.encoding); // DBMESSAGE ("Rectangle %i of %i: @ %u,%u size %u,%u encoding %u\n",num_rectangles,serverUpdate.rectangles,serverRectangle.x,serverRectangle.y,serverRectangle.width,serverRectangle.height,serverRectangle.encoding); /* Sanity check values */ if (serverRectangle.x>vnc->serverFormat.width) { DBMESSAGE("Bad rectangle: x=%u setting to 0\n",serverRectangle.x); serverRectangle.x=0; } if (serverRectangle.y>vnc->serverFormat.height) { DBMESSAGE("Bad rectangle: y=%u setting to 0\n",serverRectangle.y); serverRectangle.y=0; } if ((serverRectangle.width<=0) || (serverRectangle.width>vnc->serverFormat.width)) { DBMESSAGE("Bad rectangle: width=%u setting to 1\n",serverRectangle.width); serverRectangle.width=1; } if ((serverRectangle.height<=0) || (serverRectangle.height>vnc->serverFormat.height)) { DBMESSAGE("Bad rectangle: height=%u setting to 1\n",serverRectangle.height); serverRectangle.height=1; } /* Do we have a scratchbuffer */ if (vnc->scratchbuffer) { /* Check size */ if ( (!(vnc->scratchbuffer->w == serverRectangle.width)) || (!(vnc->scratchbuffer->h == serverRectangle.height)) ) { /* Clean out existing scratchbuffer */ SDL_FreeSurface(vnc->scratchbuffer); vnc->scratchbuffer=NULL; DBMESSAGE ("Deleted existing scratchbuffer.\n"); } } if (!(vnc->scratchbuffer)) { /* Create new scratchbuffer */ vnc->scratchbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,serverRectangle.width,serverRectangle.height,32, vnc->rmask,vnc->gmask,vnc->bmask,0); if (vnc->scratchbuffer) { SDL_SetAlpha(vnc->scratchbuffer,0,0); DBMESSAGE ("Created new scratchbuffer.\n"); } else { DBERROR ("Error creating scratchbuffer.\n"); return 0; } } /* Rectangle Data */ switch (serverRectangle.encoding) { case 0: DBMESSAGE ("RAW encoding.\n"); bytes_to_read = serverRectangle.width*serverRectangle.height*4; result = Recv(vnc->socket,(unsigned char *)vnc->scratchbuffer->pixels,bytes_to_read,0); if (result==bytes_to_read) { DBMESSAGE ("Blitting %i bytes of raw pixel data.\n",bytes_to_read); trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted raw pixel data.\n"); } else { DBERROR ("Error on pixel data. Got %i of %i bytes.\n",result,bytes_to_read); return 0; } break; case 1: DBMESSAGE ("CopyRect encoding.\n"); result = Recv(vnc->socket,&serverCopyrect,4,0); if (result==4) { serverCopyrect.x=swap_16(serverCopyrect.x); serverCopyrect.y=swap_16(serverCopyrect.y); // DBMESSAGE ("Copyrect from %u,%u\n",serverCopyrect.x,serverCopyrect.y); // srec.x=serverCopyrect.x; srec.y=serverCopyrect.y; srec.w=serverRectangle.width; srec.h=serverRectangle.height; trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->framebuffer, &srec, vnc->scratchbuffer, NULL); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted copyrect pixels.\n"); } else { DBERROR ("Error on copyrect data. Got %i of %i bytes.\n",result,4); return 0; } break; case 2: DBMESSAGE ("RRE encoding.\n"); result = Recv(vnc->socket,&serverRRE,8,0); if (result==8) { serverRRE.number=swap_32(serverRRE.number); // DBMESSAGE ("RRE of %u rectangles. Background color 0x%06x\n",serverRRE.number,serverRRE.background); SDL_FillRect(vnc->scratchbuffer, NULL, serverRRE.background); /* Draw subrectangles */ num_subrectangles=0; while (num_subrectangles<serverRRE.number) { num_subrectangles++; result = Recv(vnc->socket,&serverRREdata,12,0); if (result==12) { serverRREdata.x=swap_16(serverRREdata.x); serverRREdata.y=swap_16(serverRREdata.y); serverRREdata.width=swap_16(serverRREdata.width); serverRREdata.height=swap_16(serverRREdata.height); srec.x=serverRREdata.x; srec.y=serverRREdata.y; srec.w=serverRREdata.width; srec.h=serverRREdata.height; SDL_FillRect(vnc->scratchbuffer,&srec,serverRREdata.color); } else { DBERROR ("Error on RRE data. Got %i of %i bytes.\n",result,12); return 0; } } DBMESSAGE ("Drawn %i subrectangles.\n", num_subrectangles); trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted RRE pixels.\n"); } else { DBERROR ("Error on RRE header. Got %i of %i bytes.\n",result,8); return 0; } break; case 4: DBMESSAGE ("CoRRE encoding.\n"); result = Recv(vnc->socket,&serverCoRRE,8,0); if (result==8) { serverCoRRE.number=swap_32(serverCoRRE.number); // DBMESSAGE ("CoRRE of %u rectangles. Background color 0x%06x\n",serverCoRRE.number,serverCoRRE.background); SDL_FillRect(vnc->scratchbuffer, NULL, serverCoRRE.background); /* Draw subrectangles */ num_subrectangles=0; while (num_subrectangles<serverCoRRE.number) { num_subrectangles++; result = Recv(vnc->socket,&serverCoRREdata,8,0); if (result==8) { srec.x=serverCoRREdata.x; srec.y=serverCoRREdata.y; srec.w=serverCoRREdata.width; srec.h=serverCoRREdata.height; SDL_FillRect(vnc->scratchbuffer,&srec,serverCoRREdata.color); } else { DBERROR ("Error on CoRRE data. Got %i of %i bytes.\n",result,8); return 0; } } DBMESSAGE ("Drawn %i subrectangles.\n", num_subrectangles); trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted CoRRE pixels.\n"); } else { DBERROR ("Error on CoRRE header. Got %i of %i bytes.\n",result,8); return 0; } break; case 5: DBMESSAGE ("Hextile encoding.\n"); // if (!(vnc->tilebuffer)) { /* Create new tilebuffer */ vnc->tilebuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,16,16,32, vnc->rmask,vnc->gmask,vnc->bmask,0); if (vnc->tilebuffer) { SDL_SetAlpha(vnc->tilebuffer,0,0); DBMESSAGE ("Created new tilebuffer.\n"); } else { DBERROR ("Error creating tilebuffer.\n"); return 0; } } // /* Iterate over all tiles */ // row loop for (hy=0; hy<serverRectangle.height; hy += 16) { /* Determine height of tile */ if ((hy+16)>serverRectangle.height) { by=serverRectangle.height % 16; } else { by=16; } // column loop for (hx=0; hx<serverRectangle.width; hx += 16) { /* Determine width of tile */ if ((hx+16)>serverRectangle.width) { bx=serverRectangle.width % 16; } else { bx=16; } result = Recv(vnc->socket,&serverHextile,1,0); if (result==1) { if (serverHextile.mode & 1) { /* Read raw data for tile in lines */ bytes_to_read = bx*by*4; if ((bx==16) && (by==16)) { // complete tile result = Recv(vnc->socket,(unsigned char *)vnc->tilebuffer->pixels,bytes_to_read,0); } else { // partial tile result = 0; target=(unsigned char *)vnc->tilebuffer->pixels; rowindex=by; while (rowindex) { result += Recv(vnc->socket,target,bx*4,0); target += 16*4; rowindex--; } } if (result==bytes_to_read) { trec.x=hx; trec.y=hy; trec.w=16; trec.h=16; SDL_BlitSurface(vnc->tilebuffer, NULL, vnc->scratchbuffer, &trec); } else { DBERROR ("Error on pixel data. Got %i of %i bytes.\n",result,bytes_to_read); return 0; } } else { /* no raw data */ if (serverHextile.mode & 2) { /* Read background */ result = Recv(vnc->socket,&serverHextileBg,4,0); if (result==4) { /* All OK */ } else { DBERROR ("Error on Hextile background. Got %i of %i bytes.\n",result,4); return 0; } } SDL_FillRect(vnc->tilebuffer,NULL,serverHextileBg.color); if (serverHextile.mode & 4) { /* Read foreground */ result = Recv(vnc->socket,&serverHextileFg,4,0); if (result==4) { /* All OK */ } else { DBERROR ("Error on Hextile foreground. Got %i of %i bytes.\n",result,4); return 0; } } if (serverHextile.mode & 8) { result = Recv(vnc->socket,&serverHextileSubrects,1,0); if (result==1) { /* All OK */ } else { DBERROR ("Error on Hextile subrects. Got %i of %i bytes.\n",result,1); return 0; } /* Read subrects */ num_subrectangles=0; while (num_subrectangles<serverHextileSubrects.number) { num_subrectangles++; // /* Check color mode */ if (serverHextile.mode & 16) { /* Colored subrect */ result = Recv(vnc->socket,&serverHextileColored,6,0); if (result==6) { /* Render colored subrect */ srec.x=(serverHextileColored.xy >> 4) & 0x0f; srec.y=serverHextileColored.xy & 0x0f; srec.w=((serverHextileColored.wh >> 4) & 0x0f)+1; srec.h=(serverHextileColored.wh & 0x0f)+1; SDL_FillRect(vnc->tilebuffer,&srec,serverHextileColored.color); } else { DBERROR ("Error on Hextile color subrect data. Got %i of %i bytes.\n",result,6); return 0; } } else { /* Non-colored Subrect */ result = Recv(vnc->socket,&serverHextileRect,2,0); if (result==2) { /* Render colored subrect */ srec.x=(serverHextileRect.xy >> 4) & 0x0f; srec.y=serverHextileRect.xy & 0x0f; srec.w=((serverHextileRect.wh >> 4) & 0x0f)+1; srec.h=(serverHextileRect.wh & 0x0f)+1; SDL_FillRect(vnc->tilebuffer,&srec,serverHextileFg.color); } else { DBERROR ("Error on Hextile subrect data. Got %i of %i bytes.\n",result,2); return 0; } } // color mode check } // subrect loop // } // have subrects /* Draw tile */ trec.x=hx; trec.y=hy; trec.w=16; trec.h=16; SDL_BlitSurface(vnc->tilebuffer, NULL, vnc->scratchbuffer, &trec); } // raw data check } else {
void BckgrObj::Draw() { int *map(NULL), *objmap(NULL), height, width, i, j; SDL_Rect pos; height = settings.fieldheight; width = settings.fieldwidth; game.getMaps(&map, &objmap); objcounter = 0; SDL_BlitSurface(mapEl[0].get(), NULL, buf.get(), NULL); //DRAW FIELD for (j=0;j<height;j++) { for (i=0; i<width; i++) { pos.x=i*settings.tilesize; pos.y=j*settings.tilesize; pos.h=20; pos.w=20; if (map[j*width+i]==1 && // horizontal line ( map[j*width+i+1] != 0 || i == width-1 ) && ( map[j*width+i-1] != 0 || i == 0 ) ) { SDL_SetAlpha(mapEl[1].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[1].get(), NULL, buf.get(), &pos ); } else if (map[j*width+i]==1) { // vertical line SDL_SetAlpha(mapElRot[1][0].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapElRot[1][0].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==2 && //ghost door map[j*width+i + 1] != 0 && map[j*width+i - 1] != 0) { SDL_SetAlpha(mapEl[2].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[2].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==2) { // vertical ghost door SDL_SetAlpha(mapElRot[2][0].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapElRot[2][0].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==3) { //upper left corner SDL_SetAlpha(mapEl[3].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[3].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==4) { // upper right corner SDL_SetAlpha(mapEl[4].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[4].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==5) { // lower right corner SDL_SetAlpha(mapEl[5].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[5].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==6) { // lower left corner SDL_SetAlpha(mapEl[6].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[6].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==7 && // left T ( map[j*width+i-1]==0 || i == 0 ) ) { SDL_SetAlpha(mapEl[7].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[7].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==7) { // upside down T SDL_SetAlpha(mapElRot[7][0].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapElRot[7][0].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==8 && // right T ( map[j*width+i+1]==0 || i == width-1 ) ) { SDL_SetAlpha(mapEl[8].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[8].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==8) { // upright T SDL_SetAlpha(mapElRot[8][0].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapElRot[8][0].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==9 && map[j*width+i-1] != 0 && map[j*width+i-1] != 2 && i > 0 ) {//right stub SDL_SetAlpha(mapEl[9].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapEl[9].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==9 && map[j*width+i+1] != 0 && map[j*width+i+1] != 2 && i < width-1) { // left stub SDL_SetAlpha(mapElRot[9][1].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapElRot[9][1].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==9 && map[(j+1)*width+i] != 0 && map[(j+1)*width+i] != 2 && j < height -1) { // upper stub SDL_SetAlpha(mapElRot[9][0].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapElRot[9][0].get(), NULL, buf.get(), &pos); } else if (map[j*width+i]==9) {// lower stub SDL_SetAlpha(mapElRot[9][2].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(mapElRot[9][2].get(), NULL, buf.get(), &pos); } } } //DRAW OBJECTS for (j=0;j<height;j++) { for (i=0; i<width; i++) { pos.x=i*settings.tilesize+10; // +10 are needed for correct placement pos.y=j*settings.tilesize+10; pos.h=20; pos.w=20; if (objmap[j*width+i]==1) { SDL_SetAlpha(objEl[1].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(objEl[1].get(), NULL, buf.get(), &pos); objcounter++; } if (objmap[j*width+i]==2) { // BIG DOTS! SDL_SetAlpha(objEl[2].get(),SDL_SRCALPHA|SDL_RLEACCEL,alpha); SDL_BlitSurface(objEl[2].get(), NULL, buf.get(), &pos); objcounter++; } if (objmap[j*width+i]==3 && specialspawned && !specialeaten) { // fruit SDL_SetAlpha(objEl[3].get(),SDL_SRCALPHA,fruitalpha); SDL_BlitSurface(objEl[3].get(), NULL, buf.get(), &pos); objcounter++; } } } }
struct isoactor *isoactor_create(int w, int h, const char *sprite_filename, int ctw, int cth, int cw, int ch, const char *c_sprite_filename) { struct isoactor *actor; Uint32 colourkey; int max_size, xpad, ypad; int images_wide, images_high, hindex, windex, index; SDL_Surface *sprite, *image; SDL_Rect dst, src; if((actor = malloc(sizeof(*actor))) == NULL) { fprintf(stderr, "Error allocating memory for actor.\n"); exit(1); } actor->x = actor->y = actor->px = actor->py = 0; actor->vx = actor->vy = actor->ax = actor->ay = 0; actor->w = w; actor->h = h; actor->p2w = mkp2(w); actor->p2h = mkp2(h); actor->number_of_sprites = 0; /* Check sprite size doesn't exceed openGL's maximum texture size */ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); if(actor->p2w > max_size || actor->p2h > max_size) { fprintf(stderr, "Image size (%d, %d) exceeds " "maximum texture size (%d)\n", actor->p2w, actor->p2h, max_size); return NULL; } /* Load the image file that will contain the sprites */ image = IMG_Load(sprite_filename); if(!image) { fprintf(stderr, "Error! Could not load %s\n", sprite_filename); return NULL; } /* Make SDL copy the alpha channel of the image */ SDL_SetAlpha(image, 0, SDL_ALPHA_OPAQUE); colourkey = SDL_MapRGBA(image->format, 0xff, 0x00, 0xff, 0); xpad = (actor->p2w - actor->w)/2; ypad = (actor->p2h - actor->h)/2; sprite = SDL_CreateRGBSurface(SDL_SWSURFACE, actor->p2w, actor->p2h, 32, RMASK, GMASK, BMASK, AMASK); if(!sprite) { fprintf(stderr, "Error creating a surface for the sprites\n"); isoactor_free(actor); return NULL; } dst.x = xpad; dst.y = ypad; dst.w = actor->w; dst.h = actor->h; src.w = actor->w; src.h = actor->h; src.x = 0; src.y = 0; /* Calculate how many sprite images are contained on the * surface we have been given */ images_wide = (int)(image->w/actor->w); images_high = (int)(image->h/actor->h); actor->number_of_sprites = images_wide * images_high; actor->show_sprite = 0; for(hindex = 0; hindex < images_high; hindex++) { for(windex = 0; windex < images_wide; windex++) { index = windex + hindex * images_wide; #ifdef DEBUG_MODE fprintf(stderr, "loading sprite index %d, ", index); #endif SDL_FillRect(sprite, NULL, colourkey); SDL_SetColorKey(image, SDL_SRCCOLORKEY, colourkey); SDL_BlitSurface(image, &src, sprite, &dst); /* Create an openGL texture and bind the sprite's image to it */ glGenTextures(1, &(actor->textures[index])); glBindTexture(GL_TEXTURE_2D, actor->textures[index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, actor->p2w, actor->p2h, 0, GL_RGBA, GL_UNSIGNED_BYTE, sprite->pixels); src.x += actor->w; } src.x = 0; src.y += actor->h; } #ifdef DEBUG_MODE fprintf(stderr, "\n"); #endif actor->cw = cw; actor->ch = ch; actor->cth = cth; actor->ctw = ctw; int i; for(i = 0; i < MAX_SPRITES; i++) { actor->cfields[i] = NULL; } isoactor_load_cfields(actor, ctw, cth, c_sprite_filename); SDL_FreeSurface(image); SDL_FreeSurface(sprite); for(i = 0; i < MAX_MAPS; i++) { actor->map_handlers[i] = NULL; actor->actor_handlers[i] = NULL; actor->collision_groups[i] = 0; } actor->i_handler = NULL; return actor; }
void* SDLImageLoader::finalize() { if (mCurrentImage == NULL) { throw GCN_EXCEPTION("No image prepared."); } int i; bool hasPink = false; bool hasAlpha = false; for (i = 0; i < mCurrentImage->w * mCurrentImage->h; ++i) { if (((unsigned int*)mCurrentImage->pixels)[i] == SDL_MapRGB(mCurrentImage->format,255,0,255)) { hasPink = true; break; } } for (i = 0; i < mCurrentImage->w * mCurrentImage->h; ++i) { Uint8 r, g, b, a; SDL_GetRGBA(((unsigned int*)mCurrentImage->pixels)[i], mCurrentImage->format, &r, &g, &b, &a); if (a != 255) { hasAlpha = true; break; } } // Don't convert 32bpp images with alpha, it will destroy the // alpha channel. SDL_Surface *temp; if (hasAlpha) { temp = mCurrentImage; mCurrentImage = NULL; } else { temp = SDL_DisplayFormat(mCurrentImage); SDL_FreeSurface(mCurrentImage); mCurrentImage = NULL; } if (hasPink) { SDL_SetColorKey(temp, SDL_SRCCOLORKEY, SDL_MapRGB(temp->format,255,0,255)); } if (hasAlpha) { SDL_SetAlpha(temp, SDL_SRCALPHA, 255); } return temp; }
GLTexture::GLTexture(SDL_Surface* image) : handle(), texture_width(), texture_height(), image_width(), image_height() { #ifdef GL_VERSION_ES_CM_1_0 texture_width = next_power_of_two(image->w); texture_height = next_power_of_two(image->h); #else if (GLEW_ARB_texture_non_power_of_two) { texture_width = image->w; texture_height = image->h; } else { texture_width = next_power_of_two(image->w); texture_height = next_power_of_two(image->h); } #endif image_width = image->w; image_height = image->h; #if SDL_BYTEORDER == SDL_BIG_ENDIAN SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE, texture_width, texture_height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); #else SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE, texture_width, texture_height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); #endif if(convert == 0) { throw std::runtime_error("Couldn't create texture: out of memory"); } SDL_SetAlpha(image, 0, 0); SDL_BlitSurface(image, 0, convert, 0); assert_gl("before creating texture"); glGenTextures(1, &handle); try { GLenum sdl_format; if(convert->format->BytesPerPixel == 3) sdl_format = GL_RGB; else if(convert->format->BytesPerPixel == 4) sdl_format = GL_RGBA; else { sdl_format = GL_RGBA; assert(false); } glBindTexture(GL_TEXTURE_2D, handle); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #ifdef GL_UNPACK_ROW_LENGTH glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel); #else /* OpenGL ES doesn't support UNPACK_ROW_LENGTH, let's hope SDL didn't add * padding bytes, otherwise we need some extra code here... */ assert(convert->pitch == texture_width * convert->format->BytesPerPixel); #endif if(SDL_MUSTLOCK(convert)) { SDL_LockSurface(convert); } if (true) { // no not use mipmaps glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, texture_height, 0, sdl_format, GL_UNSIGNED_BYTE, convert->pixels); } else { // build mipmaps gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texture_width, texture_height, sdl_format, GL_UNSIGNED_BYTE, convert->pixels); } if(SDL_MUSTLOCK(convert)) { SDL_UnlockSurface(convert); } assert_gl("creating texture"); set_texture_params(); } catch(...) { glDeleteTextures(1, &handle); SDL_FreeSurface(convert); throw; } SDL_FreeSurface(convert); }
void Game::intro() { Mix_Chunk *s_expl = loadSound(S_FLASH1); SDL_Surface *fade_white = graphics->copySurface(screen, false); SDL_FillRect(fade_white, NULL, 0x00FFFFFF); float m = -479.0/160.0; int vx = 20; int x1 = (int) (SCREEN_HEIGHT/m); int y1 = SCREEN_HEIGHT; int x2 = (int) (-SCREEN_HEIGHT/m); int y2 = -SCREEN_HEIGHT; bool exit = false; bool flash = true; bool flash_sound = true; playSound(balls[0]->data->s_start); while(!exit) { control->updateState(); if (control->isPressed(KEY_BACK) || control->isPressed(KEY_OK)) exit = true; SDL_FillRect(screen, NULL, 0x00000000); graphics->apply_surface(x1, y1, players[0]->title, screen); graphics->apply_surface(x2, y2, players[1]->title, screen); if (x1 != x2) { x1 += vx; x2 -= vx; y1 = (int) roundf(m*x1); y2 = (int) roundf(m*x2); } else { if (flash) { if (flash_sound) { playSound(s_expl); flash_sound = false; } graphics->apply_surface(0, 0, fade_white, screen); SDL_SetAlpha(fade_white, SDL_SRCALPHA, fade_white->format->alpha-5); flash = (fade_white->format->alpha > 0); } if (!Mix_Playing(-1)) exit = true; } framerate->tic(); graphics->refresh_whole_screen(); framerate->delay(); } Mix_FadeOutChannel(-1, 500); }
void GL_InitTexture(int _srcWidth, int _srcHeight) { srcWidth = _srcWidth; srcHeight = _srcHeight; //delete it if we already have one if ( texture ) { glDeleteTextures( 1, &texture ); texture = 0; } if ( controller_tex ) { glDeleteTextures( 1, &controller_tex ); controller_tex = 0; } glGenTextures(1, &texture); checkError(); glBindTexture(GL_TEXTURE_2D, texture); checkError(); //sanity check int num; glGetIntegerv( GL_TEXTURE_BINDING_2D, &num ); assert( num == texture ); glGetIntegerv( GL_ACTIVE_TEXTURE, &num ); assert( num == GL_TEXTURE0 ); checkError(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter ); checkError(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter ); checkError(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); checkError(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); checkError(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, srcWidth, srcHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL ); checkError(); if( !skin ) { printf( "No skins found! Running without one...\n" ); return; } //Load controller SDL_Surface * initial_surface = IMG_Load( skin->image_path ); if ( !initial_surface ) { printf( "No controller image found! Running without one...\n" ); return; } //Make sure the surface is the right format... SDL_Surface * controller_surface = SDL_CreateRGBSurface( SDL_SWSURFACE, initial_surface->w, initial_surface->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); SDL_SetAlpha(initial_surface, 0, 0); SDL_BlitSurface( initial_surface, NULL, controller_surface, NULL ); glGenTextures(1, &controller_tex ); glBindTexture( GL_TEXTURE_2D, controller_tex ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter ); checkError(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter ); checkError(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); checkError(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); checkError(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, controller_surface->w, controller_surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, controller_surface->pixels ); checkError(); SDL_FreeSurface( initial_surface ); SDL_FreeSurface( controller_surface ); }
int IMG_SavePNG_RW(SDL_RWops *src, SDL_Surface *surf,int compression){ png_structp png_ptr; png_infop info_ptr; SDL_PixelFormat *fmt=NULL; SDL_Surface *tempsurf=NULL; int ret,funky_format,used_alpha; unsigned int i,temp_alpha; png_colorp palette; Uint8 *palette_alpha=NULL; png_byte **row_pointers=NULL; png_ptr=NULL;info_ptr=NULL;palette=NULL;ret=-1; funky_format=0; if( !src || !surf) { goto savedone; /* Nothing to do. */ } row_pointers=(png_byte **)malloc(surf->h * sizeof(png_byte*)); if (!row_pointers) { SDL_SetError("Couldn't allocate memory for rowpointers"); goto savedone; } png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (!png_ptr){ SDL_SetError("Couldn't allocate memory for PNG file"); goto savedone; } info_ptr= png_create_info_struct(png_ptr); if (!info_ptr){ SDL_SetError("Couldn't allocate image information for PNG file"); goto savedone; } /* setup custom writer functions */ png_set_write_fn(png_ptr,(voidp)src,png_write_data,NULL); if (setjmp(png_jmpbuf(png_ptr))){ SDL_SetError("Unknown error writing PNG"); goto savedone; } if(compression>Z_BEST_COMPRESSION) compression=Z_BEST_COMPRESSION; if(compression == Z_NO_COMPRESSION) // No compression { png_set_filter(png_ptr,0,PNG_FILTER_NONE); png_set_compression_level(png_ptr,Z_NO_COMPRESSION); } else if(compression<0) // Default compression png_set_compression_level(png_ptr,Z_DEFAULT_COMPRESSION); else png_set_compression_level(png_ptr,compression); fmt=surf->format; if(fmt->BitsPerPixel==8){ /* Paletted */ png_set_IHDR(png_ptr,info_ptr, surf->w,surf->h,8,PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); palette=(png_colorp) malloc(fmt->palette->ncolors * sizeof(png_color)); if (!palette) { SDL_SetError("Couldn't create memory for palette"); goto savedone; } for (i=0;i<fmt->palette->ncolors;i++) { palette[i].red=fmt->palette->colors[i].r; palette[i].green=fmt->palette->colors[i].g; palette[i].blue=fmt->palette->colors[i].b; } png_set_PLTE(png_ptr,info_ptr,palette,fmt->palette->ncolors); if (surf->flags&SDL_SRCCOLORKEY) { palette_alpha=(Uint8 *)malloc((fmt->colorkey+1)*sizeof(Uint8)); if (!palette_alpha) { SDL_SetError("Couldn't create memory for palette transparency"); goto savedone; } /* FIXME: memset? */ for (i=0;i<(fmt->colorkey+1);i++) { palette_alpha[i]=255; } palette_alpha[fmt->colorkey]=0; png_set_tRNS(png_ptr,info_ptr,palette_alpha,fmt->colorkey+1,NULL); } }else{ /* Truecolor */ if (fmt->Amask) { png_set_IHDR(png_ptr,info_ptr, surf->w,surf->h,8,PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); } else { png_set_IHDR(png_ptr,info_ptr, surf->w,surf->h,8,PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); } } png_write_info(png_ptr, info_ptr); if (fmt->BitsPerPixel==8) { /* Paletted */ for(i=0;i<surf->h;i++){ row_pointers[i]= ((png_byte*)surf->pixels) + i*surf->pitch; } if(SDL_MUSTLOCK(surf)){ SDL_LockSurface(surf); } png_write_image(png_ptr, row_pointers); if(SDL_MUSTLOCK(surf)){ SDL_UnlockSurface(surf); } }else{ /* Truecolor */ if(fmt->BytesPerPixel==3){ if(fmt->Amask){ /* check for 24 bit with alpha */ funky_format=1; }else{ /* Check for RGB/BGR/GBR/RBG/etc surfaces.*/ #if SDL_BYTEORDER == SDL_BIG_ENDIAN if(fmt->Rmask!=0xFF0000 || fmt->Gmask!=0x00FF00 || fmt->Bmask!=0x0000FF){ #else if(fmt->Rmask!=0x0000FF || fmt->Gmask!=0x00FF00 || fmt->Bmask!=0xFF0000){ #endif funky_format=1; } } }else if (fmt->BytesPerPixel==4){ if (!fmt->Amask) { /* check for 32bit but no alpha */ funky_format=1; }else{ /* Check for ARGB/ABGR/GBAR/RABG/etc surfaces.*/ #if SDL_BYTEORDER == SDL_BIG_ENDIAN if(fmt->Rmask!=0xFF000000 || fmt->Gmask!=0x00FF0000 || fmt->Bmask!=0x0000FF00 || fmt->Amask!=0x000000FF){ #else if(fmt->Rmask!=0x000000FF || fmt->Gmask!=0x0000FF00 || fmt->Bmask!=0x00FF0000 || fmt->Amask!=0xFF000000){ #endif funky_format=1; } } }else{ /* 555 or 565 16 bit color */ funky_format=1; } if (funky_format) { /* Allocate non-funky format, and copy pixeldata in*/ if(fmt->Amask){ #if SDL_BYTEORDER == SDL_BIG_ENDIAN tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); #else tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); #endif }else{ #if SDL_BYTEORDER == SDL_BIG_ENDIAN tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x00000000); #else tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000); #endif } if(!tempsurf){ SDL_SetError("Couldn't allocate temp surface"); goto savedone; } if(surf->flags&SDL_SRCALPHA){ temp_alpha=fmt->alpha; used_alpha=1; SDL_SetAlpha(surf,0,255); /* Set for an opaque blit */ }else{ used_alpha=0; } if(SDL_BlitSurface(surf,NULL,tempsurf,NULL)!=0){ SDL_SetError("Couldn't blit surface to temp surface"); SDL_FreeSurface(tempsurf); goto savedone; } if (used_alpha) { SDL_SetAlpha(surf,SDL_SRCALPHA,(Uint8)temp_alpha); /* Restore alpha settings*/ } for(i=0;i<tempsurf->h;i++){ row_pointers[i]= ((png_byte*)tempsurf->pixels) + i*tempsurf->pitch; } if(SDL_MUSTLOCK(tempsurf)){ SDL_LockSurface(tempsurf); } png_write_image(png_ptr, row_pointers); if(SDL_MUSTLOCK(tempsurf)){ SDL_UnlockSurface(tempsurf); } SDL_FreeSurface(tempsurf); } else { for(i=0;i<surf->h;i++){ row_pointers[i]= ((png_byte*)surf->pixels) + i*surf->pitch; } if(SDL_MUSTLOCK(surf)){ SDL_LockSurface(surf); } png_write_image(png_ptr, row_pointers); if(SDL_MUSTLOCK(surf)){ SDL_UnlockSurface(surf); } } } png_write_end(png_ptr, NULL); ret=0; /* got here, so nothing went wrong. YAY! */ savedone: /* clean up and return */ png_destroy_write_struct(&png_ptr,&info_ptr); if (palette) { free(palette); } if (palette_alpha) { free(palette_alpha); } if (row_pointers) { free(row_pointers); } return ret; }
void DINGUXSdlGraphicsManager::internUpdateScreen() { SDL_Surface *srcSurf, *origSurf; int height, width; ScalerProc *scalerProc; int scale1; #if defined(DEBUG) && ! defined(_WIN32_WCE) // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?) assert(_hwscreen != NULL); assert(_hwscreen->map->sw_data != NULL); #endif // If the shake position changed, fill the dirty area with blackness if (_currentShakePos != _newShakePos) { SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor}; if (_videoMode.aspectRatioCorrection && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwscreen, &blackrect, 0); _currentShakePos = _newShakePos; _forceFull = true; } // Check whether the palette was changed in the meantime and update the // screen surface accordingly. if (_screen && _paletteDirtyEnd != 0) { SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart); _paletteDirtyEnd = 0; _forceFull = true; } #ifdef USE_OSD // OSD visible (i.e. non-transparent)? if (_osdAlpha != SDL_ALPHA_TRANSPARENT) { // Updated alpha value const int diff = SDL_GetTicks() - _osdFadeStartTime; if (diff > 0) { if (diff >= kOSDFadeOutDuration) { // Back to full transparency _osdAlpha = SDL_ALPHA_TRANSPARENT; } else { // Do a linear fade out... const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100; _osdAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration; } SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha); _forceFull = true; } } #endif if (!_overlayVisible) { origSurf = _screen; srcSurf = _tmpscreen; width = _videoMode.screenWidth; height = _videoMode.screenHeight; scalerProc = _scalerProc; scale1 = _videoMode.scaleFactor; } else { origSurf = _overlayscreen; srcSurf = _tmpscreen2; width = _videoMode.overlayWidth; height = _videoMode.overlayHeight; scalerProc = Normal1x; scale1 = 1; } // Add the area covered by the mouse cursor to the list of dirty rects if // we have to redraw the mouse. if (_mouseNeedsRedraw) undrawMouse(); // Force a full redraw if requested if (_forceFull) { _numDirtyRects = 1; _dirtyRectList[0].x = 0; _dirtyRectList[0].y = 0; _dirtyRectList[0].w = width; _dirtyRectList[0].h = height; } // Only draw anything if necessary if (_numDirtyRects > 0 || _mouseNeedsRedraw) { SDL_Rect *r; SDL_Rect dst; uint32 srcPitch, dstPitch; SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects; for (r = _dirtyRectList; r != lastRect; ++r) { dst = *r; dst.x++; // Shift rect by one since 2xSai needs to access the data around dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); } SDL_LockSurface(srcSurf); SDL_LockSurface(_hwscreen); srcPitch = srcSurf->pitch; dstPitch = _hwscreen->pitch; for (r = _dirtyRectList; r != lastRect; ++r) { register int dst_y = r->y + _currentShakePos; register int dst_h = 0; register int dst_w = r->w; register int orig_dst_y = 0; register int dst_x = r->x; register int src_y; register int src_x; if (dst_y < height) { dst_h = r->h; if (dst_h > height - dst_y) dst_h = height - dst_y; orig_dst_y = dst_y; src_x = dst_x; src_y = dst_y; if (_videoMode.aspectRatioCorrection && !_overlayVisible) dst_y = real2Aspect(dst_y); assert(scalerProc != NULL); if ((_videoMode.mode == GFX_HALF) && (scalerProc == DownscaleAllByHalf)) { if (dst_x % 2 == 1) { dst_x--; dst_w++; } if (dst_y % 2 == 1) { dst_y--; dst_h++; } src_x = dst_x; src_y = dst_y; dst_x = dst_x / 2; dst_y = dst_y / 2; scalerProc((byte *)srcSurf->pixels + (src_x * 2 + 2) + (src_y + 1) * srcPitch, srcPitch, (byte *)_hwscreen->pixels + dst_x * 2 + dst_y * dstPitch, dstPitch, dst_w, dst_h); } else { scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, (byte *)_hwscreen->pixels + r->x * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h); } } if (_videoMode.mode == GFX_HALF && scalerProc == DownscaleAllByHalf) { r->w = r->w / 2; r->h = dst_h / 2; } else { r->w = r->w; r->h = dst_h; } r->x = dst_x; r->y = dst_y; #ifdef USE_SCALERS if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible) r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); #endif } SDL_UnlockSurface(srcSurf); SDL_UnlockSurface(_hwscreen); // Readjust the dirty rect list in case we are doing a full update. // This is necessary if shaking is active. if (_forceFull) { _dirtyRectList[0].y = 0; _dirtyRectList[0].h = (_videoMode.mode == GFX_HALF) ? effectiveScreenHeight() / 2 : effectiveScreenHeight(); } drawMouse(); #ifdef USE_OSD if (_osdAlpha != SDL_ALPHA_TRANSPARENT) { SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0); } #endif // Finally, blit all our changes to the screen SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); } _numDirtyRects = 0; _forceFull = false; _mouseNeedsRedraw = false; }
void ezioEmulator::CreateSurfaces(void) { // Define the colours we'll use bg.r = 73; bg.g = 84; bg.b = 149; bg_chr.r = 84; bg_chr.g = 97; bg_chr.b = 172; fg_chr.r = 250; fg_chr.g = 250; fg_chr.b = 255; // Create panel, pixel, and character surfaces lcd_panel = SDL_CreateRGBSurface(SDL_SWSURFACE, px_lcd_width, px_lcd_height, 32, rmask, gmask, bmask, amask); pixel_on = SDL_CreateRGBSurface(SDL_SWSURFACE, px_size / 2, px_size / 2, 32, rmask, gmask, bmask, amask); pixel_off = SDL_CreateRGBSurface(SDL_SWSURFACE, px_size / 2, px_size / 2, 32, rmask, gmask, bmask, amask); chr_on = SDL_CreateRGBSurface(SDL_SWSURFACE, px_chr_width, px_chr_height, 32, rmask, gmask, bmask, amask); chr_off = SDL_CreateRGBSurface(SDL_SWSURFACE, px_chr_width, px_chr_height, 32, rmask, gmask, bmask, amask); chr_uscore = SDL_CreateRGBSurface(SDL_SWSURFACE, px_chr_width, px_size / 2, 32, rmask, gmask, bmask, amask); SDL_SetAlpha(lcd_panel, 0, 0); SDL_SetAlpha(pixel_on, 0, 0); SDL_SetAlpha(pixel_off, 0, 0); SDL_SetAlpha(chr_on, 0, 0); SDL_SetAlpha(chr_off, 0, 0); SDL_SetAlpha(chr_uscore, 0, 0); SDL_FillRect(lcd_panel, NULL, SDL_MapRGB(lcd_panel->format, bg.r, bg.g, bg.b)); SDL_FillRect(pixel_on, NULL, SDL_MapRGB(pixel_on->format, fg_chr.r, fg_chr.g, fg_chr.b)); SDL_FillRect(pixel_off, NULL, SDL_MapRGB(pixel_off->format, bg_chr.r, bg_chr.g, bg_chr.b)); SDL_FillRect(chr_on, NULL, SDL_MapRGB(chr_on->format, bg.r, bg.g, bg.b)); SDL_FillRect(chr_off, NULL, SDL_MapRGB(chr_off->format, bg.r, bg.g, bg.b)); SDL_FillRect(chr_uscore, NULL, SDL_MapRGB(chr_uscore->format, bg.r, bg.g, bg.b)); // Create on/off pixel surfaces SDL_Rect rect; for (rect.y = 0; rect.y < px_chr_height; rect.y += (px_size / 2 + 1)) { for (rect.x = 0; rect.x < px_chr_width; rect.x += (px_size / 2 + 1)) { rect.w = rect.h = (px_size / 2); SDL_BlitSurface(pixel_on, NULL, chr_on, &rect); } } for (rect.y = 0; rect.y < px_chr_height; rect.y += (px_size / 2 + 1)) { for (rect.x = 0; rect.x < px_chr_width; rect.x += (px_size / 2 + 1)) { rect.w = rect.h = (px_size / 2); SDL_BlitSurface(pixel_off, NULL, chr_off, &rect); } } // Create underscore rect.y = 0; for (rect.x = 0; rect.x < px_chr_width; rect.x += (px_size / 2 + 1)) { rect.w = rect.h = (px_size / 2); SDL_BlitSurface(pixel_on, NULL, chr_uscore, &rect); } // Create font glyph surfaces device->GetFont()->Render(chr_off, pixel_on, pixel_off); // Create unknown character // TODO: throw: fatal if not found chr_unknown = device->GetFont()->GetGlyph('?'); // Clear display UpdateDisplay(0); }
void draw_fade(Uint8 alpha, SDL_Surface *surf) { SDL_Rect dest = {0, 0, 0, 0}; SDL_SetAlpha(GPX.black, SDL_SRCALPHA | SDL_RLEACCEL, alpha); SDL_BlitSurface(GPX.black, NULL, surf, NULL); return; }
GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord) { GLuint texture; int w, h; SDL_Surface *image; SDL_Rect area; Uint32 saved_flags; Uint8 saved_alpha; /* Use the surface width and height expanded to powers of 2 */ w = power_of_two(surface->w); h = power_of_two(surface->h); texcoord[0] = 0.0f; /* Min X */ texcoord[1] = 0.0f; /* Min Y */ texcoord[2] = (GLfloat)surface->w / w; /* Max X */ texcoord[3] = (GLfloat)surface->h / h; /* Max Y */ image = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); if ( image == NULL ) { return 0; } /* Save the alpha blending attributes */ saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); saved_alpha = surface->format->alpha; if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { SDL_SetAlpha(surface, 0, 0); } /* Copy the surface into the GL texture image */ area.x = 0; area.y = 0; area.w = surface->w; area.h = surface->h; SDL_BlitSurface(surface, &area, image, &area); /* Restore the alpha blending attributes */ if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { SDL_SetAlpha(surface, saved_flags, saved_alpha); } /* Create an OpenGL texture for the image */ glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); SDL_FreeSurface(image); /* No longer needed */ return texture; }
/** * Show credits with list of contributors. * * Names of people are shown scrolling up like in movie-credits.\n * Uses map from wesnoth or campaign as background. */ void show_about(CVideo &video, const std::string &campaign) { std::unique_ptr<cursor::setter> cur(new cursor::setter(cursor::WAIT)); surface& screen = video.getSurface(); if (screen == nullptr) return; // If the title is multi-line, we need to split it accordingly or we // get slight scrolling glitches in the credits screen. std::vector<std::string> text = about::get_text(campaign, true); SDL_Rect screen_rect = sdl::create_rect(0, 0, screen->w, screen->h); const surface_restorer restorer(&video, screen_rect); cur.reset(); std::vector<std::string> image_list; if(campaign.size() && !images[campaign].empty()){ image_list = utils::parenthetical_split(images[campaign], ','); } else{ image_list = utils::parenthetical_split(images_default, ','); } surface map_image, map_image_scaled; if(!image_list.empty()) { map_image = image::get_image(image_list[0]); } else { image_list.push_back(""); } if(!map_image){ image_list[0]=game_config::images::game_title_background; map_image=image::get_image(image_list[0]); } gui::button close(video,_("Close")); close.set_location((screen->w/2)-(close.width()/2), screen->h - 30); const int def_size = font::SIZE_XLARGE; const SDL_Color def_color = font::NORMAL_COLOR; //substitute in the correct control characters for '+' and '-' std::string before_header(2, ' '); before_header[0] = font::LARGE_TEXT; for(unsigned i = 0; i < text.size(); ++i) { std::string &s = text[i]; if (s.empty()) continue; char &first = s[0]; if (first == '-') first = font::SMALL_TEXT; else if (first == '+') { first = font::LARGE_TEXT; text.insert(text.begin() + i, before_header); ++i; } } text.insert(text.begin(), 10, before_header); int startline = 0; //TODO: use values proportional to screen ? // distance from top of map image to top of scrolling text const int top_margin = 60; // distance from bottom of scrolling text to bottom of map image const int bottom_margin = 40; // distance from left of scrolling text to the frame border const int text_left_padding = screen->w/32; int offset = 0; bool is_new_line = true; int first_line_height = 0; SDL_Rect frame_area; // we use a dialog to contains the text. Strange idea but at least the style // will be consistent with the titlescreen gui::dialog_frame f(video, "", gui::dialog_frame::titlescreen_style, false); // the text area's dimensions SDL_Rect text_rect = { 0, 0, 0, 0 }; // we'll retain a copy to prevent SDL_blit to change its w and h SDL_Rect text_rect_blit; surface text_surf; CKey key; bool last_escape; int image_count = 0; int scroll_speed = 4; // scroll_speed*50 = speed of scroll in pixel per second // Initially redraw all bool redraw_mapimage = true; bool update_dimensions = true; int max_text_width = 0; do { last_escape = key[SDLK_ESCAPE] != 0; // check to see if background image has changed if(text.size() && (image_count < ((startline * static_cast<int>(image_list.size())) / static_cast<int>(text.size())))){ image_count++; surface temp=image::get_image(image_list[image_count]); map_image=temp?temp:map_image; redraw_mapimage = true; } if (update_dimensions) { // rescale the background map_image_scaled = scale_surface(map_image, screen->w, screen->h); screen_rect = sdl::create_rect(0, 0, screen->w, screen->h); redraw_mapimage = true; // update the frame frame_area = sdl::create_rect( screen->w * 3 / 32 , top_margin , screen->w * 13 / 16 , screen->h - top_margin - bottom_margin); text_rect = f.layout(frame_area).interior; // update the text area text_rect.x += text_left_padding; text_rect.w -= text_left_padding; text_rect_blit = text_rect; text_surf = create_compatible_surface(screen, text_rect.w, text_rect.h); SDL_SetAlpha(text_surf, SDL_RLEACCEL, SDL_ALPHA_OPAQUE); // relocate the close button close.set_location((screen->w/2)-(close.width()/2), screen->h - 30); update_dimensions = false; } if (redraw_mapimage) { // draw map to screen, thus erasing all text sdl_blit(map_image_scaled, nullptr, screen, nullptr); update_rect(screen_rect); // redraw the dialog f.draw_background(); f.draw_border(); // cache the dialog background (alpha blending + blurred map) sdl_blit(screen, &text_rect, text_surf, nullptr); redraw_mapimage = false; } else { // redraw the saved part of the dialog where text scrolled // thus erasing all text SDL_Rect modified = sdl::create_rect(0, 0, max_text_width, text_rect.h); sdl_blit(text_surf, &modified, screen, &text_rect_blit); update_rect(text_rect); } int y = text_rect.y - offset; int line = startline; max_text_width = 0; { // clip to keep text into the frame (thus the new code block) clip_rect_setter set_clip_rect(screen, &text_rect); const int line_spacing = 5; do { // draw the text (with ellipsis if needed) // update the max_text_width for future cleaning int w = font::draw_text(&video, text_rect, def_size, def_color, text[line], text_rect.x, y).w; max_text_width = std::max<int>(max_text_width, w); // since the real drawing on screen is clipped, // we do a dummy one to get the height of the not clipped line. // (each time because special format characters may change it) const int line_height = font::draw_text(nullptr, text_rect, def_size, def_color, text[line], 0,0).h; if(is_new_line) { is_new_line = false; first_line_height = line_height + line_spacing; } line++; if(size_t(line) > text.size()-1) line = 0; y += line_height + line_spacing; } while(y < text_rect.y + text_rect.h); } // performs the actual scrolling offset += scroll_speed; if (offset>=first_line_height) { offset -= first_line_height; is_new_line = true; startline++; if(size_t(startline) == text.size()){ startline = 0; image_count = -1; } } // handle events if (key[SDLK_UP] && scroll_speed < 20) { ++scroll_speed; } if (key[SDLK_DOWN] && scroll_speed > 0) { --scroll_speed; } if (screen->w != screen_rect.w || screen->h != screen_rect.h) { update_dimensions = true; } events::pump(); events::raise_process_event(); events::raise_draw_event(); // flip screen and wait, so the text does not scroll too fast video.flip(); CVideo::delay(20); } while(!close.pressed() && (last_escape || !key[SDLK_ESCAPE])); }
// Initialise runtime bool CRuntime::Initialise(CRuntimeSetup* crSetup) { // Start by getting and saving the CPU capabilities. DWORD cpuFeatures = GetCPUCaps(); supportMMX = cpuFeatures & CPU_FEATURE_MMX; supportSSE = cpuFeatures & CPU_FEATURE_SSE; supportSSE2 = cpuFeatures & CPU_FEATURE_SSE2; // Construct requires MMX for collisions #ifndef APPRUNTIME if (!supportMMX) throw runtime_error("Your CPU does not support MMX technology (it must be pretty old!). Please buy a newer PC then try again!"); #endif // Save hInstance hInstance = crSetup->hInstance; CapReader.pRuntime = this; CreateTempDirectory(); // Get app properties BYTE* pData; int dataSize; HGLOBAL hData = OpenResourceBinary(997, "APPBLOCK", pData, dataSize); CapReader.ReadAppProperties(pData, dataSize, props); FreeResource(hData); // Cannot use both multisampling and motion blur #ifndef APPRUNTIME if (multisamples > 0 && motionBlur) throw runtime_error("Cannot enable both multisamples and motion blur. Please change one of these settings."); #endif #ifdef PYTHON // Get python hData = OpenResourceBinary(992, "PYTHONLIBS", pData, dataSize); CapReader.ReadPythonResources(pData, dataSize); FreeResource(hData); if(!SearchPath(NULL, "python26.dll", NULL, 0, NULL, NULL)) throw runtime_error("Python26.dll was not found and is required to run this application or feature. Reinstalling the application " "may fix this problem."); Py_Initialize(); #endif // Get menu resources hData = OpenResourceBinary(993, "MENUBLOCK", pData, dataSize); CapReader.ReadMenuResources(pData, dataSize, menus); FreeResource(hData); crSetup->winWidth = props.winWidth; crSetup->winHeight = props.winHeight; crSetup->eyeDistance = props.eyeDistance; crSetup->screensaver = props.screensaver; fpsMode = props.fpsMode; userFps = props.fps; //if (disableWindowsKey) // g_hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, DisableWinKeyKeyboardProc, hInstance, 0); #ifdef CONSTRUCT_DIRECTX9 crSetup->display_params.fps_mode = props.fpsMode; crSetup->display_params.fullscreen = fullscreen = props.fullscreen; crSetup->display_params.backbuffer_width = props.winWidth; crSetup->display_params.backbuffer_height = props.winHeight; switch (multisamples) { case 0: // Off crSetup->display_params.multisamples = 0; break; case 1: // 2x crSetup->display_params.multisamples = 2; break; case 2: // 4x crSetup->display_params.multisamples = 4; break; case 3: // 8x crSetup->display_params.multisamples = 8; break; default: crSetup->display_params.multisamples = 0; break; } // PreInit gets the D3D caps and allows MakeWindows to create the correct number of windows to pass to Init() //Display.SetMultiMonitorMode(MMM_CLONE); //Display.PreInit(); renderer.LoadD3D(); #endif #ifndef CONSTRUCT_SDL // Create a window for the runtime if (!MakeWindows(crSetup)) throw runtime_error("Cannot create window"); #else if (SDL_Init(SDL_INIT_VIDEO) < 0) exit(1); // Register SDL_Quit to be called at exit; makes sure things are cleaned up when we quit. atexit(SDL_Quit); // Attempt to create window with 32bit pixels in hardware Display.screen = SDL_SetVideoMode(props.winWidth, props.winHeight, 32, SDL_HWSURFACE); SDL_SetAlpha(Display.screen, SDL_SRCALPHA, 255); // Set alpha to normal #endif InitCommonControls(); // The preview runtimes show the runtime in the title bar. #ifdef CONSTRUCT_PREVIEW #ifdef CONSTRUCT_DIRECTX9 props.appTitle += " (DX9 runtime)"; #endif #ifdef APPRUNTIME props.appTitle += " (App runtime)"; #endif #ifdef CONSTRUCT_SDL props.appTitle += " (SDL runtime)"; #endif #endif #ifndef CONSTRUCT_SDL SetWindowText(hWnds.front(), props.appTitle); #else SDL_WM_SetCaption(props.appTitle, NULL); #endif // Restore mouse cursor from hourglass if (!props.screensaver) SetCursor(LoadCursor(NULL, IDC_ARROW)); // Load a menu if (props.UseMenu) if (menus.size() != 0) SetMenu(hWnds.front(), menus[0]); #ifndef APPRUNTIME #ifndef CONSTRUCT_SDL // Direct-X setup crSetup->display_params.hWnds = hWnds; crSetup->display_params.hFocusWnd = hWnds.front(); winWidthOffset = 0; winHeightOffset = 0; // Retrieve all display modes: can't set an invalid display mode size if (crSetup->display_params.fullscreen) { BOOL bRetVal; DEVMODE devMode; int iMode = 0; int wantedWidth = crSetup->display_params.backbuffer_width; int wantedHeight = crSetup->display_params.backbuffer_height; int bestWidth = 100000; int bestHeight = 100000; bool found = false; do { bRetVal = ::EnumDisplaySettings(NULL, iMode, &devMode); iMode++; if (bRetVal) { int curWidth = devMode.dmPelsWidth; int curHeight = devMode.dmPelsHeight; // Display mode found! if (curWidth == wantedWidth && curHeight == wantedHeight) found = true; // This display mode is big enough to fit the display in, but is smaller than the last best size if ((curWidth >= wantedWidth && curHeight >= wantedHeight) && (curWidth < bestWidth && curHeight < bestHeight)) { bestWidth = curWidth; bestHeight = curHeight; } } } while (bRetVal); // Identical display mode not found: use next best that can fit it all on if (!found) { // Still 100000x100000: no resolution found that supports this if (bestWidth == 100000 || bestHeight == 100000) throw runtime_error("The display resolution required by this application is not supported."); #ifdef CONSTRUCT_PREVIEW CString msg; msg.Format("Switching to Fullscreen mode: Display mode %d x %d not supported, switching to next best %d x %d.\n\n" "The 'Window Width' and 'Window Height' values in Application Properties define the fullscreen resolution.", crSetup->display_params.backbuffer_width, crSetup->display_params.backbuffer_height, bestWidth, bestHeight); MessageBox(NULL, msg, "Fullscreen preview", MB_OK | MB_ICONEXCLAMATION); #endif crSetup->display_params.backbuffer_width = wantedWidth = bestWidth; crSetup->display_params.backbuffer_height = wantedHeight = bestHeight; } } // Set the eye distance before we initialize eyeDistance = crSetup->eyeDistance; renderer.SetEyeDistance(eyeDistance); // Start up the display engine //Display.Init(&(crSetup->d3dDisplaySetup)); renderer.CreateDevice(crSetup->display_params); /* // No identical match for display mode if (crSetup->d3dDisplaySetup.resWidth != actualDisplayWidth || crSetup->d3dDisplaySetup.resHeight != actualDisplayHeight) if (tempDisplayTarget == unallocated_texture) tempDisplayTarget = CreateDisplayTargetTexture(); winWidthOffset = (actualDisplayWidth - crSetup->d3dDisplaySetup.resWidth) / 2; winHeightOffset = (actualDisplayHeight - crSetup->d3dDisplaySetup.resHeight) / 2; } */ GetSwapChains(); // Multi-monitor settings require the temp display target if (renderer.GetMultiMonitorMode() != cr::multimonitor_singlescreen) { if (tempDisplayTarget == unallocated_texture) tempDisplayTarget = CreateDisplayTargetTexture(); } // Linear resizers if (props.sampler == 0) { renderer.SetSamplerState(cr::ss_magfilter, cr::ssv_point); renderer.SetSamplerState(cr::ss_minfilter, cr::ssv_point); } if (props.sampler == 1) { renderer.SetSamplerState(cr::ss_magfilter, cr::ssv_linear); renderer.SetSamplerState(cr::ss_minfilter, cr::ssv_linear); } // Premultiplied alpha mode renderer.SetAlphaBlending(); // Runtime uses clamp-sampling renderer.SetSamplerState(cr::ss_addressu, cr::ssv_clamp); renderer.SetSamplerState(cr::ss_addressv, cr::ssv_clamp); // Create the multisampling target if one required //if (multisamples > 0) // 0 is off // multisampleTargets[0] = renderer.CreateRenderTargetTexture(crSetup->winWidth, crSetup->winHeight, cr::texture_format_a8r8g8b8, true); #if defined(CONSTRUCT_DIRECTX9) && defined(CONSTRUCT_PREVIEW) // Handle shader simulation if (simShader != SS_NOSIM) { UINT ps_major = D3DSHADER_VERSION_MAJOR(renderer.GetCaps().PixelShaderVersion); UINT ps_minor = D3DSHADER_VERSION_MINOR(renderer.GetCaps().PixelShaderVersion); CString hardwarePS; hardwarePS.Format("%d.%d", ps_major, ps_minor); CString simulatedPS; switch (simShader) { case SS_PS14: simulatedPS = "1.4"; break; case SS_PS11: simulatedPS = "1.1"; break; case SS_PS00: simulatedPS = "0.0"; break; } float ps_version = atof(hardwarePS); float sim_version = atof(simulatedPS); // If fullscreen MessageBox()'s won't work if (!fullscreen) { if (sim_version > ps_version) { CString msg; msg.Format("You have chosen to simulate a pixel shader version (PS %s) higher than your hardware supports (PS %s). " "You can only simulate lower hardware capabilities. The application will continue to use PS %s.", simulatedPS, hardwarePS, simulatedPS); MessageBox(NULL, msg, "Simulate shader", MB_OK | MB_ICONEXCLAMATION); } else if (sim_version == ps_version) { CString msg; msg.Format("You have chosen to simulate the same pixel shader version as your hardware supports (PS %s). " "The application will continue normally.", hardwarePS); MessageBox(NULL, msg, "Simulate shader", MB_OK | MB_ICONINFORMATION); } else { CString msg; msg.Format("You are simulating pixel shader %s capabilites. Your hardware supports pixel shader %s.", simulatedPS, hardwarePS); MessageBox(NULL, msg, "Simulate shader", MB_OK | MB_ICONEXCLAMATION); } } } #endif // shader sims #endif // Load the PNG image list hData = OpenResourceBinary(995, "IMAGEBLOCK", pData, dataSize); CapReader.ReadImageData(pData, dataSize, imagehandle_to_address); FreeResource(hData); #ifdef CONSTRUCT_DIRECTX9 // Initialise DirectInput if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&dinput, NULL))) throw runtime_error("Failed to initialise DirectInput. Please ensure you have DirectX 8 or above installed!"); // Initialize the keyboard if (FAILED(dinput->CreateDevice(GUID_SysKeyboard, &d_keyboard, NULL))) throw runtime_error("Failed to initialise DirectInput."); if (FAILED(d_keyboard->SetDataFormat(&c_dfDIKeyboard))) throw runtime_error("Failed to initialise DirectInput."); if (FAILED(d_keyboard->SetCooperativeLevel(hWnds.front(), DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) throw runtime_error("Failed to initialise DirectInput."); if (FAILED(d_keyboard->Acquire())) throw runtime_error("Failed to initialise DirectInput."); // initialize the mouse if (FAILED(dinput->CreateDevice(GUID_SysMouse, &d_mouse, NULL))) throw runtime_error("Failed to initialise DirectInput."); if (FAILED(d_mouse->SetCooperativeLevel(hWnds.front(), DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) throw runtime_error("Failed to initialise DirectInput."); if (FAILED(d_mouse->SetDataFormat(&c_dfDIMouse))) throw runtime_error("Failed to initialise DirectInput."); if (FAILED(d_mouse->Acquire())) throw runtime_error("Failed to initialise DirectInput."); inputState.isDirectInput = true; #endif #endif //#ifndef APPRUNTIME // Save window dimensions winWidth = crSetup->winWidth; winHeight = crSetup->winHeight; RECT clientSize; GetClientRect(hWnds.front(), &clientSize); realWinWidth = clientSize.right - clientSize.left; realWinHeight = clientSize.bottom - clientSize.top; // Unpack dependencies before loading plugins UnpackDependencies(); // Unpack the resource plugins to the temp dir and load them UnpackPlugins(1000); // Read the frame data hData = OpenResourceBinary(998, "LEVELBLOCK", pData, dataSize); CapReader.ReadFrameData(pData, dataSize); FreeResource(hData); // Map object type names to their pointers for (vector<CRunObjType*>::iterator i = objects.begin(); i != objects.end(); i++) { CString lowername = (*i)->Name; lowername.MakeLower(); name_to_object[lowername] = *i; } #ifdef CONSTRUCT_DEBUGGER // Create debugger once object types are known but before parsing event block (which may send logs) // Create invisible initially pDebug->Create(); pDebug->ShowWindow(SW_HIDE); #endif // Read the CAP event tree hData = OpenResourceBinary(999, "EVENTBLOCK", pData, dataSize); CapReader.ReadEventList(pData, dataSize); FreeResource(hData); // Iterate all events determining their modifiers vector<CRunLayout*>::iterator f = Frames.begin(); const vector<CRunLayout*>::const_iterator Frames_end = Frames.end(); for ( ; f != Frames_end; f++) { EventIterator e = (*f)->Events.begin(); EventConstIterator Events_end = (*f)->Events.end(); for ( ; e != Events_end; ++e) { // Recurse down tree finding SOL modifiers (*e)->GetSolModifiers(*f); // If this event line is a group, it can be marked as top level for optimisation if ((*e)->GetType() == EVENT_GROUP) ((CEventGroup*)*e)->isTopLevel = true; } } // Initialise effects #ifdef CONSTRUCT_DIRECTX9 hData = OpenResourceBinary(994, "HLSL", pData, dataSize); CapReader.ReadHLSLData(pData, dataSize); FreeResource(hData); // If motionblur is required, set up the textures if (motionBlur) { InitMotionBlur(); } #endif //APPRUNTIME // Clock offset (timers relative to Run()) clockOffset = clock(); curFrame = 0; // Mark objects which are not to serialize CRunObjType* pNoSerialize = GetTypeFromName("No serialize"); if (pNoSerialize) { if (!pNoSerialize->teams.empty()) { ObjTypeIterator t = pNoSerialize->teams.begin(); ObjTypeIterator end = pNoSerialize->teams.end(); for ( ; t != end; t++) (*t)->noSerialize = true; } } // Set current frame CRunLayout* pFirstFrame = Frames.front(); runningFrames.push_back(pFirstFrame); system.pLayout = pFirstFrame; pFirstFrame->systemDrawn = true; pFirstFrame->Load(); // Load any other layouts which want their textures loaded on startup vector<CRunLayout*>::iterator ly = Frames.begin(); ly++; // already loaded 1st layout for ( ; ly != Frames.end(); ++ly) { if ((*ly)->texture_loading == CRunLayout::tl_load_on_app_start) (*ly)->LoadLayoutTextures(); else if ((*ly)->texture_loading == CRunLayout::tl_use_app_setting && texture_loading == tl_load_on_app_start) (*ly)->LoadLayoutTextures(); } // Directories exist etc. by now. completedInitialisation = true; // Initial frame mouse coord POINT mouse; GetCursorPos(&mouse); if (!fullscreen) ScreenToClient(hWnds.front(), &mouse); pFirstFrame->mouseX = mouse.x; pFirstFrame->mouseY = mouse.y; // Create initial frame objects (generatevent works) pFirstFrame->CreateInitialObjects(); FlushDelayedObjects(); system.changeResWidth = winWidth; system.changeResHeight = winHeight; // Start of Layout triggered only if not previewing another layout if (previewLayout <= 0) GenerateEvent(-1, SYSTEM_STARTOFFRAME, NULL); #ifdef CONSTRUCT_DEBUGGER pDebug->ShowWindow(SW_SHOW); pDebug->SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER); pDebug->ModifyStyleEx(0, WS_EX_TOPMOST); #endif // Previewing single layout? if (previewLayout > 0) // if == 0, no need to jump anywhere, already on layout 1 system.DoFrameChange(previewLayout, "none", 0); return true; }
SWError SWCreateBlankFrame ( FramePtr* newFrameP, int w, int h, unsigned char depth, SWBoolean createAlphaChannel ) { SWError err = kNoError; FramePtr tempFrameP = NULL; SDL_Surface *tempSurfaceP = NULL; Uint32 rmask, gmask, bmask, amask; /* SDL interprets each pixel as a 32-bit number, so our masks must depend on the endianness (byte order) of the machine */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif err = SWCreateFrame( &tempFrameP ); if (err == kNoError) { if ( !createAlphaChannel ) { amask = 0; } /* Create a 32-bit surface with the bytes of each pixel in R,G,B,A order, as expected by OpenGL for textures */ tempSurfaceP = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, depth, rmask, gmask, bmask, amask); if (tempSurfaceP != NULL && createAlphaChannel) { SDL_SetAlpha(tempSurfaceP, SDL_SRCALPHA, SDL_ALPHA_OPAQUE); } if (!tempSurfaceP) err = kSDLCreateSurface; } if (err == kNoError) { tempFrameP->originalSurfaceP = tempSurfaceP; err = SWUpdateFrame( tempFrameP ); } if (err == kNoError) { *newFrameP = tempFrameP; } else { if ( tempSurfaceP ) { SDL_FreeSurface( tempSurfaceP ); } if ( tempFrameP ) { free( tempFrameP ); } } return err; }
/** * @brief Prepares the surface to be loaded as a texture. * * @param surface to load that is freed in the process. * @return New surface that is prepared for texture loading. */ SDL_Surface* gl_prepareSurface( SDL_Surface* surface ) { SDL_Surface* temp; int potw, poth; SDL_Rect rtemp; #if ! SDL_VERSION_ATLEAST(1,3,0) Uint32 saved_flags; #endif /* ! SDL_VERSION_ATLEAST(1,3,0) */ /* Make size power of two. */ potw = gl_pot(surface->w); poth = gl_pot(surface->h); if (gl_needPOT() && ((potw != surface->w) || (poth != surface->h))) { /* we must blit with an SDL_Rect */ rtemp.x = rtemp.y = 0; rtemp.w = surface->w; rtemp.h = surface->h; /* saves alpha */ #if SDL_VERSION_ATLEAST(1,3,0) SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); /* create the temp POT surface */ temp = SDL_CreateRGBSurface( 0, potw, poth, surface->format->BytesPerPixel*8, RGBAMASK ); #else /* SDL_VERSION_ATLEAST(1,3,0) */ saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { SDL_SetAlpha( surface, 0, SDL_ALPHA_OPAQUE ); SDL_SetColorKey( surface, 0, surface->format->colorkey ); } /* create the temp POT surface */ temp = SDL_CreateRGBSurface( SDL_SRCCOLORKEY, potw, poth, surface->format->BytesPerPixel*8, RGBAMASK ); #endif /* SDL_VERSION_ATLEAST(1,3,0) */ if (temp == NULL) { WARN("Unable to create POT surface: %s", SDL_GetError()); return 0; } if (SDL_FillRect( temp, NULL, SDL_MapRGBA(surface->format,0,0,0,SDL_ALPHA_TRANSPARENT))) { WARN("Unable to fill rect: %s", SDL_GetError()); return 0; } /* change the surface to the new blitted one */ SDL_BlitSurface( surface, &rtemp, temp, &rtemp); SDL_FreeSurface( surface ); surface = temp; #if ! SDL_VERSION_ATLEAST(1,3,0) /* set saved alpha */ if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) SDL_SetAlpha( surface, 0, 0 ); #endif /* ! SDL_VERSION_ATLEAST(1,3,0) */ } return surface; }
SDL_Surface *gfx_crop_surface(SDL_Surface * surface, SDL_Rect rect, SDL_PixelFormat * format, Uint32 flags) { SDL_Surface *convert; Uint32 colorkey = 0; Uint8 alpha = 0; Uint32 surface_flags; SDL_Rect bounds; /* Check for empty destination palette! (results in empty image) */ if (format->palette != NULL) { int i; for (i = 0; i < format->palette->ncolors; ++i) { if ((format->palette->colors[i].r != 0) || (format->palette->colors[i].g != 0) || (format->palette->colors[i].b != 0)) break; } if (i == format->palette->ncolors) { SDL_SetError("Empty destination palette"); return (NULL); } } /* Create a new surface with the desired format */ convert = SDL_CreateRGBSurface(flags, rect.w, rect.h, format->BitsPerPixel, format->Rmask, format->Gmask, format->Bmask, format->Amask); if (convert == NULL) { return (NULL); } /* Copy the palette if any */ if (format->palette && convert->format->palette) { memcpy(convert->format->palette->colors, format->palette->colors, format->palette->ncolors * sizeof(SDL_Color)); convert->format->palette->ncolors = format->palette->ncolors; } /* Save the original surface color key and alpha */ surface_flags = surface->flags; if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { /* Convert colourkeyed surfaces to RGBA if requested */ if ((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY && format->Amask) { surface_flags &= ~SDL_SRCCOLORKEY; } else { colorkey = surface->format->colorkey; SDL_SetColorKey(surface, 0, 0); } } if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { alpha = surface->format->alpha; SDL_SetAlpha(surface, 0, 0); } /* Copy over the image data */ bounds.x = 0; bounds.y = 0; bounds.w = rect.w; bounds.h = rect.h; SDL_LowerBlit(surface, &rect, convert, &bounds); if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK); if (convert != NULL) { Uint8 keyR, keyG, keyB; SDL_GetRGB(colorkey, surface->format, &keyR, &keyG, &keyB); SDL_SetColorKey(convert, cflags | (flags & SDL_RLEACCELOK), SDL_MapRGB(convert->format, keyR, keyG, keyB)); } SDL_SetColorKey(surface, cflags, colorkey); } if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); if (convert != NULL) { SDL_SetAlpha(convert, aflags | (flags & SDL_RLEACCELOK), alpha); } SDL_SetAlpha(surface, aflags, alpha); } /* We're ready to go! */ return (convert); }
Animation* CreateGridTexture(World* _world, Vector2i _grid_size) { bool fill = true; Vector2i offset(2, 2); Vector2i size = _grid_size * _world->GetSize() + Vector2i(4, 4); SDL_Surface* p_checkerboard = SDL_CreateRGBSurface(SDL_SWSURFACE, size.x, size.y, 32, rmask, gmask, bmask, amask); SDL_Surface* old_checkboard = p_checkerboard; p_checkerboard = SDL_DisplayFormatAlpha(p_checkerboard); SDL_FreeSurface(old_checkboard); SDL_SetAlpha(p_checkerboard, 0, 255); SDL_FillRect(p_checkerboard, NULL, SDL_MapRGB(p_checkerboard->format, 255, 255, 255)); SDL_Surface* old_screen = SDLAnimationFrame::screen_; SDLAnimationFrame::screen_ = p_checkerboard; for(int y = 0; y < _world->GetSize().y; y++) { fill = y % 2 == 0; for(int x = 0; x < _world->GetSize().x; x++) { fill = !fill; if(fill) StandardTextures::tile_a_animation->GetCurrentFrame()->Draw(offset + Vector2f(static_cast<float>(x * _grid_size.x), static_cast<float>(y * _grid_size.y))); else StandardTextures::tile_b_animation->GetCurrentFrame()->Draw(offset + Vector2f(static_cast<float>(x * _grid_size.x), static_cast<float>(y * _grid_size.y))); } } for(int y = 0; y < _world->GetSize().y; y++) { for(int x = 0; x < _world->GetSize().x; x++) { if(_world->GetGridSquare(Vector2i(x,y)).GetNorth()) { StandardTextures::wall_horz_animation->GetCurrentFrame()->Draw(Vector2f(static_cast<float>(x * _grid_size.x), static_cast<float>(y * _grid_size.y))); if(y == 0) { StandardTextures::wall_horz_animation->GetCurrentFrame()->Draw(Vector2f(static_cast<float>(x * _grid_size.x), static_cast<float>(_world->GetSize().y * _grid_size.y))); } } if(_world->GetGridSquare(Vector2i(x,y)).GetWest()) { StandardTextures::wall_vert_animation->GetCurrentFrame()->Draw(Vector2f(static_cast<float>(x * _grid_size.x), static_cast<float>(y * _grid_size.y))); if(x == 0) { StandardTextures::wall_vert_animation->GetCurrentFrame()->Draw(Vector2f(static_cast<float>(_world->GetSize().x * _grid_size.x), static_cast<float>(y * _grid_size.y))); } } } } SDLAnimationFrame::screen_ = old_screen; /* for(int y = 0; y < _world->GetSize().y; y++) { fill = y % 2 == 0; for(int x = 0; x < _world->GetSize().x; x++) { SDL_Rect area; area.x = x * _grid_size.x; area.y = y * _grid_size.y; area.w = _grid_size.x; area.h = _grid_size.y; if(fill) SDL_FillRect(p_checkerboard, &area, SDL_MapRGB(p_checkerboard->format, Settings::GetGridColorA().r, Settings::GetGridColorA().g, Settings::GetGridColorA().b)); else SDL_FillRect(p_checkerboard, &area, SDL_MapRGB(p_checkerboard->format, Settings::GetGridColorB().r, Settings::GetGridColorB().g, Settings::GetGridColorB().b)); fill = !fill; } } for(int y = 0; y < _world->GetSize().y; y++) { for(int x = 0; x < _world->GetSize().x; x++) { if(_world->GetGridSquare(Vector2i(x,y)).GetNorth()) { SDL_Rect area; area.x = x * _grid_size.x - 1; area.y = y * _grid_size.y - 1; area.w = _grid_size.x + 2; area.h = 2; SDL_FillRect(p_checkerboard, &area, SDL_MapRGB(p_checkerboard->format, 255, 0, 0)); if(y == 0) { area.y = _grid_size.y * _world->GetSize().y; SDL_FillRect(p_checkerboard, &area, SDL_MapRGB(p_checkerboard->format, 255, 0, 0)); } } if(_world->GetGridSquare(Vector2i(x,y)).GetWest()) { SDL_Rect area; area.x = x * _grid_size.x - 1; area.y = y * _grid_size.y - 1; area.w = 2; area.h = _grid_size.y + 2; SDL_FillRect(p_checkerboard, &area, SDL_MapRGB(p_checkerboard->format, 255, 0, 0)); if(x == 0) { area.x = _grid_size.x * _world->GetSize().x; SDL_FillRect(p_checkerboard, &area, SDL_MapRGB(p_checkerboard->format, 255, 0, 0)); } } } }*/ Animation* g_animation = new Animation(); SDLAnimationFrame* af = new SDLAnimationFrame(0, 0, Vector2i(0, 0), p_checkerboard); g_animation->AddFrame(af); return g_animation; }
/* Create a "light" -- a yellowish surface with variable alpha */ SDL_Surface * CreateLight(int radius) { Uint8 trans, alphamask; int range, addition; int xdist, ydist; Uint16 x, y; Uint16 skip; Uint32 pixel; SDL_Surface *light; #ifdef LIGHT_16BIT Uint16 *buf; /* Create a 16 (4/4/4/4) bpp square with a full 4-bit alpha channel */ /* Note: this isn't any faster than a 32 bit alpha surface */ alphamask = 0x0000000F; light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2 * radius, 2 * radius, 16, 0x0000F000, 0x00000F00, 0x000000F0, alphamask); #else Uint32 *buf; /* Create a 32 (8/8/8/8) bpp square with a full 8-bit alpha channel */ alphamask = 0x000000FF; light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2 * radius, 2 * radius, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, alphamask); if (light == NULL) { fprintf(stderr, "Couldn't create light: %s\n", SDL_GetError()); return (NULL); } #endif /* Fill with a light yellow-orange color */ skip = light->pitch - (light->w * light->format->BytesPerPixel); #ifdef LIGHT_16BIT buf = (Uint16 *) light->pixels; #else buf = (Uint32 *) light->pixels; #endif /* Get a tranparent pixel value - we'll add alpha later */ pixel = SDL_MapRGBA(light->format, 0xFF, 0xDD, 0x88, 0); for (y = 0; y < light->h; ++y) { for (x = 0; x < light->w; ++x) { *buf++ = pixel; } buf += skip; /* Almost always 0, but just in case... */ } /* Calculate alpha values for the surface. */ #ifdef LIGHT_16BIT buf = (Uint16 *) light->pixels; #else buf = (Uint32 *) light->pixels; #endif for (y = 0; y < light->h; ++y) { for (x = 0; x < light->w; ++x) { /* Slow distance formula (from center of light) */ xdist = x - (light->w / 2); ydist = y - (light->h / 2); range = (int) sqrt(xdist * xdist + ydist * ydist); /* Scale distance to range of transparency (0-255) */ if (range > radius) { trans = alphamask; } else { /* Increasing transparency with distance */ trans = (Uint8) ((range * alphamask) / radius); /* Lights are very transparent */ addition = (alphamask + 1) / 8; if ((int) trans + addition > alphamask) { trans = alphamask; } else { trans += addition; } } /* We set the alpha component as the right N bits */ *buf++ |= (255 - trans); } buf += skip; /* Almost always 0, but just in case... */ } /* Enable RLE acceleration of this alpha surface */ SDL_SetAlpha(light, SDL_SRCALPHA | SDL_RLEACCEL, 0); /* We're done! */ return (light); }
void GameRender::drawText(Font::GameFont* font, Text::GameText text) { SDL_Surface *initial; SDL_Surface *intermediary; SDL_Rect rect; int w, h; GLuint texture; rect.h = rect.w = rect.x = rect.y = 0; GLfloat x = text.getPosition().x; GLfloat y = text.getPosition().y; initial = TTF_RenderText_Blended(font->getFont(), text.getDataText().c_str(), font->getColor()); w = nextPowerOfTwo(initial->w); h = nextPowerOfTwo(initial->h); text.setOffset( Vector2f( GLfloat(nextPowerOfTwo(initial->w)) , GLfloat(nextPowerOfTwo(initial->h)) ) ); GLfloat offsetX = text.getOffset().x + x; GLfloat offsetY = text.getOffset().y + y; intermediary = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); SDL_SetAlpha(intermediary, 0, 0); SDL_BlitSurface(initial, 0, intermediary, 0); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary->pixels ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBlendFunc(GL_ONE, GL_ONE); glBegin( GL_QUADS ); glTexCoord2i( 0, 0 ); glVertex3f( x, y, 0.0f ); glTexCoord2i( 1, 0 ); glVertex3f( offsetX, y, 0.0f ); glTexCoord2i( 1, 1 ); glVertex3f( offsetX, offsetY, 0.0f ); glTexCoord2i( 0, 1 ); glVertex3f( x, offsetY, 0.0f ); glEnd(); SDL_FreeSurface(initial); SDL_FreeSurface(intermediary); glDeleteTextures(1, &texture); }
SDL_Surface *_PGFT_Render_NewSurface(FreeTypeInstance *ft, PgFontObject *fontobj, const FontRenderMode *mode, PGFT_String *text, FontColor *fgcolor, FontColor *bgcolor, SDL_Rect *r) { #if SDL_BYTEORDER == SDL_BIG_ENDIAN FT_UInt32 rmask = 0xff000000; FT_UInt32 gmask = 0x00ff0000; FT_UInt32 bmask = 0x0000ff00; FT_UInt32 amask = 0x000000ff; #else FT_UInt32 rmask = 0x000000ff; FT_UInt32 gmask = 0x0000ff00; FT_UInt32 bmask = 0x00ff0000; FT_UInt32 amask = 0xff000000; #endif int locked = 0; FT_UInt32 fillcolor; SDL_Surface *surface = 0; int bits_per_pixel = (bgcolor || mode->render_flags & FT_RFLAG_ANTIALIAS) ? 32 : 8; FT_UInt32 surface_flags = SDL_SWSURFACE; FontSurface font_surf; Layout *font_text; unsigned width; unsigned height; FT_Vector offset; FT_Pos underline_top; FT_Fixed underline_size; FontColor mono_fgcolor = {0, 0, 0, 1}; FontColor mono_bgcolor = {0, 0, 0, 0}; /* build font text */ font_text = _PGFT_LoadLayout(ft, fontobj, mode, text); if (!font_text) { return 0; } if (font_text->length > 0) { _PGFT_GetRenderMetrics(mode, font_text, &width, &height, &offset, &underline_top, &underline_size); } else { width = 1; height = _PGFT_Font_GetHeightSized(ft, fontobj, mode->face_size); offset.x = -font_text->min_x; offset.y = -font_text->min_y; } surface = SDL_CreateRGBSurface(surface_flags, width, height, bits_per_pixel, rmask, gmask, bmask, bits_per_pixel == 32 ? amask : 0); if (!surface) { PyErr_SetString(PyExc_SDLError, SDL_GetError()); return 0; } if (SDL_MUSTLOCK(surface)) { if (SDL_LockSurface(surface) == -1) { PyErr_SetString(PyExc_SDLError, SDL_GetError()); SDL_FreeSurface(surface); return 0; } locked = 1; } font_surf.buffer = surface->pixels; font_surf.width = surface->w; font_surf.height = surface->h; font_surf.pitch = surface->pitch; font_surf.format = surface->format; if (bits_per_pixel == 32) { font_surf.render_gray = __render_glyph_RGB4; font_surf.render_mono = __render_glyph_MONO4; font_surf.fill = __fill_glyph_RGB4; /* * Fill our texture with the required bg color */ if (bgcolor) { fillcolor = SDL_MapRGBA( surface->format, bgcolor->r, bgcolor->g, bgcolor->b, bgcolor->a); } else { fillcolor = SDL_MapRGBA(surface->format, 0, 0, 0, SDL_ALPHA_TRANSPARENT); } SDL_FillRect(surface, 0, fillcolor); } else { SDL_Color colors[2]; colors[1].r = fgcolor->r; /* Foreground */ colors[1].g = fgcolor->g; colors[1].b = fgcolor->b; colors[0].r = ~colors[1].r; /* Background */ colors[0].g = ~colors[1].g; colors[0].b = ~colors[1].b; if (!SDL_SetColors(surface, colors, 0, 2)) { PyErr_SetString(PyExc_SystemError, "Pygame bug in _PGFT_Render_NewSurface: " "SDL_SetColors failed"); SDL_FreeSurface(surface); return 0; } SDL_SetColorKey(surface, SDL_SRCCOLORKEY, (FT_UInt32)0); if (fgcolor->a != SDL_ALPHA_OPAQUE) { SDL_SetAlpha(surface, SDL_SRCALPHA, fgcolor->a); } fgcolor = &mono_fgcolor; bgcolor = &mono_bgcolor; font_surf.render_gray = __render_glyph_GRAY_as_MONO1; font_surf.render_mono = __render_glyph_MONO_as_GRAY1; font_surf.fill = __fill_glyph_GRAY1; /* * Fill our texture with the required bg color */ SDL_FillRect(surface, 0, 0); } /* * Render the text! */ render(ft, font_text, mode, fgcolor, &font_surf, width, height, &offset, underline_top, underline_size); r->x = -(Sint16)FX6_TRUNC(FX6_FLOOR(offset.x)); r->y = (Sint16)FX6_TRUNC(FX6_CEIL(offset.y)); r->w = (Uint16)width; r->h = (Uint16)height; if (locked) { SDL_UnlockSurface(surface); } return surface; }
/** ** Initialize the fog of war. ** Build tables, setup functions. */ void CMap::InitFogOfWar() { //calculate this once from the settings and store it FogOfWarColorSDL = Video.MapRGB(TheScreen->format, FogOfWarColor); Uint8 r, g, b; SDL_Surface *s; FogGraphic->Load(); #if defined(USE_OPENGL) || defined(USE_GLES) if (!UseOpenGL) #endif { // // Generate Only Fog surface. // s = SDL_CreateRGBSurface(SDL_SWSURFACE, PixelTileSize.x, PixelTileSize.y, 32, RMASK, GMASK, BMASK, AMASK); SDL_GetRGB(FogOfWarColorSDL, TheScreen->format, &r, &g, &b); Uint32 color = Video.MapRGB(s->format, r, g, b); SDL_FillRect(s, NULL, color); OnlyFogSurface = SDL_DisplayFormat(s); SDL_SetAlpha(OnlyFogSurface, SDL_SRCALPHA | SDL_RLEACCEL, FogOfWarOpacity); VideoPaletteListRemove(s); SDL_FreeSurface(s); // // Generate Alpha Fog surface. // if (FogGraphic->Surface->format->BytesPerPixel == 1) { s = SDL_DisplayFormat(FogGraphic->Surface); SDL_SetAlpha(s, SDL_SRCALPHA | SDL_RLEACCEL, FogOfWarOpacity); } else { // Copy the top row to a new surface SDL_PixelFormat *f = FogGraphic->Surface->format; s = SDL_CreateRGBSurface(SDL_SWSURFACE, FogGraphic->Surface->w, PixelTileSize.y, f->BitsPerPixel, f->Rmask, f->Gmask, f->Bmask, f->Amask); SDL_LockSurface(s); SDL_LockSurface(FogGraphic->Surface); for (int i = 0; i < s->h; ++i) { memcpy(reinterpret_cast<Uint8 *>(s->pixels) + i * s->pitch, reinterpret_cast<Uint8 *>(FogGraphic->Surface->pixels) + i * FogGraphic->Surface->pitch, FogGraphic->Surface->w * f->BytesPerPixel); } SDL_UnlockSurface(s); SDL_UnlockSurface(FogGraphic->Surface); // Convert any non-transparent pixels to use FogOfWarOpacity as alpha SDL_LockSurface(s); for (int j = 0; j < s->h; ++j) { for (int i = 0; i < s->w; ++i) { Uint32 c = *reinterpret_cast<Uint32 *>(&reinterpret_cast<Uint8 *>(s->pixels)[i * 4 + j * s->pitch]); Uint8 a; Video.GetRGBA(c, s->format, &r, &g, &b, &a); if (a) { c = Video.MapRGBA(s->format, r, g, b, FogOfWarOpacity); *reinterpret_cast<Uint32 *>(&reinterpret_cast<Uint8 *>(s->pixels)[i * 4 + j * s->pitch]) = c; } } } SDL_UnlockSurface(s); } AlphaFogG = CGraphic::New(""); AlphaFogG->Surface = s; AlphaFogG->Width = PixelTileSize.x; AlphaFogG->Height = PixelTileSize.y; AlphaFogG->GraphicWidth = s->w; AlphaFogG->GraphicHeight = s->h; AlphaFogG->NumFrames = 16;//1; AlphaFogG->GenFramesMap(); AlphaFogG->UseDisplayFormat(); } VisibleTable.clear(); VisibleTable.resize(Info.MapWidth * Info.MapHeight); }
int game::pause(SDL_Surface* screen) //shows he menu { int x,y; bool run=true; //bool variable for the menu's for loop const int NUMMENU=2;//we have 2 menu item const char* array[NUMMENU] = {"Continue","Exit"}; //the label of these are these SDL_Surface* menu[NUMMENU];//we need surface for them bool selected[NUMMENU] = {0,0};//a boolean array for each menu item, true if it is selected SDL_Color colors[2] = {{255,255,255},{255,0,0}}; //white and red color for(int i=0;i<NUMMENU;i++) menu[i]=TTF_RenderText_Solid(font,array[i],colors[0]); //make all of the white menus SDL_Rect pos[NUMMENU]; //we store the position in here for(int i=0;i<NUMMENU;i++) { pos[i].x=screen->clip_rect.w/2-menu[i]->clip_rect.w/2; //put it approxemately to the center of the screen pos[i].y=screen->clip_rect.h/2+i*(menu[i]->clip_rect.h); } SDL_Event menuevent; //event SDL_Surface* alpha=SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,screen->w,screen->h,32,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask); //create a new layer SDL_FillRect(alpha,&screen->clip_rect,SDL_MapRGB(screen->format,0x00,0x00,0x00)); //which we fill with black SDL_SetAlpha(alpha,SDL_SRCALPHA,129); //and use it for alpha blending, because it's a cool effect SDL_BlitSurface(alpha,NULL,screen,NULL); //then show it SDL_FreeSurface(alpha); //we don't need it anymore while(run) { SDL_WaitEvent(&menuevent); //OK, I think, that's new, we'll wait until an event happened, if there is no event //the program will sleep in this function, so less CPU power is needed, we don't need //to regulate the FPS switch(menuevent.type) { case SDL_QUIT: //if we're exiting, than free the surfaces and exit for(int i=0;i<NUMMENU;i++) SDL_FreeSurface(menu[i]); return 1; case SDL_MOUSEMOTION: //if the mouse is moved x=menuevent.motion.x; //then get the coordinates y=menuevent.motion.y; for(int i=0;i<NUMMENU;i++) //we go throught all of the element { //and check if we are inside one of them if(x>=pos[i].x && x <= (pos[i].x + menu[i]->clip_rect.w) && y>=pos[i].y && y <= (pos[i].y + menu[i]->clip_rect.h)) { if(!selected[i]) //if so, then we check that is it already selected { SDL_FreeSurface(menu[i]); //if not, then free the surface and make a red one menu[i]=TTF_RenderText_Solid(font,array[i],colors[1]); selected[i]=1; //and select the surface } }else{ //if we're not selecting one if(selected[i]) //we check, that is it selected { SDL_FreeSurface(menu[i]); //if so, then we delete and create a white one. menu[i]=TTF_RenderText_Solid(font,array[i],colors[0]); selected[i]=0; //and unselect it } } } break; case SDL_MOUSEBUTTONDOWN: //if the mouse button was pressed x=menuevent.button.x; //get the coordinates y=menuevent.button.y; for(int i=0;i<NUMMENU;i++) //do the same check { if(x>=pos[i].x && x <= (pos[i].x + menu[i]->clip_rect.w) && y>=pos[i].y && y <= (pos[i].y + menu[i]->clip_rect.h)) { for(int j=0;j<NUMMENU;j++) //if we clicked one menuitem, we free the menus and return the number SDL_FreeSurface(menu[j]); //of the clicked menu return i; } } break; case SDL_KEYDOWN: //if we press a key if(menuevent.key.keysym.sym==SDLK_ESCAPE) //which escape { for(int i=0;i<NUMMENU;i++) SDL_FreeSurface(menu[i]); return 0; //than return to the game } break; } for(int i=0;i<NUMMENU;i++) SDL_BlitSurface(menu[i],NULL,screen,&pos[i]); //show the menu SDL_Flip(screen); //and actually show it in the screen } }