📄 gd04-01.cpp
字号:
// ============================================================================
// GD04-01.cpp
// Bitvector Graphical Demonstration.
// ============================================================================
#include "SDLGUI.h"
#include "Bitvector.h"
#include <stdlib.h>
#include <time.h>
// ============================================================================
// Global Constants
// ============================================================================
const char PROGRAM_NAME[] = "Bitvector Graphical Demonstration";
const int WIDTH = 640;
const int HEIGHT = 480;
const int ITEMS = 32;
const int ARIAL = 0;
// ============================================================================
// Demo States
// ============================================================================
enum bitvectorstate
{
// nothing happening.
NOSTATE,
// find the correct cell to modify
FINDCELL,
// find the correct bit to mofify
FINDBIT,
// move up a one into the correct position
MOVEUPBIT,
// logically not the modifier
NOT,
// logically and the mofifier
AND,
// logically or the modifier
OR
};
// ============================================================================
// Global Variables
// ============================================================================
SDLGUI* g_gui;
// this is the bitvector that we will use in the demo
Bitvector g_vector( 64 );
// this is the bit-modifier. It will be used to modify cells
// within the bitvector.
unsigned long int g_bitmodifier;
// holds the current index in the vector.
int g_current = 0;
// used for counting.
int g_index;
// since the set and clear operations
// are almost identical, we'll use
// a boolean to determine which operation
// we are doing. 1 = clear, 0 = set.
bool g_isclear;
// holds the last known time.
Uint32 g_time;
// the current animation state.
bitvectorstate g_state = NOSTATE;
// small boxes
SDL_Surface* g_s1box;
SDL_Surface* g_s0box;
SDL_Surface* g_sr1box;
SDL_Surface* g_sr0box;
// large boxes
SDL_Surface* g_l1box;
SDL_Surface* g_l0box;
SDL_Surface* g_lr1box;
SDL_Surface* g_lr0box;
// text
SDL_Surface* g_statustext = 0;
// arrow
SDL_Surface* g_downarrow;
// ============================================================================
// Draw Algorithms
// ============================================================================
void DrawBitVector( Bitvector& p_vec, // the vector to draw
int p_x, int p_y, // x+y coords
int p_current, // the current index.
bool p_horizontal ) // horizontal or vertical?
{
int index;
// draw the vector.
for( index = 0; index < p_vec.Size(); index++ )
{
// draw the box
if( index != p_current )
{
// draw the normal boxes
if( p_vec[index] == true )
g_gui->Blit( g_s1box, p_x, p_y );
else
g_gui->Blit( g_s0box, p_x, p_y );
}
else
{
// draw the red boxes
if( p_vec[index] == true )
g_gui->Blit( g_sr1box, p_x, p_y );
else
g_gui->Blit( g_sr0box, p_x, p_y );
}
if( p_horizontal == true )
p_x += g_s1box->w;
else
p_y += g_s1box->h;
}
}
void DrawCell( unsigned long int p_cell, // the cell to draw
int p_x, int p_y, // coords
int p_current, // the current index.
bool p_horizontal ) // horizontal or vertical?
{
int index;
unsigned long int currentcell = 1;
// draw the cell.
for( index = 0; index < 32; index++, currentcell <<= 1 )
{
// draw the box
if( index != p_current )
{
// draw the normal boxes
if( (p_cell & currentcell) != 0 )
g_gui->Blit( g_l1box, p_x, p_y );
else
g_gui->Blit( g_l0box, p_x, p_y );
}
else
{
// draw the red boxes
if( (p_cell & currentcell) != 0 )
g_gui->Blit( g_lr1box, p_x, p_y );
else
g_gui->Blit( g_lr0box, p_x, p_y );
}
if( p_horizontal == true )
p_x += g_l1box->w;
else
p_y += g_l1box->h;
}
}
// ============================================================================
// Button Callbacks
// ============================================================================
void Set()
{
// create the status string
char tempstring[80];
sprintf( tempstring, "index = %d, cell = %d / 32 = %d",
g_current, g_current, g_current / 32 );
g_statustext = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), tempstring,
BLACK, WHITE );
g_isclear = false;
g_state = FINDCELL;
g_gui->GetItem( 3 )->SetVisibility( true );
g_gui->GetItem( 2 )->SetVisibility( true );
g_gui->GetItem( 0 )->SetVisibility( false );
g_gui->GetItem( 1 )->SetVisibility( false );
g_gui->GetItem( 9 )->SetVisibility( false );
};
void Clear()
{
// create the status string
char tempstring[80];
sprintf( tempstring, "index = %d, cell = %d / 32 = %d",
g_current, g_current, g_current / 32 );
g_statustext = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), tempstring,
BLACK, WHITE );
g_isclear = true;
g_state = FINDCELL;
g_gui->GetItem( 3 )->SetVisibility( true );
g_gui->GetItem( 2 )->SetVisibility( true );
g_gui->GetItem( 0 )->SetVisibility( false );
g_gui->GetItem( 1 )->SetVisibility( false );
g_gui->GetItem( 9 )->SetVisibility( false );
};
void Continue()
{
// a temporary string to print status messages to.
char tempstring[80];
// hide the continue button.
g_gui->GetItem( 2 )->SetVisibility( false );
// determine which state to go to next.
switch( g_state )
{
case FINDCELL:
g_state = FINDBIT;
SDL_FreeSurface( g_statustext );
sprintf( tempstring, "bit = %d mod 32 = %d", g_current, g_current % 32 );
g_statustext = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), tempstring,
BLACK, WHITE );
g_gui->GetItem( 3 )->SetVisibility( false );
g_gui->GetItem( 4 )->SetVisibility( true );
g_gui->GetItem( 2 )->SetVisibility( true );
break;
case FINDBIT:
g_state = MOVEUPBIT;
SDL_FreeSurface( g_statustext );
g_bitmodifier = 1;
g_time = SDL_GetTicks();
g_gui->GetItem( 4 )->SetVisibility( false );
g_gui->GetItem( 5 )->SetVisibility( true );
break;
case MOVEUPBIT:
g_gui->GetItem( 5 )->SetVisibility( false );
g_gui->GetItem( 2 )->SetVisibility( true );
if( g_isclear == true )
{
g_state = NOT;
g_gui->GetItem( 6 )->SetVisibility( true );
g_bitmodifier = ~g_bitmodifier;
}
else
{
g_state = OR;
g_gui->GetItem( 8 )->SetVisibility( true );
g_vector.Set( g_current, true );
}
break;
case NOT:
g_state = AND;
g_gui->GetItem( 6 )->SetVisibility( false );
g_gui->GetItem( 7 )->SetVisibility( true );
g_gui->GetItem( 2 )->SetVisibility( true );
g_vector.Set( g_current, false );
break;
case AND:
g_state = NOSTATE;
g_gui->GetItem( 7 )->SetVisibility( false );
g_gui->GetItem( 0 )->SetVisibility( true );
g_gui->GetItem( 1 )->SetVisibility( true );
g_gui->GetItem( 2 )->SetVisibility( false );
g_gui->GetItem( 9 )->SetVisibility( true );
break;
case OR:
g_state = NOSTATE;
g_gui->GetItem( 8 )->SetVisibility( false );
g_gui->GetItem( 0 )->SetVisibility( true );
g_gui->GetItem( 1 )->SetVisibility( true );
g_gui->GetItem( 2 )->SetVisibility( false );
g_gui->GetItem( 9 )->SetVisibility( true );
break;
}
};
// ============================================================================
// Main
// ============================================================================
int main( int argc, char* argv[] )
{
int x;
int y;
int index;
// initialise the bitvector
g_vector.ClearAll();
g_current = 0;
for( index = 0; index < 64; index++ )
g_vector.Set( index, rand()%2 );
srand( time(0) );
//initialize systems
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
SDL_WM_SetCaption( "Array Graphical Demonstration", 0);
TTF_Init();
g_gui = new SDLGUI( WIDTH, HEIGHT, ITEMS, WHITE );
g_gui->SetFont( "arial.ttf", ARIAL, 26, TTF_STYLE_NORMAL );
// add the buttons to the g_gui
g_gui->AddButton( 0, 0, "gbup.bmp", "gbdown.bmp", "set bit",
ARIAL, BLACK, WHITE, Set );
g_gui->AddButton( 128, 0, "gbup.bmp", "gbdown.bmp", "clear bit",
ARIAL, BLACK, WHITE, Clear );
g_gui->AddButton( 256, 0, "gbup.bmp", "gbdown.bmp", "continue",
ARIAL, BLACK, WHITE, Continue );
g_gui->AddLabel( 0, 400, "First, you need to find the correct cell.",
ARIAL, BLACK, WHITE );
g_gui->AddLabel( 0, 400, "then find which bit to modify in that cell.",
ARIAL, BLACK, WHITE );
g_gui->AddLabel( 0, 400, "Now make an int with the 1 in the correct index",
ARIAL, BLACK, WHITE );
g_gui->AddLabel( 0, 400, "Negate the integer", ARIAL, BLACK, WHITE );
g_gui->AddLabel( 0, 400, "Finally, logically AND them together.",
ARIAL, BLACK, WHITE );
g_gui->AddLabel( 0, 400, "Finally, logically OR them together.",
ARIAL, BLACK, WHITE );
g_gui->AddLabel( 0, 400, "Click on a box to select the g_current bit.",
ARIAL, BLACK, WHITE );
// set all the captions to be invisisble.
g_gui->GetItem( 2 )->SetVisibility( false );
g_gui->GetItem( 3 )->SetVisibility( false );
g_gui->GetItem( 4 )->SetVisibility( false );
g_gui->GetItem( 5 )->SetVisibility( false );
g_gui->GetItem( 6 )->SetVisibility( false );
g_gui->GetItem( 7 )->SetVisibility( false );
g_gui->GetItem( 8 )->SetVisibility( false );
// set our at exit function
atexit( SDL_Quit ) ;
// create the BMP's that we need.
g_s1box = SDL_LoadBMP( "s1box.bmp" );
g_s0box = SDL_LoadBMP( "s0box.bmp" );
g_sr1box = SDL_LoadBMP( "sr1box.bmp" );
g_sr0box = SDL_LoadBMP( "sr0box.bmp" );
g_l1box = SDL_LoadBMP( "l1box.bmp" );
g_l0box = SDL_LoadBMP( "l0box.bmp" );
g_lr1box = SDL_LoadBMP( "lr1box.bmp" );
g_lr0box = SDL_LoadBMP( "lr0box.bmp" );
g_downarrow = SDL_LoadBMP( "downarrow.bmp" );
// 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 );
// check to see if user clicked on a cell
if( g_state == NOSTATE )
{
if( y >= 300 &&
y < 308 &&
x >= 64 &&
x < (8 * g_vector.Size() + 64) )
{
g_current = (x - 64) / 8;
}
}
}
// 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();
// draw the bitvector and the separator between the two cells.
g_gui->Line( 319, 296, 319, 312, BLACK );
g_gui->Line( 320, 296, 320, 312, BLACK );
DrawBitVector( g_vector, 64, 300, g_current, true );
if( g_state == FINDBIT || g_state == MOVEUPBIT ||
g_state == NOT || g_state == AND || g_state == OR )
{
// draw the blown up version of the current cell.
DrawCell( g_vector.GetCell( g_current / 32 ), 64, 200, g_current % 32, true );
// draw lines depicting where the current cell came from
g_gui->ArrowLine( 64, 216, g_current/32 * 256 + 64, 300,
0, 0, true, false, BLACK );
g_gui->ArrowLine( 576, 216, g_current/32 * 256 + 320, 300,
0, 0, true, false, BLACK );
}
if( g_state == FINDCELL )
{
g_gui->Blit( g_statustext, 20, 100 );
g_gui->Blit( g_downarrow, 192 + ((g_current/32) * 256) - (g_downarrow->w/2), 230 );
}
if( g_state == FINDBIT )
{
g_gui->Blit( g_statustext, 20, 100 );
}
if( g_state == MOVEUPBIT )
{
index = (SDL_GetTicks() - g_time) / 300;
if( index > (g_current % 32) )
{
index = g_current % 32;
g_gui->GetItem( 2 )->SetVisibility( true );
}
g_bitmodifier = 1 << index;
}
if( g_state == MOVEUPBIT || g_state == NOT || g_state == AND || g_state == OR )
{
DrawCell( g_bitmodifier, 64, 160, -1, true );
}
g_gui->Update();
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -