⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gd21-01.cpp

📁 游戏开发数据结构Data Structures for Game Programmers
💻 CPP
字号:
// ============================================================================
//  GD21-01.cpp
//  RLE Compression Demo
// ============================================================================
#include "SDLGUI.h"
#include <stdlib.h>
#include <time.h>



// ============================================================================
//  Global Constants
// ============================================================================
const char PROGRAM_NAME[]   = "RLE Graphical Demonstration";
const int WIDTH             = 800;
const int HEIGHT            = 600;
const int ITEMS             = 32;
const int ARIAL             = 0;


// ============================================================================
//  Global Variables
// ============================================================================
SDLGUI* g_gui;

int g_timer;

SDL_Surface* g_bitmap = 0;

char g_filename[80] = "";
char g_filesize[80] = "";
char g_RLESize[80] = "";
char g_bytesize[80] = "";

bool g_8bitRun = true;
bool g_16bitRun = false;
bool g_24bitRun = false;
bool g_32bitRun = false;

Uint32 g_maxlength = 0xFF;
int g_lengthSize = 1;


// ============================================================================
//  Other Algorithms
// ============================================================================
int CalculateRuns()
{
    int runs = 1;
    Uint32 length = 0;
    Uint32 lastpixel;
    Uint32* buffer;
    int pixels;

    int x;
    int y;
    int pitch;

    SDL_PixelFormat pf;
    pf.palette = 0;
    pf.BitsPerPixel = 32;
    pf.BytesPerPixel = 4;
    pf.Rmask = 0xFF000000;
    pf.Gmask = 0x00FF0000;
    pf.Bmask = 0x0000FF00;
    pf.Amask = 0x000000FF;
    pf.Rloss = 0;
    pf.Gloss = 0;
    pf.Bloss = 0;
    pf.Aloss = 0;
    pf.Rshift = 24;
    pf.Gshift = 16;
    pf.Bshift = 8;
    pf.Ashift = 0;
    pf.colorkey = 0;
    pf.alpha = 0;

    // convert the surface
    SDL_Surface* temp = 0;
    temp = SDL_ConvertSurface( g_bitmap, &pf, SDL_SWSURFACE );

    // calculate the number of pixels
    pixels = temp->h * temp->w;

    // cast the bitmap buffer into an Uint32 array.
    buffer = (Uint32*)temp->pixels;

    // calculate the pitch in pixels, not bytes.
    pitch = temp->pitch / 4;

    // lock the surface so we can read it unobstructed.
    SDL_LockSurface( temp );

    lastpixel = buffer[0];
    length = 0;

    for( y = 0; y < temp->h; y++ )
    {
        for( x = 0; x < temp->w; x++ )
        {
            length++;
            if( buffer[y * pitch + x] != lastpixel )
            {
                runs++;
                lastpixel = buffer[ y * pitch + x];
                length = 1;
            }
            else
            {
                if( length > g_maxlength )
                {
                    length = 1;
                    runs++;
                }
            }
        }
    }



    // unlock the surface again
    SDL_UnlockSurface( temp );

    return runs;
}


// toggles the state of a gui button item
void ToggleOff( int p_index )
{
    SDLButton* button = (SDLButton*)( g_gui->GetItem( p_index ) );
    if( button != 0 )
    {
        if( button->State() == BUTTONDOWN )
        {
            button->Toggle();
        }
    }
}

void ToggleOn( int p_index )
{
    SDLButton* button = (SDLButton*)( g_gui->GetItem( p_index ) );
    if( button != 0 )
    {
        if( button->State() == BUTTONUP )
        {
            button->Toggle();
        }
    }
}

// ============================================================================
//  Button Callbacks
// ============================================================================
void LoadBMP()
{
    int runs;

    // free the old bitmap
    if( g_bitmap != 0 )
        SDL_FreeSurface( g_bitmap );

    // load the new bitmap
    g_bitmap = SDL_LoadBMP( g_filename );

    // load the bitmap size
    if( g_bitmap != 0 )
    {
        runs = CalculateRuns();
        sprintf( g_filesize, "%d pixels", g_bitmap->h * g_bitmap->w );
        sprintf( g_RLESize, "%d runs", runs );
        sprintf( g_bytesize, "%d bytes", runs * g_lengthSize + runs * 3 );
    }
    else
    {
        sprintf( g_filesize, "0 pixels" );
        sprintf( g_RLESize, "0 runs" );
        sprintf( g_bytesize, "0 bytes" );
    }
}


void Press8Bit()
{
    ToggleOn( 6 );
    ToggleOff( 7 );
    ToggleOff( 8 );
    ToggleOff( 9 );
    g_8bitRun = true;
    g_16bitRun = false;
    g_24bitRun = false;
    g_32bitRun = false;
    g_maxlength = 0xFF;
    g_lengthSize = 1;
    LoadBMP();
}


void Press16Bit()
{
    ToggleOff( 6 );
    ToggleOn( 7 );
    ToggleOff( 8 );
    ToggleOff( 9 );
    g_8bitRun = false;
    g_16bitRun = true;
    g_24bitRun = false;
    g_32bitRun = false;
    g_maxlength = 0xFFFF;
    g_lengthSize = 2;
    LoadBMP();
}

void Press24Bit()
{
    ToggleOff( 6 );
    ToggleOff( 7 );
    ToggleOn( 8 );
    ToggleOff( 9 );
    g_8bitRun = false;
    g_16bitRun = false;
    g_24bitRun = true;
    g_32bitRun = false;
    g_maxlength = 0xFFFFFF;
    g_lengthSize = 3;
    LoadBMP();
}

void Press32Bit()
{
    ToggleOff( 6 );
    ToggleOff( 7 );
    ToggleOff( 8 );
    ToggleOn( 9 );
    g_8bitRun = false;
    g_16bitRun = false;
    g_24bitRun = false;
    g_32bitRun = false;
    g_maxlength = 0xFFFFFFFF;
    g_lengthSize = 4;
    LoadBMP();
}


// ============================================================================
//  Main
// ============================================================================
int main( int argc, char* argv[] )
{
    int x;
    int y;

    //initialize systems
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
    SDL_EnableUNICODE( true );
    SDL_WM_SetCaption( PROGRAM_NAME, 0); 
    TTF_Init();
    g_gui = new SDLGUI( WIDTH, HEIGHT, ITEMS, WHITE );
    g_gui->SetFont( "arial.ttf", ARIAL, 18, TTF_STYLE_NORMAL );



    // add the items to the g_gui
    g_gui->AddTextBox( 668, 0, 128, 32, g_filename, 32, ARIAL, BLACK, WHITE, 
                       true, LoadBMP );
    g_gui->AddTextBox( 668, 34, 128, 32, g_filesize, 32, ARIAL, BLACK, WHITE, 
                       false, 0 );
    g_gui->AddTextBox( 668, 68, 128, 32, g_RLESize, 32, ARIAL, BLACK, WHITE, 
                       false, 0 );

    g_gui->AddLabel( 580, 0, "Filename:", ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 580, 34, "File size:", ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 580, 68, "RLE size:", ARIAL, BLACK, WHITE );

    g_gui->AddCheckbox( 690, 160, "circleopen.bmp", "circleclosed.bmp", 
                        "8 bit", ARIAL, BLACK, WHITE, Press8Bit );
    g_gui->AddCheckbox( 690, 192, "circleopen.bmp", "circleclosed.bmp", 
                        "16 bit", ARIAL, BLACK, WHITE, Press16Bit );
    g_gui->AddCheckbox( 690, 224, "circleopen.bmp", "circleclosed.bmp", 
                        "24 bit", ARIAL, BLACK, WHITE, Press24Bit );
    g_gui->AddCheckbox( 690, 256, "circleopen.bmp", "circleclosed.bmp", 
                        "32 bit", ARIAL, BLACK, WHITE, Press32Bit );
        

    g_gui->AddTextBox( 668, 102, 128, 32, g_bytesize, 32, ARIAL, BLACK, WHITE, 
                       false, 0 );
    g_gui->AddLabel( 580, 102, "byte size:", ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 580, 154, "length size:", ARIAL, BLACK, WHITE );




    ToggleOn( 6 );

    // set our at exit function
    atexit( SDL_Quit ) ;

    // declare event variable
    SDL_Event event;

    g_gui->Draw();
    g_gui->Update();

    // loop until we get a quit message.
    while( 1 )
    {
        //look for an event
        if( SDL_PollEvent( &event ) )
        {
            //an event was found
            if( event.type == SDL_QUIT ) 
                break;

            // mouse button was pressed
            if( event.type == SDL_MOUSEBUTTONDOWN ) 
            {
                // get the mouse g_state.
                SDL_GetMouseState( &x, &y );

                // tell the GUI that a button has been pressed
                g_gui->MouseDown( x, y );

            }

            // mouse button was released
            if( event.type == SDL_MOUSEBUTTONUP ) 
            {
                // get the mouse state.
                SDL_GetMouseState( &x, &y );

                // tell the GUI that a button has been released
                g_gui->MouseUp( x, y );
            }

            if( event.type == SDL_KEYDOWN )
            {
                // a key was pressed.
                if( event.key.keysym.sym == SDLK_ESCAPE )
                {
                    // if ESC was pressed, quit the program.
                    SDL_Event quit;
                    quit.type = SDL_QUIT;
                    SDL_PushEvent( &quit );
                }

                // tell the GUI that a key was pressed.
                g_gui->KeyDown( event.key.keysym.sym, 
                                event.key.keysym.mod,
                                event.key.keysym.unicode );
            }
        }

        // draw the g_gui at the end of each loop.
        g_gui->Draw();

        if( g_bitmap != 0 )
        {
            g_gui->Box( 0, 0, g_bitmap->w + 2, g_bitmap->h + 2, BLACK );
            g_gui->Blit( g_bitmap, 1, 1 );
        }

        g_gui->Update();
    }

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -