home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / video / img_settings.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-09-24  |  16.5 KB  |  613 lines

  1. /***************************************************************************
  2.  * img_settings.cpp  -  Image Settings Handler
  3.  *
  4.  * Copyright (C) 2005 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../video/img_settings.h"
  17. #include "../core/game_core.h"
  18. #include "../video/gl_surface.h"
  19. #include "../core/math/utilities.h"
  20. #include "../core/math/size.h"
  21.  
  22. /* *** *** *** *** *** *** cImage_settings_data *** *** *** *** *** *** *** *** *** *** *** */
  23.  
  24. cImage_settings_data :: cImage_settings_data( void )
  25. {
  26.     m_base_settings = 0;
  27.  
  28.     m_int_x = 0;
  29.     m_int_y = 0;
  30.     m_col_rect.clear();
  31.     m_width = 0;
  32.     m_height = 0;
  33.     m_rotation_x = 0;
  34.     m_rotation_y = 0;
  35.     m_rotation_z = 0;
  36.     m_mipmap = 0;
  37.  
  38.     m_type = -1;
  39.     m_ground_type = GROUND_NORMAL;
  40.     m_obsolete = 0;
  41. }
  42.  
  43. cImage_settings_data :: ~cImage_settings_data( void )
  44. {
  45.  
  46. }
  47.  
  48. cSize_Float cImage_settings_data :: Get_Surface_Size( SDL_Surface *sdl_surface )
  49. {
  50.     if( !sdl_surface )
  51.     {
  52.         return cSize_Float();
  53.     }
  54.  
  55.     // check if texture needs to get downscaled
  56.     float new_w = static_cast<float>(Get_Power_of_2( sdl_surface->w ));
  57.     float new_h = static_cast<float>(Get_Power_of_2( sdl_surface->h ));
  58.     
  59.     // todo : add check for maximum opengl texture size
  60.     // if image settings dimension
  61.     if( m_width > 0 && m_height > 0 )
  62.     {
  63.         /* downscale to fit best for the current resolution
  64.          * uses the first dimension which is not smaller as the default scale
  65.         */
  66.         while( new_w * 0.5f > m_width * global_upscalex && new_h * 0.5f > m_height * global_upscaley )
  67.         {
  68.             new_w *= 0.5f;
  69.             new_h *= 0.5f;
  70.         }
  71.  
  72.         // if texture detail below low
  73.         if( pVideo->texture_detail < 0.25f )
  74.         {
  75.             // half size only if texture size is high
  76.             if( new_w * 0.8f > m_width * global_upscalex && new_h * 0.8f > m_height * global_upscaley )
  77.             {
  78.                 new_w *= 0.5f;
  79.                 new_h *= 0.5f;
  80.             }
  81.         }
  82.     }
  83.  
  84.     return cSize_Float( new_w, new_h);
  85. }
  86.  
  87. void cImage_settings_data :: Apply( GL_Surface *image )
  88. {
  89.     // empty image
  90.     if( !image )
  91.     {
  92.         printf( "Error : surface for base %s does not exist\n", m_base.c_str() );
  93.         return;
  94.     }
  95.  
  96.     // ## int_x/int_y
  97.     image->int_x = static_cast<float>(m_int_x);
  98.     image->int_y = static_cast<float>(m_int_y);
  99.  
  100.     // ## width
  101.     if( m_width > 0 )
  102.     {
  103.         image->start_w = static_cast<float>(m_width);
  104.         image->w = image->start_w;
  105.         image->col_w = image->w;
  106.     }
  107.     // ## height
  108.     if( m_height > 0 )
  109.     {
  110.         image->start_h = static_cast<float>(m_height);
  111.         image->h = image->start_h;
  112.         image->col_h = image->h;
  113.     }
  114.  
  115.     // ## collision rect
  116.     if( m_col_rect.w > 0 && m_col_rect.h > 0 )
  117.     {
  118.         // position
  119.         image->col_pos.x = m_col_rect.x;
  120.         image->col_pos.y = m_col_rect.y;
  121.         // dimension
  122.         image->col_w = m_col_rect.w;
  123.         image->col_h = m_col_rect.h;
  124.     }
  125.  
  126.     // ## rotation x
  127.     if( m_rotation_x != 0 )
  128.     {
  129.         image->base_rotx = static_cast<float>(m_rotation_x);
  130.  
  131.         //image->col_pos = image->col_pos.rotate3d( image->base_rotx, 1, 0, 0 );
  132.         // mirror
  133.         if( image->base_rotx == 180 )
  134.         {
  135.             image->col_pos.y = image->h - ( image->col_h + image->col_pos.y );
  136.         }
  137.     }
  138.     // ## rotation y
  139.     if( m_rotation_y != 0 )
  140.     {
  141.         image->base_roty = static_cast<float>(m_rotation_y);
  142.  
  143.         //image->col_pos = image->col_pos.rotate3d( image->base_roty, 0, 1, 0 );
  144.         // mirror
  145.         if( image->base_roty == 180 )
  146.         {
  147.             image->col_pos.x = image->w - ( image->col_w + image->col_pos.x );
  148.         }
  149.     }
  150.     // ## rotation z
  151.     if( m_rotation_z != 0 )
  152.     {
  153.         image->base_rotz = static_cast<float>(m_rotation_z);
  154.  
  155.         //image->col_pos = image->col_pos.rotate3d( image->base_rotz, 0, 0, 1 );
  156.  
  157.         if( image->base_rotz == 90 )
  158.         {
  159.             // rotate position
  160.             GL_point pos( image->int_x, image->int_y );
  161.             pos = pos.rotate( GL_point( image->w * 0.5f, image->h * 0.5f ), image->base_rotz );
  162.             image->int_x = pos.y;
  163.             image->int_y = pos.x - image->h;
  164.             // rotate collision position
  165.             float orig_x = image->col_pos.x;
  166.             image->col_pos.x = image->h - ( image->col_h + image->col_pos.y );
  167.             image->col_pos.y = orig_x;
  168.  
  169.             // switch width and height
  170.             float orig_w = image->w;
  171.             image->w = image->h;
  172.             image->h = orig_w;
  173.             // switch collision width and height
  174.             float orig_col_w = image->col_w;
  175.             image->col_w = image->col_h;
  176.             image->col_h = orig_col_w;
  177.         }
  178.         // mirror
  179.         else if( image->base_rotz == 180 )
  180.         {
  181.             image->col_pos.y = image->h - ( image->col_h + image->col_pos.y );
  182.         }
  183.         else if( image->base_rotz == 270 )
  184.         {
  185.             // rotate position
  186.             GL_point pos( image->int_x, image->int_y );
  187.             pos = pos.rotate( GL_point( image->w * 0.5f, image->h * 0.5f ), image->base_rotz );
  188.             image->int_x = pos.y - image->w;
  189.             image->int_y = pos.x;
  190.             // rotate collision position
  191.             float orig_x = image->col_pos.x;
  192.             image->col_pos.x = image->col_pos.y;
  193.             image->col_pos.y = orig_x;
  194.  
  195.             // switch width and height
  196.             float orig_w = image->w;
  197.             image->w = image->h;
  198.             image->h = orig_w;
  199.             // switch collision width and height
  200.             float orig_col_w = image->col_w;
  201.             image->col_w = image->col_h;
  202.             image->col_h = orig_col_w;
  203.         }
  204.     }
  205.  
  206.     // ## editor_tags
  207.     if( !m_editor_tags.empty() )
  208.     {
  209.         image->editor_tags = m_editor_tags;
  210.     }
  211.  
  212.     // ## name
  213.     if( !m_name.empty() )
  214.     {
  215.         image->name = m_name;
  216.  
  217.         // finds all "_" and replaces them with " "
  218.         for( string::iterator itr = image->name.begin(); itr != image->name.end(); ++itr )
  219.         {
  220.             // change
  221.             if( *itr == '_' )
  222.             {
  223.                 *itr = ' ';
  224.             }
  225.         }
  226.     }
  227.  
  228.     // ## type
  229.     if( m_type > 0 )
  230.     {
  231.         image->type = m_type;
  232.     }
  233.  
  234.     // ## ground type
  235.     image->ground_type = m_ground_type;
  236.  
  237.     // ## obsolete
  238.     image->obsolete = m_obsolete;
  239. }
  240.  
  241. void cImage_settings_data :: Apply_Base( cImage_settings_data *base_settings_data )
  242. {
  243.     if( !base_settings_data->m_base.empty() )
  244.     {
  245.         m_base = base_settings_data->m_base;
  246.         m_base_settings = base_settings_data->m_base_settings;
  247.     }
  248.  
  249.     m_int_x = base_settings_data->m_int_x;
  250.     m_int_y = base_settings_data->m_int_y;
  251.     m_col_rect = base_settings_data->m_col_rect;
  252.     m_width = base_settings_data->m_width;
  253.     m_height = base_settings_data->m_height;
  254.     m_rotation_x = base_settings_data->m_rotation_x;
  255.     m_rotation_y = base_settings_data->m_rotation_y;
  256.     m_rotation_z = base_settings_data->m_rotation_z;
  257.     m_mipmap = base_settings_data->m_mipmap;
  258.     m_editor_tags = base_settings_data->m_editor_tags;
  259.     m_name = base_settings_data->m_name;
  260.     m_type = base_settings_data->m_type;
  261.     m_author = base_settings_data->m_author;
  262.  
  263.     // only set if this isn't obsolete
  264.     if( !m_obsolete && base_settings_data->m_obsolete )
  265.     {
  266.         m_obsolete = 1;
  267.     }
  268. }
  269.  
  270. /* *** *** *** *** *** *** cImage_settings *** *** *** *** *** *** *** *** *** *** *** */
  271.  
  272. cImage_settings :: cImage_settings( void )
  273. : cFile_parser()
  274. {
  275.     settings = NULL;
  276.     load_base = 1;
  277. }
  278.  
  279. cImage_settings :: ~cImage_settings( void )
  280. {
  281.     //
  282. }
  283.  
  284. cImage_settings_data *cImage_settings :: Get( string &filename, bool load_base_settings /* = 1 */ )
  285. {
  286.     load_base = load_base_settings;
  287.     settings = new cImage_settings_data();
  288.  
  289.     Parse( filename );
  290.     return settings;
  291. }
  292.  
  293. bool cImage_settings :: HandleMessage( string *parts, unsigned int count, unsigned int line )
  294. {
  295.     if( parts[0].compare( "base" ) == 0 )
  296.     {
  297.         if( count < 2 || count > 3 )
  298.         {
  299.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  300.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2-3 parameters" );
  301.             return 0; // error
  302.         }
  303.  
  304.         if( !is_valid_number( parts[2] ) )
  305.         {
  306.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  307.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  308.             return 0; // error
  309.         }
  310.  
  311.         settings->m_base = data_file.substr( 0, data_file.rfind( "/" ) + 1 ) + parts[1];
  312.  
  313.         // with settings option
  314.         if( count == 3 && string_to_int( parts[2] ) )
  315.         {
  316.             settings->m_base_settings = 1;
  317.  
  318.             if( load_base )
  319.             {
  320.                 string settings_file = settings->m_base;
  321.  
  322.                 // if settings file exists
  323.                 while( !settings_file.empty() )
  324.                 {
  325.                     // if not already image settings based
  326.                     if( settings_file.rfind( ".settings" ) == string::npos )
  327.                     {
  328.                         settings_file.erase( settings_file.rfind( "." ) + 1 );
  329.                         settings_file.insert( settings_file.rfind( "." ) + 1, "settings" );
  330.                     }
  331.  
  332.                     // not found
  333.                     if( !File_Exists( settings_file ) )
  334.                     {
  335.                         break;
  336.                     }
  337.  
  338.                     // create new temporary parser
  339.                     cImage_settings *temp_parser = new cImage_settings();
  340.                     cImage_settings_data *base_settings = temp_parser->Get( settings_file );
  341.                     // finished loading base settings
  342.                     delete temp_parser;
  343.                     settings_file.clear();
  344.  
  345.                     // handle
  346.                     if( base_settings )
  347.                     {
  348.                         // todo : apply settings in reverse order ( deepest settings should override first )
  349.                         settings->Apply_Base( base_settings );
  350.                         
  351.                         // if also based on settings
  352.                         if( !base_settings->m_base.empty() && base_settings->m_base_settings )
  353.                         {
  354.                             settings_file = base_settings->m_base;
  355.                         }
  356.                         
  357.                         delete base_settings;
  358.                     }
  359.                 }
  360.             }
  361.         }
  362.     }
  363.     else if( parts[0].compare( "int_x" ) == 0 )
  364.     {
  365.         if( count != 2 )
  366.         {
  367.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  368.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  369.             return 0; // error
  370.         }
  371.  
  372.         if( !is_valid_number( parts[1] ) )
  373.         {
  374.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  375.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  376.             return 0; // error
  377.         }
  378.  
  379.         settings->m_int_x = string_to_int( parts[1] );
  380.     }
  381.     else if( parts[0].compare( "int_y" ) == 0 )
  382.     {
  383.         if( count != 2 )
  384.         {
  385.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  386.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  387.             return 0; // error
  388.         }
  389.  
  390.         if( !is_valid_number( parts[1] ) )
  391.         {
  392.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  393.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  394.             return 0; // error
  395.         }
  396.  
  397.         settings->m_int_y = string_to_int( parts[1] );
  398.     }
  399.     else if( parts[0].compare( "col_rect" ) == 0 )
  400.     {
  401.         if( count != 5 )
  402.         {
  403.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  404.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 5 parameters" );
  405.             return 0; // error
  406.         }
  407.  
  408.         for( unsigned int i = 1; i < 5; i++ )
  409.         {
  410.             if( !is_valid_number( parts[i] ) )
  411.             {
  412.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  413.                 printf( "%s is not a valid integer value\n", parts[1].c_str() );
  414.                 return 0; // error
  415.             }
  416.         }
  417.  
  418.         // position and dimension
  419.         settings->m_col_rect = GL_rect( static_cast<float>(string_to_int( parts[1] )), static_cast<float>(string_to_int( parts[2] )), static_cast<float>(string_to_int( parts[3] )), static_cast<float>(string_to_int( parts[4] )) );
  420.     }
  421.     else if( parts[0].compare( "width" ) == 0 )
  422.     {
  423.         if( count != 2 )
  424.         {
  425.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  426.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  427.             return 0; // error
  428.         }
  429.  
  430.         if( !is_valid_number( parts[1] ) )
  431.         {
  432.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  433.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  434.             return 0; // error
  435.         }
  436.  
  437.         settings->m_width = string_to_int( parts[1] );
  438.     }
  439.     else if( parts[0].compare( "height" ) == 0 )
  440.     {
  441.         if( count != 2 )
  442.         {
  443.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  444.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  445.             return 0; // error
  446.         }
  447.  
  448.         if( !is_valid_number( parts[1] ) )
  449.         {
  450.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  451.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  452.             return 0; // error
  453.         }
  454.  
  455.         settings->m_height = string_to_int( parts[1] );
  456.     }
  457.     else if( parts[0].compare( "rotation" ) == 0 )
  458.     {
  459.         if( count < 2 || count > 5 )
  460.         {
  461.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  462.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2-5 parameters" );
  463.             return 0; // error
  464.         }
  465.  
  466.         if( !is_valid_number( parts[1] ) )
  467.         {
  468.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  469.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  470.             return 0; // error
  471.         }
  472.  
  473.         // x
  474.         settings->m_rotation_x = string_to_int( parts[1] );
  475.  
  476.         // y
  477.         if( count > 2 )
  478.         {
  479.             if( !is_valid_number( parts[2] ) )
  480.             {
  481.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  482.                 printf( "%s is not a valid integer value\n", parts[2].c_str() );
  483.                 return 0; // error
  484.             }
  485.  
  486.             settings->m_rotation_y = string_to_int( parts[2] );
  487.         }
  488.         // z
  489.         if( count > 3 )
  490.         {
  491.             if( !is_valid_number( parts[3] ) )
  492.             {
  493.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  494.                 printf( "%s is not a valid integer value\n", parts[3].c_str() );
  495.                 return 0; // error
  496.             }
  497.  
  498.             settings->m_rotation_z = string_to_int( parts[3] );
  499.         }
  500.     }
  501.     else if( parts[0].compare( "mipmap" ) == 0 )
  502.     {
  503.         if( count != 2 )
  504.         {
  505.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  506.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  507.             return 0; // error
  508.         }
  509.  
  510.         if( !is_valid_number( parts[1] ) )
  511.         {
  512.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  513.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  514.             return 0; // error
  515.         }
  516.  
  517.         // if mipmaps enabled
  518.         if( string_to_int( parts[1] ) )
  519.         {
  520.             settings->m_mipmap = 1;
  521.         }
  522.     }
  523.     else if( parts[0].compare( "editor_tags" ) == 0 )
  524.     {
  525.         if( count != 2 )
  526.         {
  527.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  528.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  529.             return 0; // error
  530.         }
  531.  
  532.         settings->m_editor_tags = parts[1];
  533.     }
  534.     else if( parts[0].compare( "name" ) == 0 )
  535.     {
  536.         if( count != 2 )
  537.         {
  538.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  539.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  540.             return 0; // error
  541.         }
  542.  
  543.         settings->m_name = parts[1];
  544.     }
  545.     else if( parts[0].compare( "type" ) == 0 )
  546.     {
  547.         if( count != 2 )
  548.         {
  549.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  550.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  551.             return 0; // error
  552.         }
  553.  
  554.         settings->m_type = Get_Sprite_Type_Id( parts[1] );
  555.     }
  556.     else if( parts[0].compare( "ground_type" ) == 0 )
  557.     {
  558.         if( count != 2 )
  559.         {
  560.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  561.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  562.             return 0; // error
  563.         }
  564.  
  565.         settings->m_ground_type = Get_Ground_Type_Id( parts[1] );
  566.     }
  567.     else if( parts[0].compare( "author" ) == 0 )
  568.     {
  569.         if( count != 2 )
  570.         {
  571.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  572.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  573.             return 0; // error
  574.         }
  575.  
  576.         settings->m_author = parts[1];
  577.     }
  578.     else if( parts[0].compare( "obsolete" ) == 0 )
  579.     {
  580.         if( count != 2 )
  581.         {
  582.             printf( "%s : line %d Error :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  583.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  584.             return 0; // error
  585.         }
  586.  
  587.         if( !is_valid_number( parts[1] ) )
  588.         {
  589.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  590.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  591.             return 0; // error
  592.         }
  593.  
  594.         // if tagged obsolete
  595.         if( string_to_int( parts[1] ) )
  596.         {
  597.             settings->m_obsolete = 1;
  598.         }
  599.     }
  600.     else
  601.     {
  602.         printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  603.         printf( "Unknown Command : %s\n", parts[0].c_str() );
  604.         return 0; // error
  605.     }
  606.  
  607.     return 1;
  608. }
  609.  
  610. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  611.  
  612. cImage_settings *pSettingsParser = NULL;
  613.