/** * Program: Solo, a computer solitarie card game. * By: MD, md@tomatesasesinos.com * Copyright 2007 * * License: GPL http://www.gnu.org/licences/gpl.html * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * File: graficos.c * Contents: Graphics functions */ #include "globals.h" void solitarioSDL(void) { SDL_Event evento; SDLKey tecla; iniciarSDL(); cargarImagenes(); iniciarVentana(); iniciarCursores(); mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); while(1) { if(SDL_WaitEvent(&evento)) { SDL_PollEvent(&evento); switch(evento.type) { case SDL_KEYDOWN: tecla=evento.key.keysym.sym; switch(tecla) { case SDLK_UP: moverCursorTeclado(ARRIBA); break; case SDLK_DOWN: moverCursorTeclado(ABAJO); break; case SDLK_RIGHT: moverCursorTeclado(DERECHA); break; case SDLK_LEFT: moverCursorTeclado(IZQUIERDA); break; case SDLK_SPACE: accion(); break; case SDLK_ESCAPE: exit(0); //Aqui deberia ir el menu de momento solo se sale break; } break; case SDL_QUIT: exit(0); break; case SDL_VIDEOEXPOSE: //Codigo a medias, falta mejorar mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); break; } } if(victoria()) { while(1) { mostrarMesa(); SDL_BlitSurface(ganaste,NULL,pantalla,NULL); SDL_Flip(pantalla); if(SDL_WaitEvent(&evento)) { SDL_PollEvent(&evento); if(evento.type==SDL_KEYDOWN) { tecla=evento.key.keysym.sym; if(tecla==SDLK_ESCAPE) exit(0); } if(evento.type==SDL_QUIT) exit(0); } } } } atexit(SDL_Quit); } void iniciarCursores(void) { int i; /* cursorSuperficie=crearSuperficie(ANCHOCARTA,ALTOCARTA); SDL_FillRect(cursorSuperficie, NULL,SDL_MapRGB(pantalla->format,0,0,255)); SDL_SetAlpha(cursorSuperficie,SDL_SRCALPHA|SDL_RLEACCEL,255/2);*/ /* cursorOrigenAccionSuperficie=crearSuperficie(ANCHOCARTA,ALTOCARTA); SDL_FillRect(cursorOrigenAccionSuperficie, NULL,SDL_MapRGB(pantalla->format,255,0,0)); SDL_SetAlpha(cursorOrigenAccionSuperficie,SDL_SRCALPHA|SDL_RLEACCEL,255/2);*/ cursorSuperficie=IMG_Load(FICHERO_IMG_SELAZUL); cursorOrigenAccionSuperficie=IMG_Load(FICHERO_IMG_SELROJO); cursorTeclado.x=BORDEPANTALLA; cursorTeclado.y=BORDEPANTALLA; accionEnCurso=FALSE; for(i=0;iformat->BitsPerPixel, SDL_ANYFORMAT); } void iniciarSDL(void) { if(SDL_Init(SDL_INIT_VIDEO)<0) { fprintf(stderr,"ERROR: No se puede iniciar SDL: %s\n",SDL_GetError()); exit(1); } } void accion(void) { int posicionTableroCursor=posicionActualCursor%100; int posicionAnteriorTableroCursor=posicionAnteriorCursor%100; int posicionEscaleraCursor=posicionActualCursor/100; int posicionAnteriorEscaleraCursor=posicionAnteriorCursor/100; switch(posicionTableroCursor) { case SACAR: accionEnCurso=FALSE; accionSacar(); break; default: if(accionEnCurso) { accionEnCurso=FALSE; if(posicionAnteriorEscaleraCursor==0) { if((posicionTableroCursor!=SACAR)&&(posicionTableroCursor!=OLVIDAR)&&(posicionTableroCursor!=posicionAnteriorTableroCursor)) { moverCartaLegal(posicionAnteriorTableroCursor,posicionTableroCursor); mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); }else { //El "doble click" que lleva la carta a los palos if(posicionTableroCursor==posicionAnteriorTableroCursor) { if(moverPalos(posicionTableroCursor)) { mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); }else { //Hacer ruido molesto :) mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); } } } }else { moverGrupoCartasLegal(posicionAnteriorTableroCursor,posicionAnteriorEscaleraCursor,posicionTableroCursor); mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); } }else { if(tablero[posicionTableroCursor][0].numCarta!=SINCARTA) { if(posicionEscaleraCursor==0) { //Sobre una sola carta if(tablero[posicionTableroCursor][0].bocaArriba==BOCARRIBA) { accionEnCurso=TRUE; posicionAnteriorCursor=posicionActualCursor; cursorOrigenAccion.x=cursorTeclado.x; cursorOrigenAccion.y=cursorTeclado.y; tablero[posicionTableroCursor][0].bocaArriba=BOCARRIBA; mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); }else { tablero[posicionTableroCursor][0].bocaArriba=BOCARRIBA; escalerasTablero[posicionTableroCursor-COLUMNA1]++; mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); } }else { //Sobre varias cartas accionEnCurso=TRUE; posicionAnteriorCursor=posicionActualCursor; cursorOrigenAccion.x=cursorTeclado.x; cursorOrigenAccion.y=cursorTeclado.y; mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); } } } break; } } void accionSacar(void) { if(cartasTablero[SACAR]>0) { sacarCartaSacar(); mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); }else { rellenarPilaSacar(); mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); } } void moverCursorTeclado(int direccion) { int posicionTableroCursor=posicionActualCursor%100; int posicionEscaleraCursor=posicionActualCursor/100; switch(direccion) { case ARRIBA: if(posicionTableroCursor>=COLUMNA1) { if(escalerasTablero[posicionTableroCursor-COLUMNA1]>1) { if(escalerasTablero[posicionTableroCursor-COLUMNA1]>(posicionEscaleraCursor+1)) posicionEscaleraCursor++; else { posicionEscaleraCursor=0; if(posicionTableroCursor!=COLUMNA3) { if(posicionTableroCursor<=COLUMNA2) posicionTableroCursor=posicionTableroCursor-6; else posicionTableroCursor=posicionTableroCursor-7; } } }else { if(posicionTableroCursor!=COLUMNA3) { posicionEscaleraCursor=0; if(posicionTableroCursor<=COLUMNA2) posicionTableroCursor=posicionTableroCursor-6; else posicionTableroCursor=posicionTableroCursor-7; } } }else { if(posicionTableroCursor0) posicionEscaleraCursor--; } } break; case ABAJO: if(posicionTableroCursor0) posicionEscaleraCursor--; else { if(posicionTableroCursor!=COLUMNA3) { posicionEscaleraCursor=0; if(posicionTableroCursor<=COLUMNA2) posicionTableroCursor=posicionTableroCursor-6; else posicionTableroCursor=posicionTableroCursor-7; } } } break; case IZQUIERDA: if((posicionTableroCursor!=SACAR)&&(posicionTableroCursor!=COLUMNA1)) { posicionTableroCursor--; }else { if(posicionTableroCursor==COLUMNA1) posicionTableroCursor=COLUMNA7; if(posicionTableroCursor==SACAR) posicionTableroCursor=PALO4; } posicionEscaleraCursor=0; break; case DERECHA: if((posicionTableroCursor!=PALO4)&&(posicionTableroCursor!=COLUMNA7)) { posicionTableroCursor++; }else { if(posicionTableroCursor==COLUMNA7) posicionTableroCursor=COLUMNA1; if(posicionTableroCursor==PALO4) posicionTableroCursor=SACAR; } posicionEscaleraCursor=0; break; } posicionActualCursor=posicionEscaleraCursor*100+posicionTableroCursor; mostrarMesa(); mostrarCursorTeclado(); SDL_Flip(pantalla); } SDL_Surface *crearSuperficie(int w, int h) { SDL_Surface *retorno=NULL; retorno=SDL_CreateRGBSurface(SDL_SRCALPHA,w,h,pantalla->format->BitsPerPixel,pantalla->format->Rmask,pantalla->format->Gmask,pantalla->format->Bmask,pantalla->format->Amask); return retorno; } void mostrarCursorTeclado(void) { int posicionTableroCursor=posicionActualCursor%100; int posicionEscaleraCursor=posicionActualCursor/100; //Eje y if(posicionTableroCursor>=COLUMNA1) { cursorTeclado.y=ALTOCARTA+SEPARACION+BORDEPANTALLA; if(cartasTablero[posicionTableroCursor]>0) { if(escalerasTablero[posicionTableroCursor-COLUMNA1]>0) { cursorTeclado.y=cursorTeclado.y+(SEPARACIONVERTICALENTRECARTAYVOLTEADA*(cartasTablero[posicionTableroCursor]-escalerasTablero[posicionTableroCursor-COLUMNA1])); }else { cursorTeclado.y=cursorTeclado.y+(SEPARACIONVERTICALENTRECARTAYVOLTEADA*(cartasTablero[posicionTableroCursor]-1)); } if(escalerasTablero[posicionTableroCursor-COLUMNA1]>1) { cursorTeclado.y=cursorTeclado.y+(SEPARACIONVERTICALENTRECARTAS*(escalerasTablero[posicionTableroCursor-COLUMNA1]-posicionEscaleraCursor-1)); } } }else cursorTeclado.y=BORDEPANTALLA; //Eje x if(posicionTableroCursor>=COLUMNA1) { cursorTeclado.x=BORDEPANTALLA+(ANCHOCARTA+SEPARACION)*(posicionTableroCursor-COLUMNA1); }else { if(posicionTableroCursor>=PALO1) cursorTeclado.x=BORDEPANTALLA+(ANCHOCARTA+SEPARACION)*(posicionTableroCursor+1); else cursorTeclado.x=BORDEPANTALLA+(ANCHOCARTA+SEPARACION)*posicionTableroCursor; } SDL_BlitSurface(cursorSuperficie,NULL,pantalla,&cursorTeclado); if(accionEnCurso) SDL_BlitSurface(cursorOrigenAccionSuperficie,NULL,pantalla,&cursorOrigenAccion); } void blitCarta(int posDelTablero,int posDentroPila,int x,int y) { SDL_Surface *imagen=NULL; SDL_Rect *celdaSprite=NULL; SDL_Rect posicion; if(tablero[posDelTablero][posDentroPila].numCarta!=SINCARTA) { if(tablero[posDelTablero][posDentroPila].bocaArriba) { celdaSprite=cualSpriteCarta(tablero[posDelTablero][posDentroPila].numCarta); imagen=cartas; }else { celdaSprite=NULL; imagen=contra; } posicion.x=x+BORDEPANTALLA; posicion.y=y+BORDEPANTALLA; SDL_BlitSurface(imagen,celdaSprite,pantalla,&posicion); } } void dibujarEscaleras(void) { int i,j; int x,y; x=0; for(i=COLUMNA1;i=0;j--) { blitCarta(i,j,x,y); if(tablero[i][j].bocaArriba) y=y+SEPARACIONVERTICALENTRECARTAS; else y=y+SEPARACIONVERTICALENTRECARTAYVOLTEADA; } x=x+ANCHOCARTA+SEPARACION; } } void dibujarMontones(void) { int i; SDL_Rect posicion; int x=0; int y=0; for(i=0;i12) blitCartaArriba(i,x-(SEPARACIONENTRECARTASMONTON*3),y-(SEPARACIONENTRECARTASMONTON*3)); if(cartasTablero[i]>8) blitCartaArriba(i,x-(SEPARACIONENTRECARTASMONTON*2),y-(SEPARACIONENTRECARTASMONTON*2)); if(cartasTablero[i]>4) blitCartaArriba(i,x-SEPARACIONENTRECARTASMONTON,y-SEPARACIONENTRECARTASMONTON); blitCartaArriba(i,x,y); x=x+(ANCHOCARTA+SEPARACION); if(i==OLVIDAR) x=x+(ANCHOCARTA+SEPARACION); //El hueco entre DEJAR y los palos viene despues } posicion.x=BORDEPANTALLA; posicion.y=posicion.x; if(cartasTablero[SACAR]==0) SDL_BlitSurface(vacia,NULL,pantalla,&posicion); } void dibujarBordesPalos(void) { //Pequeña reparacion para que el borde sea un poco mayor y se vea rodeando al monton SDL_Rect bordeDentro,bordeFuera; int i; bordeDentro.w=ANCHOCARTA+SEPARACIONBORDEPALOS*2; bordeDentro.h=ALTOCARTA+SEPARACIONBORDEPALOS*2; bordeFuera.w=bordeDentro.w+GROSORBORDEPALOS*2; bordeFuera.h=bordeDentro.h+GROSORBORDEPALOS*2; bordeFuera.x=(BORDEPANTALLA+(ANCHOCARTA*3+SEPARACION*3))-(SEPARACIONBORDEPALOS+GROSORBORDEPALOS); bordeFuera.y=BORDEPANTALLA-(GROSORBORDEPALOS+SEPARACIONBORDEPALOS); bordeDentro.x=bordeFuera.x+GROSORBORDEPALOS; bordeDentro.y=bordeFuera.y+GROSORBORDEPALOS; for(i=0;i<4;i++) { SDL_FillRect(pantalla, &bordeFuera,SDL_MapRGB(pantalla->format,255,255,255)); SDL_FillRect(pantalla, &bordeDentro,SDL_MapRGB(pantalla->format,0,255,0)); bordeFuera.x=bordeFuera.x+SEPARACION+ANCHOCARTA; bordeDentro.x=bordeDentro.x+SEPARACION+ANCHOCARTA; } } void mostrarMesa(void) { //Aqui deberia pegarse una imagen guardada de la mesa SDL_FillRect(pantalla, NULL,SDL_MapRGB(pantalla->format,0,255,0)); dibujarBordesPalos(); dibujarMontones(); dibujarEscaleras(); } void blitCartaArriba(int posDelTablero, int x,int y) { blitCarta(posDelTablero,0,x,y); } SDL_Rect *cualSpriteCarta(int numCarta) { SDL_Rect *retorno=NULL; retorno=(SDL_Rect *)malloc(sizeof(SDL_Rect)); retorno->w=ANCHOCARTA; retorno->h=ALTOCARTA; retorno->x=(numCarta%13)*ANCHOCARTA; retorno->y=(numCarta/13)*ALTOCARTA; return retorno; }