Exemplo n.º 1
0
void drawAllTelePaths( SDL_Surface* screen, listItem* l )
{
  listItem* it = l;
  telePort_t* t;

  while( (it=it->next) )
  {
    t = (telePort_t*)it->data;
    drawTelePath(screen, t, 0);
  }
}
Exemplo n.º 2
0
void draw(cursorType* cur, playField* pf, SDL_Surface* screen)
{
  int x,y;
  listItem* t; //general purpose, reusable
  psysSet_t ps;

  SDL_BlitSurface(graphics.boardImg , NULL, screen, &(setting()->bgPos) );

  for(x=0;x<NUMTILES;x++)
  {
    playAni(graphics.tileAni[x]);
  }

  //Draw static bricks
  for(y=0; y < FIELDSIZE; y++)
  {
    for(x=0; x < FIELDSIZE; x++)
    {
      //Bricks-Walls
      if(pf->board[x][y] && pf->board[x][y]->type != RESERVED)
      {
        //We treat walls/glue/oneways/switches/evilbricks/copybricks and rembricks as walls (they will have the walltile defined)
        if( isWall(pf, x, y) )
        {
          drawSprite(screen, graphics.walls[pf->board[x][y]->wall], pf->board[x][y]->pxx, pf->board[x][y]->pxy);
        }

        if( pf->board[x][y]->type != STDWALL && graphics.tiles[pf->board[x][y]->type-1])
        {
          //We draw the animated extra-tiles if they exist.
          if(graphics.tileAni[pf->board[x][y]->type-1])
          {
            if( !isSwitch( pf->board[x][y] ) )
            {
              drawAni(screen, graphics.tileAni[pf->board[x][y]->type-1], pf->board[x][y]->pxx-5, pf->board[x][y]->pxy-5);
            } else {
              //We only end here when it's a switch
              if( (pf->board[x][y]->type==SWON)?pf->board[x][y]->isActive:!pf->board[x][y]->isActive)
              {
                drawAni(screen, graphics.tileAni[SWON-1], pf->board[x][y]->pxx-5, pf->board[x][y]->pxy-5);
              } else {
                drawAni(screen, graphics.tileAni[SWOFF-1], pf->board[x][y]->pxx-5, pf->board[x][y]->pxy-5);
              }
            }
          //Fall back to the static non-moving tiles if no animation is found.
          } else {
            if( !isSwitch( pf->board[x][y] ) )
            {
              drawSprite(screen, graphics.tiles[pf->board[x][y]->type-1], pf->board[x][y]->pxx, pf->board[x][y]->pxy);
            } else {
              if( (pf->board[x][y]->type==SWON)?pf->board[x][y]->isActive:!pf->board[x][y]->isActive)
              {
                drawSprite(screen, graphics.tiles[SWON-1], pf->board[x][y]->pxx, pf->board[x][y]->pxy);
              } else {
                drawSprite(screen, graphics.tiles[SWOFF-1], pf->board[x][y]->pxx, pf->board[x][y]->pxy);
              }
            }
          }
        } // not a wall.
      } //Not a reserved brick.
      /*else if( pf->board[x][y] && pf->board[x][y]->type == RESERVED )
      {
        drawSprite(screen, graphics.tiles[RESERVED-1], x*brickSize+boardOffsetX, y*brickSize+boardOffsetY);
      }*/
    }
  } //xy loop

  //Draw moving bricks
  t=pf->movingList;
  brickType* b;
  while( (t = t->next) )
  {
    b=(brickType*)t->data;

    if(graphics.tileAni[b->type-1])
    {
      drawAni(screen, graphics.tileAni[b->type-1], b->pxx-5, b->pxy-5);
    } else {
      drawSprite(screen, graphics.tiles[b->type-1], b->pxx, b->pxy);
    }
  }

  //Particle systems that are between bricks and die animantion
  runParticlesLayer(screen, PSYS_LAYER_UNDERDEATHANIM);


  //Draw dying bricks, animation?
  t=pf->removeList;

  while( (t = t->next) )
  {
    b=(brickType*)t->data;
    //Draw base brick if time enough left
    if(b->tl > (pf->levelInfo->brick_die_ticks/2))
    {
      if(graphics.tileAni[b->type-1])
      {
        drawAni(screen, graphics.tileAni[b->type-1], b->pxx-5, b->pxy-5);
      } else {
        drawSprite(screen, graphics.tiles[b->type-1], b->pxx, b->pxy);
      }
    }


    int explFrame = 16*(pf->levelInfo->brick_die_ticks-b->tl)/pf->levelInfo->brick_die_ticks;

    drawAniFrame(screen, graphics.brickExpl[b->type-1], b->pxx-5, b->pxy-5,explFrame);

    //Spawn particles for brick death
    if(explFrame==8 && pf->levelInfo->brickDieParticles)
    {
      ps.layer=pf->levelInfo->brickDieParticles;
      ps.x=b->pxx;
      ps.y=b->pxy;
      ps.vel=50;
      ps.life=750;
      ps.lifeVar=1000;
      ps.gravity=0;
      ps.bounce=0;
      ps.srcImg=graphics.tiles[b->type-1]->img;
      ps.srcRect=graphics.tiles[b->type-1]->clip;
      spawnParticleSystem(&ps);
    }

  }

  //Teleport overlay
  t = pf->levelInfo->teleList;
  telePort_t* tp;
  while( (t=t->next) )
  {
    tp = (telePort_t*)t->data;

    if(graphics.tileAni[TELESRC-1])
    {
      drawAni(screen, graphics.tileAni[TELESRC-1], boardOffsetX+20*tp->sx-5, boardOffsetY+20*tp->sy-5);
    } else {
      drawSprite(screen, graphics.tiles[TELESRC-1], boardOffsetX+20*tp->sx, boardOffsetY+20*tp->sy);
    }


    //if cursor is on it, draw the path too
    if(cur->x == tp->sx && cur->y == tp->sy)
    {
      drawTelePath( screen, tp, 1 );
    }
  }

  //Particles
  runParticles(screen);

  //Cursor
  updateCursor(cur);
  if(!cur->lock)
    drawSprite(screen, graphics.curSpr[0], cur->px, cur->py);
  else
    drawSprite(screen, graphics.curSpr[1], cur->px, cur->py);


  if(graphics.curSpr[0] && cur->moving )
  {
    ps.layer=PSYS_LAYER_TOP;
    ps.x=cur->px;
    ps.y=cur->py;
    ps.vel=50;
    ps.life=100;
    ps.lifeVar=100;
    ps.gravity=0;
    ps.srcImg=graphics.curSpr[0]->img;
    ps.srcRect=graphics.curSpr[0]->clip;

    spawnParticleSystem(&ps);
  }

}
Exemplo n.º 3
0
int runEditor(SDL_Surface* screen)
{
  SDL_Rect selBrickRect;
  getInpPointerState()->escEnable=1;

  if( editorState == EDITOR_MAIN )
  {

    if(getButton(C_BTNMENU) || isPointerEscapeClicked() )
    {
      resetBtn( C_BTNMENU );
      resetMouseBtn();

      changed++; //If it was 0 then it will become 1 (saved) exit. If it was 1 it becomes 2 (not saved).
      if( changed != 2 )
      {
        editorCleanUp();
        startTransition(screen, TRANSITION_TYPE_ROLL_IN, 500 );
        return(STATEMENU);
      }
    }

    //We detect if the "preview" brick on the left is clicked, we do this now so we can reset the click so that it does not hit the board
    selBrickRect.x = HSCREENW-125;
    selBrickRect.y = HSCREENH-85;
    selBrickRect.w = selBrickRect.x+20;
    selBrickRect.h = selBrickRect.y+20;
    //Also, we can only click it if a teleport destination is not being placed.
    if( isBoxClicked(&selBrickRect) && teleState==0 )
    {
      editorState=EDITOR_BRICKS_SELECTION;
      resetMouseBtn();
    }

    //We detect mouse-save input here so it won't hit the board.
    selBrickRect.x = HSCREENW-145;
    selBrickRect.y = HSCREENH+42;
    selBrickRect.w = selBrickRect.x+59;
    selBrickRect.h = selBrickRect.y+24;
    if( isBoxClicked(&selBrickRect) && changed>0)
    {
      changed=EDITOR_SAVEBTN_CLICKED;
      resetMouseBtn();
    }

    //We check if the cursor is in the field (if it is not, brick-placement is blocked so we don't place bricks when clicking outside of the field).
    if( isPointerInBox(&fieldRect) || getInpPointerState()->timeSinceMoved > POINTER_SHOW_TIMEOUT )
    {
      allowBrickToBePlaced=1;
    } else {
      allowBrickToBePlaced=0;
    }

    //Handle movement
    if(getButton(C_UP))
    {
      resetBtn(C_UP);
      moveCursor(&cur, 0,DIRUP, 0);
    }

    if(getButton(C_DOWN))
    {
      resetBtn(C_DOWN);
      moveCursor(&cur, 0,DIRDOWN,0);
    }

    if(getButton(C_LEFT))
    {
      resetBtn(C_LEFT);
      moveCursor(&cur, DIRLEFT,0, 0);
    }

    if(getButton(C_RIGHT))
    {
      resetBtn(C_RIGHT);
      moveCursor(&cur, DIRRIGHT,0, 0);
    }

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

    if(getButton(C_BTNB))
    {
      resetBtn(C_BTNB);
      selBrick++;

      if(selBrick==RESERVED)
        selBrick++;

      if(selBrick>NUMTILES)
        selBrick=1;
    }

    if(getButton(C_BTNA))
    {
      resetBtn(C_BTNA);

      selBrick--;
      if(selBrick==RESERVED)
        selBrick--;

      if(selBrick<1)
        selBrick=NUMTILES;
    }



    //Is place brick button being pressed, and if it is, are we allowed to place the brick?
    if( (getButton(C_BTNX) || getInpPointerState()->isDown ) && selBrick != RESERVED && allowBrickToBePlaced )
    {

      //We remove the brick before placing a new one if it's not a teleport or if it's a switch (not switch-target).
      if( selBrick!=TELESRC && !((editIsSwitch(selBrick)&&teleState==1)  ) )
      {
        editorRemoveBrickUnderCursor();
      }

      if(selBrick==TELESRC || editIsSwitch(selBrick) )
      {
        resetMouseBtn();
        resetBtn(C_BTNX);

        if(teleState==0)
        {
          //Save source pos
          teleSrcPos[0] = cur.x;
          teleSrcPos[1] = cur.y;
          teleState++;
        } else {
          //Add to list
          if(editIsSwitch(selBrick))
          {
            teleAddToList( pf.levelInfo->switchList, teleSrcPos[0], teleSrcPos[1], cur.x, cur.y );
            //printf("Number of members in switchList: %i\n", listSize(pf.levelInfo->switchList) );
            cur.x = teleSrcPos[0];
            cur.y = teleSrcPos[1];
            editAddToBoard(selBrick);
          } else {
            teleAddToList( pf.levelInfo->teleList, teleSrcPos[0], teleSrcPos[1], cur.x, cur.y );
          }
          //Reset state
          teleState=0;
        }
      } else {
        editAddToBoard(selBrick);
      } //Not a teleport

      changed=1;
    }

    if( getButton(C_BTNY) )
    {
      //If we are trying to remove an empty teleport
      if(telePresent(pf.levelInfo->teleList, cur.x, cur.y) && selBrick!=TELESRC)
      {
        resetBtn(C_BTNY);
        selBrick=TELESRC;
      } else {
        if(selBrick!=RESERVED)
        {
          editorPickBrickUnderCursor();
        }
        editorRemoveBrickUnderCursor();
      }
    }

    if( getInpPointerState()->isDown && selBrick==RESERVED )
    {
      editorRemoveBrickUnderCursor();
    }

    if(getButton(C_BTNSELECT) || changed==EDITOR_SAVEBTN_CLICKED)
    {
      resetBtn(C_BTNSELECT);
      FILE *f = fopen(fileName, "w");
      int x,y;
      sprintf(buf, "#Author of level\nauthor=%s\n\n", pf.levelInfo->author);
      fputs(buf,f);

      sprintf(buf, "#Name of the level\nlevelname=%s\n\n", pf.levelInfo->levelName);
      fputs(buf,f);

      sprintf(buf, "#Seconds to complete level\nseconds=%i\n\n", pf.levelInfo->time);
      fputs(buf,f);

      sprintf(buf, "bgfile=%s\n", pf.levelInfo->bgFile);
      fputs(buf,f);

      sprintf(buf, "tilebase=%s\n", pf.levelInfo->tileBase);
      fputs(buf,f);

      sprintf(buf, "explbase=%s\n", pf.levelInfo->explBase);
      fputs(buf,f);

      sprintf(buf, "wallbase=%s\n", pf.levelInfo->wallBase);
      fputs(buf,f);

      sprintf(buf, "sounddir=%s\n", pf.levelInfo->soundDir);
      fputs(buf,f);

      sprintf(buf, "charbase=%s\n", pf.levelInfo->fontName);
      fputs(buf,f);

      sprintf(buf, "cursorfile=%s\n", pf.levelInfo->cursorFile);
      fputs(buf,f);

      sprintf(buf, "startimage=%s\n", (pf.levelInfo->startImg)?pf.levelInfo->startImg:"none");
      fputs(buf,f);

      sprintf(buf, "stopimage=%s\n", (pf.levelInfo->stopImg)?pf.levelInfo->stopImg:"none");
      fputs(buf,f);

      sprintf(buf, "showtelepath=%i\n", (pf.levelInfo->showTelePath) );
      fputs(buf,f);

      sprintf(buf, "showswitchpath=%i\n", (pf.levelInfo->showSwitchPath) );
      fputs(buf,f);


      //Teleports
      char* str = teleMkStrings(pf.levelInfo->teleList, "teleport");
      if(str) //Returns 0 if there's no teleports
      {
        fputs("\n#Teleports\n",f);
        fputs(str,f);
        free(str);
      }

      //Switches
      str = teleMkStrings(pf.levelInfo->switchList, "switch");
      if(str) //Returns 0 if there's no teleports
      {
        fputs("\n#Switches\n",f);
        fputs(str,f);
        free(str);
      }



      fputs("\n#The level-data block\n[data]",f);

      if(f)
      {
        for(y=0; y < FIELDSIZE; y++)
        {
          fputc('\n',f);
          for(x=0; x < FIELDSIZE; x++)
          {
            if(pf.board[x][y])
            {
              fprintf(f,"%02i", pf.board[x][y]->type);
            } else {
              fprintf(f,"00");
            }
          }
        }
        fputc('\n',f);
        changed=0;
        fclose(f);

        //Refresh the list of userLevels.
        addUserLevel(fileName);
      }

    }

  } //Editor in main state, don't ignore input


  draw(&cur, &pf, screen);


  if(changed==2)
  {
    txtWriteCenter(screen, FONTMEDIUM, STR_EDIT_NOT_SAVED_WARNING, HSCREENW,HSCREENH-20);
    txtWriteCenter(screen, FONTSMALL, STR_EDIT_PRESS_EXIT_TO_EXIT, HSCREENW,HSCREENH);
    txtWriteCenter(screen, FONTSMALL, STR_EDIT_PRESS_SAVE_TO_SAVE, HSCREENW,HSCREENH+10);
  }


  txtWriteCenter(screen, FONTSMALL,STR_EDIT_STATUS, HSCREENW-115,HSCREENH+80);
  txtWriteCenter(screen, FONTSMALL, (changed)?STR_EDIT_UNSAVED:STR_EDIT_SAVED, HSCREENW-115,HSCREENH+89);

  txtWriteCenter(screen, FONTSMALL,fileName, HSCREENW,HSCREENH+110);

  txtWriteCenter(screen, FONTSMALL,STR_EDIT_CONTROLS, HSCREENW,HSCREENH-120);


  //Write which keys are used to cycle selected brick.
  txtWriteCenter(screen, FONTSMALL,STR_EDIT_PREVBRICK_KEY,HSCREENW-142,HSCREENH-80);
  txtWriteCenter(screen, FONTSMALL,STR_EDIT_NEXTBRICK_KEY,HSCREENW-88,HSCREENH-80);


  //Draw the currently selected brick.
  drawBrick(screen, selBrick,HSCREENW-125,HSCREENH-85);

  //Write brick name.
  txtWriteCenter(screen, FONTSMALL, str_brick_names[selBrick], HSCREENW-116,HSCREENH-56 );

  //Tell if we're placing teleport source or destination
  if(selBrick==TELESRC && teleState==0)
  {
    txtWriteCenter(screen, FONTSMALL, "(From)", HSCREENW-115,HSCREENH-41);
  } else if(teleState)
  {
    if(selBrick==TELESRC)
    {
      txtWriteCenter(screen, FONTSMALL, "(To)", HSCREENW-115,HSCREENH-41);
    } else {
      txtWriteCenter(screen, FONTSMALL, "(Target)", HSCREENW-115,HSCREENH-41);
    }
    drawPath(screen, teleSrcPos[0], teleSrcPos[1], cur.x, cur.y, 1);
  }

  //Draw all the telepaths.
  drawAllTelePaths(screen, pf.levelInfo->teleList);


  //Draw switchpath we hover above
  listItem* t = &pf.levelInfo->switchList->begin;
  while( LISTFWD(pf.levelInfo->switchList, t) )
  {
    telePort_t* tp=(telePort_t*)t->data;
    if(cur.x == tp->sx && cur.y == tp->sy)
    {
      drawTelePath( screen, tp, 1 );
    }
  }
  //Draw all switchpaths
  drawAllTelePaths(screen, pf.levelInfo->switchList);

  if( (getInpPointerState()->timeSinceMoved < POINTER_SHOW_TIMEOUT) && (changed > 0) )
  {
    drawSprite(screen, saveBtnSprite, HSCREENW-145, HSCREENH+42 );
  }

  //Draw brick-selection
  if( editorState == EDITOR_BRICKS_SELECTION )
  {
    SDL_BlitSurface(selBrickBG , NULL, screen, &(setting()->bgPos) );

    //Draw bricks in a 6*4 grid
    int px,py,bnum=BRICKSBEGIN;
    static int brickSelOfX = HSCREENW - 78 + 8;
    static int brickSelOfY = HSCREENH - 54 + 8;
    for(py=0;py < 4; py++)
    {
      for(px=0; px < 6; px++)
      {
        if( bnum > NUMTILES )
          break;
        selBrickRect.x = brickSelOfX+(24*px);
        selBrickRect.y = brickSelOfY+(24*py);
        selBrickRect.w = selBrickRect.x+20;
        selBrickRect.h = selBrickRect.y+20;


        //We set bricks on mouseover, this way we get the description too (maybe punch a hole in the dots where the text is?)
        if( isPointerInBox(&selBrickRect) )
        {
          selBrick=bnum;
        }

        //We continue back to the main editor
        if( isPointerClicked() )
        {
          resetMouseBtn();
          editorState=EDITOR_MAIN;
        }

        drawBrick(screen, bnum, selBrickRect.x, selBrickRect.y );
        bnum++;
      }
    }
  }

  return(STATEEDIT);
}