Exemple #1
0
int lostLifeMsg( cursorType* cur, playField* pf, SDL_Surface* screen, const char* strmsg, const char* straction )
{
  draw(cur,pf, screen);
  //drawUi(screen);

  countdown-=getTicks();


    txtWriteCenter(screen, GAMEFONTMEDIUM, strmsg, HSCREENW,HSCREENH-24);

    if(countdown < 1000)
    {
      txtWriteCenter(screen, GAMEFONTSMALL, STR_MENU_PRESS_B, HSCREENW,HSCREENH+12);
      //Wait for anykey
      if(getButton(C_BTNB) || countdown < -6000 || getInpPointerState()->isDown )
      {
        resetBtn(C_BTNB);
        resetMouseBtn();
        //Subtract lives
        if(!player()->inEditor)
        {
          if(player()->lives != -1)
          {
            player()->lives--;
          }

          if(player()->lives==0)
          {
            setGameOver();
          } else {
            //Lost a life, but did not get gameover, upload the death
            statsUpload(player()->level, player()->hsEntry.time, player()->hsEntry.moves,player()->hsEntry.combos,player()->hsEntry.score, straction,0, NULL);
            setMenu(menuStateNextLevel);
          }
        }

        //Clear score
          player()->hsEntry.score=0;
        //Goto cleanup, then menu
        cleanUpGame();
        startTransition(screen, TRANSITION_TYPE_ROLL_IN, 700);
        return(1);
      }
    }
    return(0);
}
Exemple #2
0
void gameRestart(SDL_Surface* screen)
{
  restartConfirm=0;
  player()->hsEntry.score=0;
  //Save time before restarting
  timeBeforeRestart=pf.levelInfo->time;
  spentTimeBeforeRestart=player()->hsEntry.time;
  cleanUpGame();
//  startTransition(screen, TRANSITION_TYPE_DISSOLVE, 2500);
  initGame(screen);
  if(!player()->inEditor)
  {
    //Set time back to what it was before restarting
    pf.levelInfo->time=timeBeforeRestart;
    player()->hsEntry.time=spentTimeBeforeRestart;

    //Tell that we restarted
    statsUpload(player()->level, player()->hsEntry.time, player()->hsEntry.moves,player()->hsEntry.combos,player()->hsEntry.score, "reset-level",0, NULL);
  }
}
Exemple #3
0
int runGame(SDL_Surface* screen)
{
  if(gameState==GAMESTATEPLAYING)
  {
    getInpPointerState()->escEnable=1;
    //Handle input
    int lim=1; //Limit cursor travel...
    int goUp=0, goDown=0, goLeft=0, goRight=0;
    if( getButton( C_UP ) )
    {
      restartConfirm=0;
      if( getBtnTime( C_UP ) > REPEATDELAY )
      {
        goUp=1;
      } else if(getBtnTime(C_UP)==0) {
        goUp=1;
        lim=0;
      }
    }

    if( getButton( C_DOWN ) )
    {
      restartConfirm=0;
      if( getBtnTime( C_DOWN ) > REPEATDELAY )
      {
        goDown=1;
      } else if(getBtnTime(C_DOWN)==0) {
        goDown=1;
        lim=0;
      }
    }

    if( getButton( C_LEFT ) )
    {
      restartConfirm=0;
      if( getBtnTime( C_LEFT ) > REPEATDELAY )
      {
        goLeft=1;
      } else if(getBtnTime(C_LEFT)==0) {
        goLeft=1;
        lim=0;
      }
    }

    if( getButton( C_RIGHT ) )
    {
      restartConfirm=0;
      if( getBtnTime( C_RIGHT ) > REPEATDELAY )
      {
        goRight=1;
      } else if(getBtnTime(C_RIGHT)==0) {
        goRight=1;
        lim=0;
      }
    }

    //Pause ?
    if( getButton( C_BTNMENU ) || isPointerEscapeClicked() )
    {
      resetBtn( C_BTNMENU );
      gamePause(screen);
      return(STATEMENU);
    }

    //Retry
    if( getButton( C_BTNSELECT ) || (getInpPointerState()->timeSinceMoved<POINTER_SHOW_TIMEOUT && isBoxClicked(&ptrRestartRect)) )
    {
      resetBtn( C_BTNSELECT );
      resetMouseBtn();
      if(!restartConfirm)
      {
        restartConfirm=1;
      } else if(restartConfirm) {
        gameRestart(screen);
      }

    }

    //Handle mouse input
    if( getInpPointerState()->timeSinceMoved==0 && !cur.lock )
    {
      setCursor(&cur, getInpPointerState()->curX,getInpPointerState()->curY );
    }

    if(!getInpPointerState()->isDown)
    {
      mouseGrab=0;
      //Allow moving the cursor around with the input device when no brick is below, just for effect
    } else {
      brickType* b=brickUnderCursor(&pf, cur.x,cur.y);

      //We're over a brick, tell curser it's position, it will be locked later because we grab it now

      if( b )
      {
        getInpPointerState()->startX=b->dx;
        getInpPointerState()->startY=b->dy;
        if( !cur.lock )
        {
          mouseGrab=1;
          getInpPointerState()->startX=getInpPointerState()->curX;
          getInpPointerState()->startY=getInpPointerState()->curY;
        } else
        {
          if( b->dx > getInpPointerState()->curX )
          {
            //Drag Left
            if( b->dx == b->sx  && getInpPointerState()->startX != getInpPointerState()->curX )
            {
              goLeft=1;
            }
          } else if(  b->dx < getInpPointerState()->curX )
          {
            //Drag Right
            if( b->dx == b->sx && getInpPointerState()->startX != getInpPointerState()->curX )
            {
              goRight=1;
            }
          }
        }
      } else {
        mouseGrab=0;
      }
    }
   //   printf("x:%i\n", getInpPointerState()->curX );
      //Drag
    if( getButton( C_BTNX ) || getButton( C_BTNB ) || mouseGrab || isPointerClicked() )
    {
      //Remove "Restart" question
      restartConfirm=0;

      //Magnet to brick if it's moving
      brickType* b=brickUnderCursor(&pf, cur.dx, cur.dy);

      if( !cur.lock && b )
      {
        //Attach cursor
        cur.lock=1;
        b->curLock=1;
        cur.x=cur.dx;
        cur.y=cur.dy;
        cur.px = b->pxx-4;
        cur.py = b->pxy-4;

        sndPlay( SND_BRICKGRAB, cur.px );
      }

      int movedBrick=0;
      //We're holding a brick, and it's not falling
      if( b )
      {
        if( (goRight && curMoveBrick(&pf,b, DIRRIGHT)) || (goLeft && curMoveBrick(&pf,b, DIRLEFT)) )
        {
          movedBrick=1;
          b->curLock=1;
          cur.lock=1;
        }
      }

      //Moved brick
      if(movedBrick)
      {
        player()->hsEntry.moves++;
        sndPlay(SND_BRICKMOVE, cur.px);
        ps.layer=PSYS_LAYER_TOP;
        ps.x=b->pxx;
        ps.y=b->pxy+18;
        ps.vel=50;
        ps.life=500;
        ps.lifeVar=250;
        ps.gravity=1;
        ps.srcImg=stealGfxPtr()->tiles[b->type-1]->img;
        ps.srcRect=stealGfxPtr()->tiles[b->type-1]->clip;
        ps.srcRect.y += 18;
        ps.srcRect.h = 2;
        spawnParticleSystem(&ps);
      }

    }
    else
    {
      cur.lock=0;
    }

      if(!cur.lock)
      {
        if( goLeft ) moveCursor(&cur, DIRLEFT, 0, lim);
        if( goRight ) moveCursor(&cur, DIRRIGHT, 0, lim);
        if( goUp ) moveCursor(&cur, 0, DIRUP, lim);
        if( goDown ) moveCursor(&cur, 0, DIRDOWN, lim);
      }

    //Sim first, so moving blocks get evaluated before getting moved again
    simField(&pf, &cur);

    //Do rules
    int ret=doRules(&pf);

    //Draw scene
    draw(&cur,&pf, screen);

    //Draw a path to show where we are pulling the brick
    if( mouseGrab )
      drawPath( screen, getInpPointerState()->startX,getInpPointerState()->startY,getInpPointerState()->curX,getInpPointerState()->startY,1 );


    //If no more bricks, countdown time left.
    if(ret == NOBRICKSLEFT)
    {
      if( !justWon )
      {
        sndPlay(SND_WINNER,160);
      }
      justWon++;
      pf.levelInfo->time -= 1000;
      player()->hsEntry.score +=1;

      if(getButton(C_BTNX) || getButton(C_BTNB) || isPointerClicked() )
      {
        resetBtn(C_BTNX);
        resetBtn(C_BTNB);
        resetMouseBtn();
        while(pf.levelInfo->time > 0)
        {
          player()->hsEntry.score +=1;
          pf.levelInfo->time -= 1000;
        }
      }

      if(justWon > 50)
      {
        sndPlayOnce(SND_SCORECOUNT, 160);
      }
      if(pf.levelInfo->time < 1)
      {
        //Completed level
        player()->timeouts=0;
        pf.levelInfo->time=0;
        sndPlay(SND_VICTORY, 160);

        if(!player()->inEditor)
        {
          //Don't submit if it was from the leveleditor
          statsSubmitBest();
          setMenu(menuStateFinishedLevel);
          if(pf.levelInfo->stopImg)
          {
            gameState=GAMESTATESTOPIMAGE;
            return(STATEPLAY);
          }
        } else {
          setLevelCompletable(pf.levelInfo->file, 1);
        }
        cleanUpGame();
        startTransition(screen, TRANSITION_TYPE_ROLL_IN, 700);
        return(STATEMENU);
      }
    } else if(ret > 0) //Player destroyed bricks.
    {
      if(ret > 2) //Check for combo's
      {
        ///TODO: Some nice text effect? How about dissolving an image into a particle system?
        printf("%i Combo!\n",ret);
        player()->hsEntry.combos++;
      }
      player()->hsEntry.score += ret*ret*11*(player()->level+1);
    }

    //if ret > -1 then ret == number of bricks destroyed
    if(ret>-1)
    {
      //Update time:
      pf.levelInfo->time -= getTicks();
      player()->hsEntry.time += getTicks();
      if(pf.levelInfo->time < 1 && ret!=NOBRICKSLEFT )
      {
        countdown=4000;
        gameState=GAMESTATEOUTOFTIME;
        if( !player()->inEditor )
        {
          player()->timeouts++;
        }

        sndPlay(SND_TIMEOUT, 160);
      }
    }

    //Check if level is unsolvable.
    if(ret==UNSOLVABLE)
    {
      countdown=2000;
      gameState=GAMESTATEUNSOLVABLE;
      if( !player()->inEditor )
      {
        player()->timeouts++;
      }

      sndPlay(SND_LOSER, 160);
    } else if(ret==LIFELOST)
    {
      countdown=2000;
      gameState=GAMESTATELIFELOST;

      if( !player()->inEditor )
      {
        player()->timeouts++;
      }

      sndPlay(SND_LOSER, 160);

    }


    //Draw question
    if(restartConfirm)
    {
      sprintf(buf,STR_GAME_RESTARTWARNING);
      txtWriteCenter(screen, GAMEFONTMEDIUM, buf, HSCREENW, HSCREENH-20);
      sprintf(buf,STR_GAME_RESTARTCONFIRM);
      txtWriteCenter(screen, GAMEFONTSMALL, buf, HSCREENW, HSCREENH);
    } else {
      //Draw text
      drawUi(screen);
    }
    //Show the restart icon
    if(getInpPointerState()->timeSinceMoved<POINTER_SHOW_TIMEOUT && getInpPointerState()->escEnable)
    {
      SDL_Rect ptrRestartRectC = ptrRestartRect;
      SDL_BlitSurface( ptrRestart,NULL, screen, &ptrRestartRectC );
    }


  } else
  if(gameState==GAMESTATECOUNTDOWN)
  {

    draw(&cur,&pf, screen);
    countdown -=getTicks();

    if( getButton( C_BTNMENU ) )
    {
      resetBtn( C_BTNMENU );
      countdownSeconds=0;
      countdown=0;
    }

    if( (getButton( C_BTNX ) || getButton( C_BTNB ) || getInpPointerState()->isDown ) && countdownSeconds )
    {
      countdownSeconds=0;
      countdown=500;
    }

    drawShowCountDown(screen, countdownSeconds);

    drawUi(screen);

    if(countdown < 1)
    {
      countdown=1000;
      countdownSeconds--;

      if(countdownSeconds == -1)
      {
        gameState=GAMESTATEPLAYING;
        return(STATEPLAY);
      }
      if(countdownSeconds==0)
      {
        countdown=500;
        sndPlay(SND_START, 160);
      } else {
        sndPlay(SND_COUNTDOWNTOSTART, 160);
      }
    }

  } else
  if(gameState==GAMESTATEOUTOFTIME) //Menu was last in "Entering level" so it will return to that if timeout
  {
    draw(&cur,&pf, screen);
    //drawUi(screen);

    countdown-=getTicks();

    //Offer to skip after dying twice on same level, but only if it is not the last level in the pack.
    if( player()->timeouts > 1 && player()->level+1 < getNumLevels() )
    {
      int skipLevel = skipLevelDialog(screen);
      if( skipLevel==1 )
      {
        gameState=GAMESTATESKIPLEVEL;
        countdown=500;
      }
      txtWriteCenter(screen, GAMEFONTMEDIUM, STR_GAME_OUTOFTIME, HSCREENW,HSCREENH-24-31);
    } else {
      if( lostLifeMsg(&cur, &pf, screen, STR_GAME_OUTOFTIME, "lostlife-timeout" ) )
      {
        return(STATEMENU);
      }
    }

  } else
  if(gameState==GAMESTATEUNSOLVABLE) //The same as out-of-time, but with another graphics.
  {
    draw(&cur,&pf, screen);
    //drawUi(screen);

    countdown-=getTicks();

    //Offer to skip after dying twice on same level, but only if it is not the last level in the pack.
    if( player()->timeouts > 1 && player()->level+1 < getNumLevels() )
    {
      int skipLevel = skipLevelDialog(screen);
      if( skipLevel==1 )
      {
        gameState=GAMESTATESKIPLEVEL;
        countdown=500;
      }
      txtWriteCenter(screen, GAMEFONTMEDIUM, buf, HSCREENW,HSCREENH-24-31);

    } else {
      if( lostLifeMsg(&cur, &pf, screen, STR_GAME_UNSOLVABLE, "lostlife-unsolvable" ) )
      {
        return(STATEMENU);
      }
    }


  } else
  if(gameState==GAMESTATELIFELOST)
  {
    if( lostLifeMsg(&cur, &pf, screen, STR_GAME_LOSTLIFE, "lostlife-evilbrick" ) )
    {
      return(STATEMENU);
    }
  } else
  if(gameState==GAMESTATESTARTIMAGE)
  {

    if(!startStopImg)
    {
      startStopImgCounter=0;
      startStopImg = loadImg( packGetFile("themes/", pf.levelInfo->startImg) );
      if(!startStopImg)
      {
        printf("Couldn't load '%s'\n",packGetFile("themes/", pf.levelInfo->startImg));
      }
    }

    startStopImgCounter+=getTicks();

    if((startStopImgCounter > 500 && ( getButton(C_BTNB) || isPointerClicked() ) ) || !startStopImg)
    {
      if(startStopImg)
        SDL_FreeSurface(startStopImg);
      startStopImg=0;
      resetBtn(C_BTNB);
      resetMouseBtn();
      gameState=GAMESTATECOUNTDOWN;
    }

    SDL_BlitSurface( startStopImg, 0, screen, &(setting()->bgPos) );

    if(startStopImgCounter>4000)
      txtWriteCenter(screen, GAMEFONTSMALL, STR_GAME_PRESSB, HSCREENW,HSCREENH+80);

  } else if(gameState==GAMESTATESTOPIMAGE)
  {
    if(!startStopImg)
    {
      startStopImgCounter=0;
      startStopImg = loadImg( packGetFile("themes/", pf.levelInfo->stopImg) );
      if(!startStopImg)
      {
        printf("Couldn't load '%s'\n",packGetFile("themes/", pf.levelInfo->stopImg));
      }
    }

    startStopImgCounter+=getTicks();

    if((startStopImgCounter > 500 && (getButton(C_BTNB) || isPointerClicked() ) ) || !startStopImg)
    {
      if(startStopImg)
        SDL_FreeSurface(startStopImg);
      startStopImg=0;
      resetBtn(C_BTNB);
      resetMouseBtn();
      cleanUpGame();
      startTransition(screen, TRANSITION_TYPE_ROLL_IN, 700);
      return(STATEMENU);
    }

    SDL_BlitSurface( startStopImg, 0, screen, &(setting()->bgPos) );
    if(countdownSeconds>4000)
      txtWriteCenter(screen, GAMEFONTSMALL, STR_GAME_PRESSB, HSCREENW,HSCREENH+80);

  } else if(gameState==GAMESTATESKIPLEVEL)
  {

    doRules(&pf);
    simField(&pf, &cur);
    draw(&cur,&pf, screen);

    countdown-=getTicks();

    if( countdown < 1 )
    {
      countdown=500;

      if( boardDestroyNextBrick(&pf) == 0 )
      {

        //Tell that we chose to skip level
        statsUpload(player()->level, player()->hsEntry.time, player()->hsEntry.moves,player()->hsEntry.combos,player()->hsEntry.score, "skip-level",0, NULL);

        pf.levelInfo->time=0;
        player()->hsEntry.score=0;
        cleanUpGame();
        startTransition(screen, TRANSITION_TYPE_ROLL_IN, 700);
        clearParticles();
        setMenu(menuStatePrepareNextLevel);
        return(STATEMENU);
      }
    }
    drawUi(screen);

  }
  return(STATEPLAY);
}
Exemple #4
0
static void setGameOver()
{
  statsUpload(player()->level, player()->hsEntry.time, player()->hsEntry.moves,player()->hsEntry.combos,player()->hsEntry.score, "gameover",0, NULL);
  setMenu(menuStateGameOver);
}
Exemple #5
0
int main(int argc, char *argv[])
{
  int doScale=0; // 0=Undefined, 1=320x240, -1=OpenGL, >1=SwScale
  char* dumpPack=NULL;
  int state=1; //Game, Menu, Editor, Quit
  int sdlVideoModeFlags = SDL_SWSURFACE;

  #ifdef PSP
    //Note to PSP porter, please test if HW is actually faster, Wizznic does a lot of memory-manipulation in the screen-surface, each call might initiate a full copy back/forth from video memory. Remove comment when read. :)
    sdlVideoModeFlags = (SDL_HWSURFACE | SDL_DOUBLEBUF |SDL_HWACCEL);
    SetupCallbacks();//Callbacks actifs
    scePowerSetClockFrequency(333,333,166);
  #endif

//  #ifdef WIN32
//Redirect stdout to console on windows, so we can see what's going in.
//  FILE *stream;
//  stream = freopen("CON", "w", stdout);
//  #endif

  //Print welcome message
  printf( "Wizznic "VERSION_STRING". GPLv3 or newer Copyleft 2010-2013\n\n");

  //initialize path strings
  initUserPaths();

  //Tell where stuff's at.
  printf("Directories:\n    Settings: %s\n    DLC: %s\n    Highscores: %s\n    Editorlevels: %s\n    Datafiles: %s\n\n", \
                            getConfigDir(), getUsrPackDir(), getHighscoreDir(), getUserLevelDir(), (!strlen(DATADIR))?".":DATADIR);

  //Print the command line parameters
  printf("Command-line parameters:\n"STR_VID_OPTIONS);

  //Quit if user wants help
  if( argc > 1 && ( strcmp(argv[1], "-h")==0 || strcmp(argv[1], "--help")==0 || strcmp(argv[1], "-help")==0 ))
  {
    printf("Please see readme.txt or http://wizznic.org/ for more help.\n");
    return(0);
  }

  //Read settings
  printf("Loading settings...\n");
  initSettings();

  #if defined(WITH_OPENGL)
  //We start by enabling glScaling if it was enabled in settings, it can then be overwritten by command line options.
  if( setting()->glEnable && doScale==0 )
    doScale=-1;
  #endif

  //Set scaling
  setting()->scaleFactor=1.0;

  atexit(SDL_Quit);

  //Init SDL
  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_TIMER ) <0 )
  {
    printf("SDL_Init failed: %s\n",SDL_GetError());
    return(-1);
  }

  //Setup display
  #if defined (GP2X) || defined (PSP) || defined (WIZ)
  SDL_Surface* screen = SDL_SetVideoMode(SCREENW,SCREENH,16, sdlVideoModeFlags);
  #else
  SDL_Surface* screen=NULL;

  int i;
  for( i=0; i < argc; i++ )
  {
    if( strcmp( argv[i], "-sw" ) == 0 )
    {
      setting()->glEnable=0;
      doScale=0;
      saveSettings();
    } else
    if( strcmp( argv[i], "-gl" ) == 0 )
    {
      setting()->glEnable=1;
      doScale=-1;
      saveSettings();
    } else
    if( strcmp( argv[i], "-z" ) == 0 )
    {
      if( i+1 < argc )
      {
        doScale = atoi( argv[i+1] );
        setting()->glEnable=0;
        i++;
        saveSettings();
      } else {
        printf(" -z requires zoom level ( -z 2 for example ).\n");
        return(1);
      }
    } else
    if( strcmp( argv[i], "-f" ) == 0 )
    {
        setting()->fullScreen=1;
        saveSettings();
    } else
    if( strcmp( argv[i], "-w" ) == 0 )
      {
        setting()->fullScreen=0;
        saveSettings();
    } else if( strcmp( argv[i], "-glheight" ) == 0 )
    {
      if( i+1 < argc )
      {
        setting()->glHeight = atoi( argv[i+1] );
        setting()->glEnable=1;
        doScale=-1;
        i++;
        printf("Setting OpenGL window height to %i.\n", setting()->glHeight);
        saveSettings();
      } else {
        printf(" -glheight requires an argument (-1 or size in pixels).\n");
        return(1);
      }
    } else if( strcmp( argv[i], "-glwidth" ) == 0 )
    {
      if( i+1 < argc )
      {
        setting()->glWidth = atoi( argv[i+1] );
        setting()->glEnable=1;
        doScale=-1;
        i++;
        printf("Setting OpenGL window width to %i.\n", setting()->glWidth);
        saveSettings();
      } else {
        printf(" -glwidth requires an argument (-1 or size in pixels).\n");
        return(1);
      }
    } else if( strcmp( argv[i], "-glfilter" ) == 0 )
    {
      if( i+1 < argc )
      {
        setting()->glFilter=atoi(argv[i+1]);
        printf("OpenGL texture filtering set to %s.\n", (setting()->glFilter)?"Smooth":"Off");
        i++;
        saveSettings();
      } else {
        printf("-glfilter requires 0 or 1 as argument.\n");
        return(1);
      }
    } else if( strcmp( argv[i] , "-d" ) == 0 )
    {
      if( argc == 3 && i < argc+1 )
      {
        dumpPack = malloc( sizeof(char)*strlen(argv[i+1])+1 );
        strcpy( dumpPack, argv[i+1] );
        doScale=0;
        setting()->glEnable=0;
        i++;
      } else {
        printf("-d requires a packname, and must not be used with other parameters.\n");
        return(1);
      }
    } else if( strcmp( argv[i], "-rift") == 0 )
    {
      setting()->glWidth = 1280;
      setting()->glHeight = 800;
      setting()->glEnable=1;
      setting()->rift=1;
      doScale=-1;
    } else if( i > 0 )
    {
      printf("\nError: Invalid argument '%s', quitting.\n", argv[i]);
      return(1);
    }

  }

  if( setting()->fullScreen )
  {
    sdlVideoModeFlags |= SDL_FULLSCREEN;
  }

  if(doScale)
  {
    //Hardware accelerated scaling
    if( doScale == -1 )
    {
    #ifdef HAVE_ACCELERATION
      printf("Enabling platform specific accelerated scaling.\n");
      screen = platformInitAccel(sdlVideoModeFlags);
      if( !screen )
      {
        printf("Failed to set platform accelerated scaling, falling back to software window.\n");
        screen=swScreen(SDL_SWSURFACE);
        doScale=0;
      }
    #else
      printf("\nError:\n  Not compiled with hardware-scaling support, don't give me -z -1\n  Exiting...\n");
      return(-1);
    #endif
    } else if( doScale > 0 )
    {
    #ifdef WANT_SWSCALE
      //Set up software scaling
      printf("Enabling slow software-based scaling to %ix%i.\n",320*doScale, 240*doScale);
      screen = swScaleInit(sdlVideoModeFlags,doScale);
    #else
      printf("\nError:\n  I don't support software scaling, don't give me any -z options\n  Exiting...\n");
      return(-1);
    #endif
    }
  } else {
    screen=swScreen(sdlVideoModeFlags);
    doScale=0;
  }

  printf("Scaling factor: %f\n", setting()->scaleFactor);

  if( screen == NULL )
  {
    printf("ERROR: Couldn't init video.\n");
    return(-1);
  }


  //Set window title
  SDL_WM_SetCaption("Wizznic!", "Wizznic!");
  //Set window icon
  SDL_Surface* icon = IMG_Load( DATADIR"data/wmicon.png");
  SDL_WM_SetIcon(icon, NULL);
  SDL_FreeSurface(icon);

  #endif

  setting()->bpp = screen->format->BytesPerPixel;
  setAlphaCol( setting()->bpp );

  printf("Screen surface using %i bytes per pixel.\n",setting()->bpp);

  //Open Joysticks (for wiz)
  if (SDL_NumJoysticks() > 0) SDL_JoystickOpen(0);

  //Hide mouse cursor
  SDL_ShowCursor(SDL_DISABLE);

  //Load fonts
  txtInit();

  //Load sounds
  if(!initSound())
  {
    printf("Couldn't init sound.\n");
    return(-1);
  }

  //Menu Graphics
  if(!initMenu(screen))
  {
    printf("Couldn't load menu graphics.\n");
    return(-1);
  }

  //Init controls
  initControls();

  //Init stats
  statsInit();

  //Init packs
  packInit();

  //Scan userlevels dir
  makeUserLevelList(screen);

  //Init particles
  initParticles(screen);

  //Seed the pseudo random number generator (for particles 'n' stuff)
  srand( (int)time(NULL) );

  #if defined(PC)
  //Need to dump level-screenshots?
  if(dumpPack)
  {
    printf("Dumping level-images for pack: %s\n", dumpPack);
    dumplevelimages(screen, dumpPack, 0);
    return(0);
  }
  #endif

  //init starfield
  initStars(screen);

  //Init pointer
  initPointer(screen);

  printf("Applying settings..\n");
  //Apply settings (has to be done after packs are inited)
  applySettings();
  //Set Pack
  packSetByPath( setting()->packDir );

  #if defined( PLATFORM_SUPPORTS_STATSUPLOAD )
  if( (setting()->uploadStats) && !(setting()->firstRun) )
  {
    statsUpload(0,0,0,0,0,"check",1, &(setting()->session) );
    statsUpload(0,0,0,0,0,"q_solved",1, &(setting()->solvedWorldWide) );

    //DLC only works when stats-uploading is enabled so we can use the same nag-screen.
    dlcCheckOnline();
  }
  #endif

  printf("Setting Music...\n");
  //Start playing music (has to be done after readong settings)
  soundSetMusic();

  //Initialize credits
  initCredits(screen);

  initTransition();


#if SCREENW != 320 || SCREENH != 240
  SDL_Rect *borderSrcRect = malloc(sizeof(SDL_Rect));
  SDL_Surface* border = loadImg( BORDER_IMAGE );
  if( border )
  {
    printf("Border image loaded.\n");
    borderSrcRect->x=(border->w-SCREENW)/2;
    borderSrcRect->y=(border->h-SCREENH)/2;
    borderSrcRect->w=SCREENW;
    borderSrcRect->h=SCREENH;
    SDL_BlitSurface( border, borderSrcRect, screen, NULL );
    SDL_FreeSurface(border);
  } else {
    printf("Could not load border image: %s\n", BORDER_IMAGE);
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0,0,0));
  }
  free(borderSrcRect);
  borderSrcRect=NULL;

#endif

  int lastTick;
  while(state!=STATEQUIT)
  {
    lastTick=SDL_GetTicks();

    frameStart();

    if(runControls()) state=STATEQUIT;
    switch(state)
    {
      case STATEPLAY:
        state = runGame(screen);
      break;

      case STATEMENU:
        state = runMenu(screen);
      break;

      case STATEEDIT:
        state=runEditor(screen);
      break;
    }

    drawPointer(screen);

    soundRun(screen,state);

    runTransition(screen);

    if(setting()->showFps)
      drawFPS(screen);

    switch( doScale )
    {
      #if defined(HAVE_ACCELERATION)
      case -1:
        platformDrawScaled(screen);
        break;
      #endif
      case 0:
        SDL_Flip(screen);
        break;
      #if defined(WANT_SWSCALE)
      default:
        swScale(screen,doScale);
        break;
      #else
      default:
        state=STATEQUIT;
      break;
      #endif
    }

    #if defined(CRUDE_TIMING)
    //Oh how I loathe this, is there no better way?
    while(SDL_GetTicks()-lastTick <= PLATFORM_CRUDE_TIMING_TICKS)
    {
      //Burn, burn baby burn!
    }
    #else
    int t=SDL_GetTicks()-lastTick;
    if(t < 20)
    {
      SDL_Delay( 20 -t);
    }
    #endif
  }

  #if defined(PLATFORM_NEEDS_EXIT)
  platformExit();
  #endif

  SDL_Quit();

  return(0);
}