📄 gd21-01.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 + -