#include "SDL.h" #include "SDL_image.h" #include #include #include using namespace std; const int DEFAULT_WID = 820; const int DEFAULT_HEI = 600; const int DEFAULT_DEPTH = 32; // exit function as before void exitFunc(void) { SDL_Quit(); } // a routine to select a good screen for the application. SDL_Surface * setUpScreen(void) { SDL_Surface * tmp; int wid, hei; int max; int bpp; // describe the screen you want. int flag = 0; SDL_Rect ** modes; modes = SDL_ListModes(NULL,flag); if (modes == NULL) { // if there is no video bail. tmp = NULL; } else if (modes ==(SDL_Rect **) -1) { // if I have infinate choices use the default tmp = SDL_SetVideoMode(DEFAULT_WID, DEFAULT_HEI, DEFAULT_DEPTH, flag); } else { // step through the available screens int i; // grab the most pixels I can; i = 0; max = modes[i]->w*modes[i]->h; wid = modes[i]->w; hei = modes[i]->h; for(i=1;modes[i];i++) { if (modes[i]->w * modes[i]->h > max) { max = modes[i]->w*modes[i]->h; wid = modes[i]->w; hei = modes[i]->h; } } //see the pixel depth that the screen can be bpp= SDL_VideoModeOK(wid,hei,DEFAULT_DEPTH,flag); if (bpp == 0) { // oops, can't do it tmp = NULL; } else { // yes we can, so grab it. tmp = SDL_SetVideoMode(wid,hei,bpp,flag); } } return tmp; } void hexCorner(int a, int b, Sint16 & x, Sint16 & y, int r1, int r2) { // this is the center of the hex x = ((a/2)*3+1)*r1; y = b*r2; if (a%2 == 0) { x -= int(1.5*r1); } // this is the upper left hand corner, in screen coordinates x -= r1; y -= r2; } int FirstPlayableRow(void) { //yehaw, always 1 return 1; } int FirstPlayableCol(int row) { // strangeness due to the way we number the board. if (row %2 == 0) { return 2; } else { return 1; } } int LastPlayableRow(int screenHeight, int radius2) { int value; int test; value = screenHeight/radius2; // if the last row we calculat is not FULLY visible, // cut theis back by one. if (value*radius2+radius2 > screenHeight){ value --; } return value ; } int LastPlayableCol(int screenWidth, int radius1) { int value; int test; value = int(screenWidth/(radius1*1.5)); // if the clast col is not fully visible, cut this back by one. test =int( value * radius1*1.5); if (test+radius1 > screenWidth) { value -= 1; } return(value); } // this will load a bmp and mark the color white as the transparent // part of the surface. void LoadTransparentImage(SDL_Surface * & rv,string filename){ Uint32 tmpColor; SDL_Surface * tmp; // try to load a BMP tmp = IMG_Load(filename.c_str()); if(tmp == NULL) { cout << "Unable to load " << filename << " " << IMG_GetError() << endl; exit(-1); } rv = SDL_DisplayFormat(tmp); if (rv == NULL) { cout << "Unable convert " << filename << " " << SDL_GetError() << endl; return; } SDL_FreeSurface(tmp); // Mark White as a color not to be drawn. tmpColor = SDL_MapRGB(rv->format, 255,255,255); SDL_SetColorKey( rv, SDL_SRCCOLORKEY | SDL_RLEACCEL , tmpColor); } int main() { int x,y; SDL_Rect src, dest; SDL_Surface * thingToDraw, *cursor, *killed; int oldi=0, oldj=0; int i,j; int startPos; if( SDL_Init(SDL_INIT_VIDEO ) != 0 ){ cout << "Unable to Initialize SDL " << SDL_GetError() << endl; return -1; } atexit(exitFunc); // this will be the size of the new screen, draw on it. SDL_Surface * mainScreen; mainScreen = setUpScreen(); // make sure it is valid after we grab it. if (mainScreen == NULL) { cout << "Unable open an SDL screen " << SDL_GetError() << endl; return -1; } // load the images. LoadTransparentImage(thingToDraw,"gifs/hexGreen.gif"); LoadTransparentImage(cursor, "gifs/cursor.gif"); LoadTransparentImage(killed, "gifs/target.gif"); // set up the source rectangle. src.w = thingToDraw->w; src.h = thingToDraw->h; src.x = 0; src.y = 0; // compute the radii of the hexes int r1 = thingToDraw->w/2; int r2 = thingToDraw->h/2; // a routine to draw the entire map. for(i=FirstPlayableRow()-1; i<= LastPlayableRow(mainScreen->h,r2)+2;i++) { for(j=FirstPlayableCol(i)-2; j<=LastPlayableCol(mainScreen->w,r1)+2;j+=2) { hexCorner(j,i,dest.x, dest.y, r1, r2); SDL_BlitSurface(thingToDraw, &src, mainScreen, & dest); } } // display this SDL_UpdateRect(mainScreen,0,0,0,0); SDL_Delay(1000); // now move the cursor across the visibile map. Notice we only // refresh the hex we have drawn in. for(i=FirstPlayableRow(); i <= LastPlayableRow(mainScreen->h,r2); i++) { for(j=FirstPlayableCol(i); j<= LastPlayableCol(mainScreen->w,r1); j+=2) { // we must have drawn something else, this is really a delay to // be able to undraw the cursor. // if we had a cursor class, we would handle this there. if (oldi != 0) { hexCorner(oldj,oldi,dest.x, dest.y, r1, r2); SDL_BlitSurface(thingToDraw, &src, mainScreen, & dest); SDL_BlitSurface(killed, &src, mainScreen, & dest); } // draw the next hex hexCorner(j,i,dest.x,dest.y,r1,r2); // keep track of where we just drew. oldi = i; oldj = j; // draw the next hex SDL_BlitSurface(cursor, &src, mainScreen, & dest); // we could just compute the two boxes we just drew and // update them, this would make this portion "quicker" SDL_UpdateRect(mainScreen,0,0,0,0); SDL_Delay(125); } } // draw the last one hexCorner(oldj,oldi,dest.x, dest.y, r1, r2); SDL_BlitSurface(thingToDraw, &src, mainScreen, & dest); SDL_BlitSurface(killed, &src, mainScreen, & dest); SDL_UpdateRect(mainScreen,0,0,0,0); cout << "Done Drawing Cursor Test" << endl; SDL_Delay(3000); SDL_FreeSurface(thingToDraw); SDL_FreeSurface(cursor); SDL_FreeSurface(killed); return 0; }