1. #include "CPGraphics.h"
  2.  
  3. // Class startup. Still requires Init, though.
  4. CPGraphicsEngine::CPGraphicsEngine(void)
  5. {
  6.     m_initialized = false;
  7. #ifdef USE_SDL
  8.     m_screen = NULL;
  9.     m_font = NULL;
  10. #else
  11.     m_spriteHandler = NULL;
  12. #endif
  13. }
  14.  
  15. // Class cleanup.
  16. CPGraphicsEngine::~CPGraphicsEngine(void)
  17. {
  18.     if(m_initialized)
  19.     {
  20. #ifdef USE_SDL
  21.         //Close the font that was used
  22.         TTF_CloseFont( m_font );
  23.  
  24.         SDL_FreeSurface(m_screen);
  25.         //SDL_quit();
  26. #else
  27.         if (m_spriteHandler != NULL)
  28.             m_spriteHandler->Release();
  29.         if (m_font != NULL)
  30.             m_font->Release();
  31. #endif
  32.     }
  33.  
  34. }
  35.  
  36. // Initialize the graphics engine (DX or SDL)
  37. bool CPGraphicsEngine::Init_Graphics(long windowPointer /*hwnd*/, int width, int height, int fullscreen)
  38. {
  39.     m_initialized = true;
  40. #ifdef USE_SDL
  41.     #ifdef USE_OPENGL
  42.     // SDL + OpenGL
  43.     // Try to use OpenGL
  44.     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
  45.  
  46.     //Create Window
  47.     if( SDL_SetVideoMode( width, height, 32, SDL_OPENGL ) == NULL )
  48.     {
  49.         cout << "ERROR: Unable to set Video Mode (" << width << "x" << height << "x32)" << endl;
  50.         return false;
  51.     }
  52.  
  53.     //Initialize OpenGL
  54.     if( init_GL(width,height,fullscreen) == false )
  55.     {
  56.         cout << "ERROR: Unable to Init OpenGL" << endl;
  57.         return false;
  58.     }
  59.     SDL_WM_SetCaption( "BugHunt 2942AD (SDL + OpenGL)", NULL );
  60.     #else
  61.     //SDL + SDL_gfx
  62.     // Setup the screen:
  63.     Uint32 tempFlags = SDL_SWSURFACE; // | SDL_DOUBLEBUF | SDL_FULLSCREEN;
  64.     if ( fullscreen ) tempFlags = tempFlags && SDL_FULLSCREEN;
  65.  
  66.     m_screen = SDL_SetVideoMode( width, height, 32, tempFlags );
  67.     if (m_screen == NULL)
  68.     {
  69.         cout << "ERROR: Unable to set Video Mode (" << width << "x" << height << "x32)" << endl;
  70.         m_initialized = false;
  71.         return false;
  72.     }
  73.     SDL_WM_SetCaption( "BugHunt 2942AD (SDL)", NULL );
  74.     #endif
  75.  
  76.     // SDL text fonts
  77.     //Initialize SDL_ttf
  78.     if( TTF_Init() == -1 )
  79.     {
  80.         cout << "Error: Unable to initialize True Type Fonts" << endl;
  81.         return false;
  82.     }
  83.  
  84.     //Open the font
  85.     m_font = TTF_OpenFont( "Comic_Sans_MS_Bold.ttf", 14 ); // pitch size
  86.  
  87. #else
  88.     if (!Init_Direct3D((HWND)windowPointer, width, height, fullscreen))
  89.         m_initialized = false;
  90.     else
  91.     {
  92.         //create sprite handler object
  93.         HRESULT result = D3DXCreateSprite(d3ddev, &m_spriteHandler);
  94.         if (result != D3D_OK)
  95.             m_initialized = false;
  96.        
  97.         // load the font
  98.         result = D3DXCreateFont( d3ddev, 14, 0, FW_NORMAL, 1, false, DEFAULT_CHARSET,
  99.                     OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
  100.                     "Comic Sans", &m_font); // Arial Black
  101.         if (result != D3D_OK)
  102.             m_initialized = false;
  103.     }
  104.  
  105.     m_inFrame = false;
  106. #endif
  107.     return m_initialized;
  108. }
  109.  
  110. // Called at the start of rendering a single frame.
  111. // in SDL this is probably a no-op, except maybe to clear the screen...
  112. bool CPGraphicsEngine::StartFrame()
  113. {
  114. #ifdef USE_SDL
  115.     #ifdef USE_OPENGL
  116.     //Clear the screen
  117.     glClear( GL_COLOR_BUFFER_BIT );
  118.     #else
  119.     Uint32 black = SDL_MapRGB( m_screen->format, 0, 0, 0 );
  120.     SDL_FillRect(m_screen, NULL, black);
  121.     #endif
  122.     return true;
  123. #else
  124.     if(!m_inFrame)
  125.     {
  126.         HRESULT result;
  127.         result = d3ddev->BeginScene();
  128.         //if (result)
  129.         //{        
  130.             //erase the entire background
  131.             d3ddev->ColorFill(backbuffer, NULL, D3DCOLOR_XRGB(0,0,0));
  132.  
  133.             //start sprite handler
  134.             m_spriteHandler->Begin(D3DXSPRITE_ALPHABLEND);
  135.  
  136.             m_inFrame = true;
  137.             return true;
  138.         //}
  139.         //else return false;
  140.     }
  141. #endif
  142. }
  143.  
  144. // Called at the end of rendering a single frame.
  145. // This probably includes "flip buffer" in SDL
  146. void CPGraphicsEngine::EndFrame()
  147. {
  148. #ifdef USE_SDL
  149.     #ifdef USE_OPENGL
  150.     //Update screen
  151.     SDL_GL_SwapBuffers();
  152.     #else
  153.     SDL_Flip( m_screen );
  154.     #endif
  155. #else
  156.     if (m_inFrame)
  157.     {
  158.         //stop drawing
  159.         m_spriteHandler->End();
  160.  
  161.         //stop rendering
  162.         d3ddev->EndScene();
  163.  
  164.         //display the back buffer on the screen
  165.         d3ddev->Present(NULL, NULL, NULL, NULL);
  166.        
  167.         m_inFrame = false;
  168.     }
  169. #endif
  170. }
  171.  
  172. //Draw a texture to the screen. This is full featured with rotation and scaling.
  173. void CPGraphicsEngine::DrawTexture(float x, float y, int width, int height, float sx, float sy, float angle, unsigned char alpha, CPTexture& texture, CPRECT *rc, bool FixAngle)
  174. {
  175.     // some angles are messed up, got to add 90 before drawing
  176.     int tAngle = angle;
  177.     if (FixAngle)
  178.     {
  179.         tAngle += 90;
  180.         if (tAngle < 0)
  181.             tAngle = 360 + tAngle;
  182.         if (tAngle >= 360)
  183.             tAngle = tAngle - 360;
  184.     }
  185.  
  186. #ifdef USE_SDL
  187.     tAngle = -tAngle; // fix difference in orientation of DX vs. SDL
  188.  
  189.     if (m_initialized) // Don't draw before we are initialized.
  190.     {
  191.         SDL_Rect src;
  192.         SDL_Rect dest;
  193.         int centerX, centerY;
  194.         centerX = x + (width/2);
  195.         centerY = y + (height/2);
  196.  
  197.         if (rc != NULL) // use the part of the image they told us about...
  198.         {
  199.             src.x = rc->left;
  200.             src.y = rc->top;
  201.             src.h = rc->bottom - rc->top;
  202.             src.w = rc->right - rc->left;
  203.         }
  204.         else // ... or use the whole thing.
  205.         {
  206.             src.x = 0;
  207.             src.y = 0;
  208.             src.h = height;
  209.             src.w = width;
  210.         }
  211.  
  212.         #ifdef USE_OPENGL
  213.         // Convert to OpenGL texture ... FIRST ... this could be done as they are loaded to save time
  214.         // This is a handle to our texture object
  215.         GLuint oGLTexture;
  216.         SDL_Surface *surface;
  217.    
  218.         // create a temporary image (extra blit, but allows us to take one frame of an animation)
  219.         surface = CPTexture::CreateDisplayFormatSurface(width, height);
  220.    
  221.         // blit the part of the original image that we need to the current one.
  222.         SDL_BlitSurface( (SDL_Surface*)(texture.GetNativeTexture()), &src, surface, NULL );
  223.    
  224.         // Have OpenGL generate a texture object handle for us
  225.         glGenTextures( 1, &oGLTexture );
  226.    
  227.         // Bind the texture object
  228.         glBindTexture( GL_TEXTURE_2D, oGLTexture );
  229.    
  230.         // Set the texture's stretching properties
  231.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  232.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  233.    
  234.         // Edit the texture object's image data using the information SDL_Surface gives us
  235.         glTexImage2D( GL_TEXTURE_2D, 0, texture.nOfColors, surface->w, surface->h, 0,
  236.             texture.texture_format, GL_UNSIGNED_BYTE, surface->pixels );
  237.    
  238.         int SQUARE_WIDTH  = width  * sx;
  239.         int SQUARE_HEIGHT = height * sy;
  240.    
  241.         // OK - now DRAW it
  242.    
  243.         //Move to offset (x,y) of destination
  244.         glTranslatef(x+(width/2), y+(height/2), 0 );
  245.         // offset to center the sprite
  246.  
  247.         // now rotate it
  248.         glRotatef( angle, 0.0, 0.0, 1.0 ); 
  249.    
  250.         glBegin( GL_QUADS );
  251.             //Top-left vertex (corner)
  252.             glTexCoord2i( 0, 0 );
  253.             glVertex3f( -(SQUARE_WIDTH/2), -(SQUARE_HEIGHT/2), 0 );
  254.    
  255.             //Top-right vertex (corner)
  256.             glTexCoord2i( 1, 0 );
  257.             glVertex3f( (SQUARE_WIDTH/2), -(SQUARE_HEIGHT/2), 0 );
  258.    
  259.             //Bottom-right vertex (corner)
  260.             glTexCoord2i( 1, 1 );
  261.             glVertex3f( (SQUARE_WIDTH/2), (SQUARE_HEIGHT/2), 0 );
  262.    
  263.             //Bottom-left vertex (corner)
  264.             glTexCoord2i( 0, 1 );
  265.             glVertex3f( -(SQUARE_WIDTH/2), (SQUARE_HEIGHT/2), 0 );
  266.         glEnd();
  267.    
  268.         //Reset
  269.         glLoadIdentity();
  270.    
  271.         // Free the SDL_Surface only if it was successfully created
  272.         SDL_FreeSurface( surface );
  273.    
  274.         // delete the openGl texture handle
  275.         glDeleteTextures( 1, &oGLTexture );
  276.  
  277.         return;
  278.  
  279.         #else
  280.         // Use SDL_gfx stuff:
  281.         // if no rotation and no scaling ...
  282.         if ((abs(angle) <= 1.0f) && (sx == 1.0f) && (sy == 1.0f))
  283.         {
  284.             dest.x = x;//centerX - (width/2);
  285.             dest.y = y;//centerY - (height/2);
  286.             dest.w = width;//centerX + (width/2);
  287.             dest.h = height;//centerY + (height/2);
  288.  
  289.             // draw to screen:
  290.             SDL_BlitSurface( (SDL_Surface*)(texture.GetNativeTexture()), &src, m_screen, &dest);
  291.         }
  292.         else
  293.         {
  294.             SDL_Surface *optSurf,*rotZoomPic;
  295.  
  296.             // create a temporary image (extra blit, but allows us to take one frame of an animation)
  297.             // TODO: Optimize when rc is NULL to not do this...
  298.             optSurf = CPTexture::CreateDisplayFormatSurface(width, height);
  299.  
  300.             // blit the part of the original image that we need to the current one.
  301.             SDL_BlitSurface( (SDL_Surface*)(texture.GetNativeTexture()), &src, optSurf, NULL );
  302.  
  303.             // draw with rotate/scale.
  304.             // TODO: If rotate = 0, scale = 1, optimize and just use SDL_BlitSurface
  305.             rotZoomPic = rotozoomSurfaceXY( optSurf, static_cast<double>(tAngle), sx, sy, SMOOTHING_OFF);
  306.  
  307.             //Set all pixels of color R:0xFF, G:0x00, B:0xFF to be transparent
  308.             Uint32 colorkey = SDL_MapRGB( rotZoomPic->format, 0, 0, 0);
  309.             SDL_SetColorKey( rotZoomPic, SDL_SRCCOLORKEY, colorkey );
  310.  
  311.             // final extents (rotating and scaling changes this)
  312.             dest.x = centerX - (rotZoomPic->w/2);
  313.             dest.y = centerY - (rotZoomPic->h/2);
  314.             dest.w = rotZoomPic->w;
  315.             dest.h = rotZoomPic->h;
  316.    
  317.             // draw to screen, finally:
  318.             SDL_BlitSurface( rotZoomPic,NULL, m_screen, &dest );
  319.  
  320.             // cleanup:
  321.             SDL_FreeSurface(rotZoomPic);
  322.             SDL_FreeSurface(optSurf);
  323.         }
  324.         #endif
  325.     }
  326. #else
  327.     if (m_initialized)
  328.     {
  329.         if (!texture.isSurface)
  330.         {
  331.             const int halfWidth = width/2; //desc.Width >> 1;
  332.             const int halfHeight = height/2; //desc.Height >> 1;
  333.  
  334.             D3DXMATRIX rotate, trasl, scale, result;
  335.  
  336.             D3DXMatrixIdentity(&result);
  337.             D3DXMatrixTranslation(&trasl, -halfWidth, -halfHeight, 0);
  338.             D3DXMatrixMultiply(&result, &result, &trasl);
  339.             D3DXMatrixScaling(&scale, sx, sy, 1.0f);
  340.             D3DXMatrixMultiply(&result, &result, &scale);
  341.             D3DXMatrixRotationZ(&rotate, D3DXToRadian(tAngle));
  342.             D3DXMatrixMultiply(&result, &result, &rotate);
  343.             D3DXMatrixTranslation(&trasl, +halfWidth, +halfHeight, 0);
  344.             D3DXMatrixMultiply(&result, &result, &trasl);
  345.             D3DXMatrixTranslation(&trasl, x, y, 0);
  346.             D3DXMatrixMultiply(&result, &result, &trasl);
  347.  
  348.             m_spriteHandler->SetTransform(&result);
  349.             m_spriteHandler->Draw((LPDIRECT3DTEXTURE9)(texture.GetNativeTexture()), (RECT *)rc, NULL, NULL, (0xFFFFFF) | (alpha << 24));
  350.         }
  351.     }
  352. #endif
  353. }
  354.  
  355. // NOTE: This is used to draw the background image(s) for each level and the health bars //
  356. // ALSO: It does NOT use the same ScaleX and ScaleY that the avatars use //
  357. //Draw a texture in a slightly simpler version--scales it to fit from source rect to destination rect.
  358. void CPGraphicsEngine::DrawStretchTexture(CPTexture& texture, CPRECT sourceRect, CPRECT destRect)
  359. {
  360. #ifdef USE_SDL
  361.     #ifdef USE_OPENGL
  362.     // Convert to OpenGL texture ... FIRST ... this could be done as they are loaded to save time
  363.     // This is a handle to our texture object
  364.     GLuint oGLTexture;
  365.     SDL_Surface *surface;
  366.  
  367.     int height = sourceRect.bottom - sourceRect.top;
  368.     int width = sourceRect.right - sourceRect.left;
  369.  
  370.     // convert source to SDL_Rect
  371.     SDL_Rect src;
  372.     src.x = sourceRect.left;
  373.     src.y = sourceRect.top;
  374.     src.h = sourceRect.bottom - sourceRect.top;
  375.     src.w = sourceRect.right  - sourceRect.left;
  376.  
  377.     // create a temporary image (extra blit, but allows us to take one frame of an animation)
  378.     surface = CPTexture::CreateDisplayFormatSurface(width, height);
  379.  
  380.     // blit the part of the original image that we need to the current one.
  381.     SDL_BlitSurface( (SDL_Surface*)(texture.GetNativeTexture()), &src, surface, NULL );
  382.  
  383.     // Have OpenGL generate a texture object handle for us
  384.     glGenTextures( 1, &oGLTexture );
  385.  
  386.     // Bind the texture object
  387.     glBindTexture( GL_TEXTURE_2D, oGLTexture );
  388.  
  389.     // Set the texture's stretching properties
  390.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  391.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  392.  
  393.     // Edit the texture object's image data using the information SDL_Surface gives us
  394.     glTexImage2D( GL_TEXTURE_2D, 0, texture.nOfColors, surface->w, surface->h, 0,
  395.                       texture.texture_format, GL_UNSIGNED_BYTE, surface->pixels );
  396.  
  397.     int SQUARE_HEIGHT = destRect.bottom - destRect.top;
  398.     int SQUARE_WIDTH  = destRect.right - destRect.left;
  399.  
  400.     // OK - now DRAW it
  401.  
  402.     //Move to offset (x,y) of destination
  403.     glTranslatef(destRect.left, destRect.top, 0 );
  404.  
  405.     glBegin( GL_QUADS );
  406.         //Top-left vertex (corner)
  407.         glTexCoord2i( 0, 0 );
  408.         glVertex3f( 0, 0, 0 );
  409.  
  410.         //Top-right vertex (corner)
  411.         glTexCoord2i( 1, 0 );
  412.         glVertex3f( SQUARE_WIDTH, 0, 0 );
  413.  
  414.         //Bottom-right vertex (corner)
  415.         glTexCoord2i( 1, 1 );
  416.         glVertex3f( SQUARE_WIDTH, SQUARE_HEIGHT, 0 );
  417.  
  418.         //Bottom-left vertex (corner)
  419.         glTexCoord2i( 0, 1 );
  420.         glVertex3f( 0, SQUARE_HEIGHT, 0 );
  421.     glEnd();
  422.  
  423.     //Reset
  424.     glLoadIdentity();
  425.  
  426.     // Free the SDL_Surface
  427.     SDL_FreeSurface( surface );
  428.  
  429.     // delete the openGl texture handle
  430.     glDeleteTextures( 1, &oGLTexture );
  431.     return;
  432.     #else
  433.  
  434.     // use SGL_gfx stuff:
  435.     double scaleX, scaleY;
  436. //  SDL_Surface* rotZoomPic;
  437.     SDL_Rect src, dst;
  438.  
  439.     src.x = sourceRect.left;
  440.     src.y = sourceRect.top;
  441.     src.h = sourceRect.bottom - sourceRect.top;
  442.     src.w = sourceRect.right - sourceRect.left;
  443.  
  444.     dst.x = destRect.left;
  445.     dst.y = destRect.top;
  446.     dst.h = destRect.bottom - destRect.top;
  447.     dst.w = destRect.right - destRect.left;
  448.  
  449.     scaleX = static_cast<double>(dst.w) / static_cast<double>(src.w);
  450.     scaleY = static_cast<double>(dst.h) / static_cast<double>(src.h);
  451. // Removing this doubles the FPS ... likely because the BG surfaces use this and they are 2048x2048x32bpp in size
  452. //  rotZoomPic = rotozoomSurfaceXY( (SDL_Surface*)(texture.GetNativeTexture()), 0.0, scaleX, scaleY, SMOOTHING_OFF);
  453.  
  454. //  src.x = src.x * scaleX;
  455. //  src.y = src.y * scaleY;
  456.     src.h = src.h * scaleY;
  457.     src.w = src.w * scaleX;
  458.  
  459. //  SDL_BlitSurface( rotZoomPic, &src, m_screen, &dst );
  460.     SDL_BlitSurface( (SDL_Surface*)(texture.GetNativeTexture()), &src, m_screen, &dst );
  461.  
  462. //  SDL_FreeSurface(rotZoomPic);
  463.     #endif
  464. #else
  465.     if (texture.isSurface)
  466.         d3ddev->StretchRect(texture.m_nativeSurface,  (RECT *)(&sourceRect), backbuffer, (RECT *)(&destRect), D3DTEXF_NONE);
  467. #endif
  468. }
  469.  
  470. void CPGraphicsEngine::DrawTextToRect(std::string text, CPRECT rect, CPCOLOR color)
  471. {
  472. #ifndef USE_SDL
  473.     m_font->DrawTextA(  NULL,
  474.                 text.c_str(),
  475.                 text.length(),
  476.                 (LPRECT)&rect,
  477.                 DT_LEFT, //DT_RIGHT,
  478.                 color
  479.              );
  480. #else
  481.     // TTF fonts
  482.     //The color of the font
  483.     SDL_Color textColor = { CPCOLOR_REDVALUE(color), CPCOLOR_GREENVALUE(color), CPCOLOR_BLUEVALUE(color) };
  484.     //Render the text
  485.     SDL_Surface *message = TTF_RenderText_Solid( m_font, text.c_str(), textColor );
  486.     //If there was an error in rendering the text
  487.     if( message == NULL )
  488.      {
  489.         cout << "Error rendering text: " << text << endl;
  490.         return;
  491.      }
  492.  
  493.     //Holds offsets
  494.     SDL_Rect offset;
  495.  
  496.     //Get offsets
  497.     offset.x = rect.left;
  498.     offset.y = rect.top;
  499.  
  500.     //Blit
  501.     SDL_BlitSurface( message, NULL, m_screen, &offset );
  502. #endif
  503. }
  504.  
  505.  
  506. // Init object
  507. CPTexture::CPTexture()
  508. {
  509. #ifndef USE_SDL
  510.     m_nativeTexture = NULL;
  511. #endif
  512.     m_nativeSurface = NULL;
  513.     isSurface = false;
  514. }
  515.  
  516.  
  517. // cleanup object
  518. CPTexture::~CPTexture(void)
  519. {
  520.     if(m_nativeSurface != NULL)
  521. #ifdef USE_SDL
  522.         SDL_FreeSurface(m_nativeSurface);
  523. #else
  524.         m_nativeSurface->Release();
  525.     if(!m_nativeTexture == NULL)
  526.         m_nativeTexture->Release();
  527. #endif
  528. }
  529.  
  530. // Load a texture
  531. bool CPTexture::LoadTextureFromFile(char* filename, CPCOLOR color, bool createDirectlyInVideoMemory)
  532. {
  533. #ifdef USE_SDL
  534.   SDL_Surface* loadedImage = NULL;
  535.    SDL_Surface* optimizedImage = NULL;
  536.  
  537.    cout << "Loading from file: " << filename << endl;
  538.  
  539.    // load the image:
  540.    loadedImage = IMG_Load( filename );
  541.    
  542.    // optimize it for the screen:
  543.    if ( loadedImage != NULL )
  544.    {
  545.       optimizedImage = SDL_DisplayFormat( loadedImage );
  546.      
  547.       SDL_FreeSurface( loadedImage ); // (don't need anymore)
  548.    }
  549.    
  550.    // set cyan to be transparent
  551.    if( optimizedImage != NULL )
  552.    {
  553.       //Map the color key
  554.       Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0xFF, 0, 0xFF );
  555.       //Set all pixels of color R 0xFF, G 0, B 0xFF to be transparent
  556.       SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
  557.    }
  558.    
  559.    m_nativeSurface = optimizedImage;
  560.  
  561.     #ifdef USE_OPENGL
  562.     // Convert to OpenGL format
  563.     // Check that the image's width is a power of 2
  564.     if ( (optimizedImage->w % 2) != 0 )
  565.     {
  566.         cout << "warning: image.bmp's width is not a power of 2 (w=" << optimizedImage->w << ")" << endl;
  567.     }
  568.    
  569.     // Also check if the height is a power of 2
  570.     if ( (optimizedImage->h % 2) != 0 )
  571.     {
  572.         cout << "warning: image.bmp's height is not a power of 2 (h=" << optimizedImage->h << ")"  << endl;
  573.     }
  574.  
  575.     // get the number of channels in the SDL surface
  576.     nOfColors = optimizedImage->format->BytesPerPixel;
  577.     if (nOfColors == 4)     // contains an alpha channel
  578.     {
  579.         if (optimizedImage->format->Rmask == 0x000000ff)
  580.             texture_format = GL_RGBA;
  581.         else
  582.             texture_format = GL_BGRA;
  583.     }
  584.     else if (nOfColors == 3)     // no alpha channel
  585.     {
  586.         if (optimizedImage->format->Rmask == 0x000000ff)
  587.             texture_format = GL_RGB;
  588.         else
  589.             texture_format = GL_BGR;
  590.     }
  591.     else
  592.     {
  593.         cout    << "warning: the image is not truecolor..  this will probably break (noOfColors="
  594.             << nOfColors << ")"
  595.             << endl;
  596.         // this error should not go unhandled
  597.     }
  598.     #endif
  599. // ...
  600.    return true;
  601. #else
  602.     if (!createDirectlyInVideoMemory)
  603.     {
  604.         m_nativeTexture = LoadTexture(filename, (D3DCOLOR)color);
  605.         if (m_nativeTexture == NULL)
  606.             return false;
  607.         isSurface = false;
  608.         return true;
  609.     }
  610.     else
  611.     {
  612.         m_nativeSurface = LoadSurface(filename, (D3DCOLOR)color);
  613.         if (m_nativeSurface == NULL)
  614.             return false;
  615.         isSurface = true;
  616.         return true;
  617.     }
  618. #endif
  619. }
  620.  
  621. bool CPTexture::CreateOffscreenTexture(int width, int height)
  622. {
  623. #ifdef USE_SDL
  624.     return true;
  625. #else
  626.     HRESULT result = d3ddev->CreateOffscreenPlainSurface(
  627.         width, height,
  628.         D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT,
  629.         &m_nativeSurface,
  630.         NULL);
  631.  
  632.     if (result != D3D_OK)
  633.         return false;
  634.     else
  635.     {
  636.         isSurface = true;
  637.         return true;
  638.     }
  639. #endif
  640. }
  641.  
  642. // Get the DX or SDL object (mostly for use by CPGraphicsEngine...)
  643. long CPTexture::GetNativeTexture()
  644. {
  645. #ifdef USE_SDL
  646.     return (long)m_nativeSurface;
  647. #else
  648.     if (isSurface) return (long)m_nativeSurface;
  649.     else return (long)m_nativeTexture;
  650. #endif
  651. }
  652.  
  653. // checks if surface created. "return true;" in Linux.
  654. bool CPTexture::CreatedInVideoMemory()
  655. {
  656. #ifdef USE_SDL
  657.     return true;
  658. #else
  659.     return isSurface;
  660. #endif
  661. }
  662.  
  663. #ifdef USE_SDL
  664. bool IntersectCPRect( CPRECT& dest, const CPRECT src1, const CPRECT src2)
  665. {
  666.   int px0,py0,px1,py1;
  667.   int cx0,cy0,cx1,cy1;
  668.   int rx0,ry0,rx1,ry1;
  669.  
  670.   // fill in default (NULL) result rectangle
  671.  
  672.   dest.left = 0;    // x
  673.   dest.top = 0; // y
  674.   dest.right = 0;   // w
  675.   dest.bottom = 0;  // h
  676.  
  677.   // get coordinates of the rectangles
  678.  
  679.   px0 = src1.left;
  680.   py0 = src1.top;
  681.   px1 = src1.left + src1.right - 1;
  682.   py1 = src1.top + src1.bottom - 1;
  683.  
  684.   cx0 = src2.left;
  685.   cy0 = src2.top;
  686.   cx1 = src2.left + src2.right - 1;
  687.   cy1 = src2.top + src2.bottom - 1;
  688.  
  689.   // check if the rectangles intersect
  690.  
  691.   //if ((cx0 < px0) && (cx1 < px0))
  692.   if (cx1 < px0)
  693.     return false;
  694.  
  695.   //  if((cx0 > px1) && (cx1 > px1) )
  696.   if(cx0 > px1)
  697.     return false;
  698.  
  699. //  if ((cy0 < py0) && (cy1 < py0))
  700.   if (cy1 < py0)
  701.         return false;
  702.  
  703. //  if ((cy0 > py1) && (cy1 > py1))
  704.   if (cy0 > py1)
  705.     return false;
  706.  
  707.   // intersect x
  708.  
  709.   if(cx0 <= px0) rx0 = px0;
  710.   else rx0 = cx0;
  711.  
  712.   if(cx1 >= px1) rx1 = px1;
  713.   else rx1 = cx1;
  714.  
  715.   // intersect y
  716.  
  717.   if(cy0 <= py0) ry0 = py0;
  718.   else ry0 = cy0;
  719.  
  720.   if(cy1 >= py1) ry1 = py1;
  721.   else ry1 = cy1;
  722.  
  723.   // fill in result rect
  724.  
  725.   dest.left = rx0;
  726.   dest.top = ry0;
  727.   dest.right = (rx1-rx0)+1;
  728.   dest.bottom = (ry1-ry0)+1;
  729.  
  730. return true;
  731. };
  732.  
  733. SDL_Surface* CPTexture::CreateDisplayFormatSurface(int width, int height)
  734. {
  735.     Uint32 rmask, gmask, bmask, amask;
  736.        
  737.     #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  738.         rmask = 0xff000000;
  739.         gmask = 0x00ff0000;
  740.         bmask = 0x0000ff00;
  741.         amask = 0x000000ff;
  742.     #else
  743.         rmask = 0x000000ff;
  744.         gmask = 0x0000ff00;
  745.         bmask = 0x00ff0000;
  746.         amask = 0xff000000;
  747.     #endif
  748.  
  749.     SDL_Surface* newSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, bmask, gmask, rmask, amask);
  750.     SDL_Surface* optimizedSurface = SDL_DisplayFormat(newSurface);
  751.  
  752.     SDL_FreeSurface(newSurface);
  753.  
  754.     return optimizedSurface;
  755. }
  756.  
  757. int CPTexture::GetWidth()
  758. {
  759.     return m_nativeSurface->w;
  760. }
  761.  
  762. int CPTexture::GetHeight()
  763. {
  764.     return m_nativeSurface->h;
  765. }
  766.  
  767.     #ifdef USE_OPENGL
  768.     bool init_GL(int width, int height, int fullscreen)
  769.     {
  770.         glEnable( GL_TEXTURE_2D );      // added
  771.        
  772.         //Set clear color
  773.         glClearColor( 0, 0, 0, 0 );
  774.    
  775.         glViewport( 0, 0, width, height );  // added
  776.         glClear( GL_COLOR_BUFFER_BIT );     // added
  777.        
  778.         //Set projection
  779.         glMatrixMode( GL_PROJECTION );
  780.         glLoadIdentity();
  781.         glOrtho( 0, width, height, fullscreen, -1, 1 );
  782.        
  783.         //Initialize modelview matrix
  784.         glMatrixMode( GL_MODELVIEW );
  785.         glLoadIdentity();
  786.        
  787.         //If there was any errors
  788.         if( glGetError() != GL_NO_ERROR )
  789.         {
  790.             cout << "Error: Init_GL failed !" << endl;
  791.             return false;
  792.         }
  793.        
  794.         //If everything initialized
  795.         return true;
  796.     }
  797.     #endif
  798. #endif