コード例 #1
0
ファイル: main.c プロジェクト: DusteDdk/Wizznic
void showItems(list_t* list)
{
  listItem* it=&list->begin;
  while( LISTFWD(list,it) )
  {
    showItem((item*)it->data);
  }
}
コード例 #2
0
ファイル: sound.c プロジェクト: DusteDdk/Wizznic
void soundPlayUserSongNum(int num, char* songName)
{
  if(!setting()->musicVol) return;
  listItem* it=&fileList()->begin;
  fileListItem_t* file;
  int i=0;
  while( LISTFWD(fileList(),it) )
  {
    file=(fileListItem_t*)it->data;
    if(!file->dir)
    {
      if(i==num)
      {
        //Unload current song.
        Mix_HaltMusic();
        if(mus[1])
        {
          Mix_FreeMusic(mus[1]);
          mus[1]=0;
        }
        //Load new song
        mus[1]=Mix_LoadMUS( file->fullName );
        if(!mus[1])
        {
          printf("Couldn't load music: '%s'\n",file->fullName);
        }
        else
        {
          printf("Now Playing: '%s'\n",file->fullName);
          if(songName)
          {
            showSNCD=SHOW_SONG_TIME;
            strcpy(songName,file->name);
          }
        }

        Mix_FadeInMusicPos(mus[1], 0, MUSIC_FADETIME,mPos[1]);


        //return; We don't return, instead we let it run, to count number of usertracks.
      }
      i++;
    }
  }
  numUserSongs=i;
}
コード例 #3
0
//Search through packs to find dir, if none found, default to 0.
//This algorithm is a lot slower than doing the while( (it=it->next) ) however
//it is also smaller and only used once.
void packSetByPath(const char* dir)
{
  int i=0;
  listItem* it=&ps.packs->begin;
  while( LISTFWD(ps.packs,it) )
  {
    if( strcmp( ((packInfoType*)it->data)->path,dir ) == 0 )
    {
      packSet(i);
      return;
    }
    i++;
  }

  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "packSetByPath(); Error: Could not find pack with path '%s'\n",dir);

  packSet(0);
  return;
}
コード例 #4
0
int packAdd(const char* packDir, int isDLC)
{
  char* buf = malloc(sizeof(char)*2048);
  char* buf2= malloc(sizeof(char)*1024);
  char* val = malloc(sizeof(char)*1024);
  char* set = malloc(sizeof(char)*1024);

  //This block is for playlists
  list_t* playList=0;
  listItem* li=0;
  playListItem* pli=0;
  int i; //Counter

  FILE* f=0;
  packInfoType* ti = malloc(sizeof(packInfoType));
  ti->lives=3; //Default 3 lives, if pack do not define another number.
  ti->isDLC=isDLC;

  //Any levels? (Packs are invalid without a levels folder and atleast one level)
  sprintf(buf, "%s/levels/level000.wzp", packDir);

  //Initialize list for playlist
  playList = listInit(_freePlaylistItem);

  //Open packs/packname/info.ini
  sprintf(buf, "%s/info.ini", packDir);
  f = android_fopen(buf, "r");
  if(f)
  {
    while( fgets(buf, 128, f) )
    {
      stripNewLine(buf);
      if(splitVals('=',buf,set,val))
      {
        if(strcmp("author", set)==0)
        {
          ti->author = malloc( sizeof(char)*(strlen(val)+1+3) );
          sprintf(ti->author, "By %s", val);
        } else
        if(strcmp("packname", set)==0)
        {
          ti->name = malloc( sizeof(char)*(strlen(val)+1) );
          strcpy(ti->name,val);
        } else
        if(strcmp("comment", set)==0)
        {
          ti->comment = malloc( sizeof(char)*(strlen(val)+1+1) );
          sprintf(ti->comment, "-%s", val);
        } else
        if(strcmp("mus", set)==0)
        {
          //mus=00,song
          if( splitVals(',',val, buf,set ) && splitVals('-',buf,val,buf2) )
          {
              //val= from buf2=to set=song name
              pli = malloc( sizeof( playListItem ) );
              pli->from=atoi(val);
              pli->to=atoi(buf2);
              pli->song=malloc(sizeof(char)*strlen(set)+1);
              strcpy( pli->song, set );
              listAppendData( playList, (void*)pli );
          } else {
            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "   Playlist entry format is mus=XX-XX,song name.ogg where XX-XX is a level range.\n");
          }
        } else
        if(strcmp("lives", set)==0)
        {
          ti->lives = atoi(val);
        }
      } //Found =
    } //reading file

    //Close the info file.
    fclose(f);
  } else {
    //Fall back if no file was found.
    SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Warning: '%s' not found, using defaults.\n",buf);
    ti->author = malloc( sizeof(char)* 20 );
    strcpy(ti->author, "info.ini not found");
    ti->comment=ti->author;
    ti->name = malloc( sizeof(char)*(strlen(packDir)+1) );
    strcpy(ti->name, packDir);
  }


  //Set path
  ti->path = malloc( sizeof(char)*(strlen(packDir)+1) );
  strcpy(ti->path,packDir);

  //Set pack icon
  sprintf(buf, "%s/icon.png", packDir);
  ti->icon = loadImg(buf);
  if(!ti->icon)
  {
    ti->icon = loadImg( "data/noicon.png" );
  }

  //Check if pack have a "finished" icon.
  sprintf(buf, "%s/finished.png", packDir);

  //Set ps.cp before entering makeLevelist, it makes use of packGetFile
  ps.cp = ti;

  //Add levels.
  ti->levels=0;
  ti->levels=makeLevelList(packDir); //makeLevelList looks in packDir/levels/

  //set number of levels in pack
  ti->numLevels = ti->levels->count - 1  ; //The last level does not count (because it is just a "completed" screen).


  //Add to list of packages
  listAppendData( ps.packs, (void*)ti );

  //Increase number of available packages
  ps.numPacks++;

  //Put playlist songs into levelfiles.
  li=&playList->begin;
  while( LISTFWD(playList,li) )
  {
    pli=(playListItem*)li->data;

    for(i=0; i<ti->numLevels;i++)
    {
      if(i >= pli->from && i <= pli->to)
      {
        levelInfo(i)->musicFile = malloc( sizeof(char)*strlen(pli->song)+1 );
        strcpy(levelInfo(i)->musicFile, pli->song);
      }
    }
  }

  //Clear playlist data
  listFree( playList );

  free(buf);
  free(buf2);
  free(val);
  free(set);

  return(ps.numPacks-1);
}
コード例 #5
0
void packInit()
{

  SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "initPack();\n");

  ps.packs = listInit(NULL);
  ps.numPacks=0;

  //Add the wizznic packs
  packAdd("packs/000_wizznic", 0);
  packAdd("packs/001_wizznic", 0);

  list_t* packDirList = listInit(NULL);
  list_t* usrPackDirList = listInit(NULL);

  //packScanDir("packs", packDirList);
  packScanDir( getUsrPackDir(), usrPackDirList);

  if(packDirList->count < 1)
  {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "packInit(); Error: No packs found.\n");
  }

  //Add pack directories to list of strings to be sorted
  char** sortme = malloc( sizeof(char**) * packDirList->count );
  int i=0;
  listItem* it = &packDirList->begin;
  while( LISTFWD(packDirList,it) )
  {
    sortme[i]=(char*)it->data;
    i++;
  }

  //Sort the array
  qsort( sortme, packDirList->count, sizeof(char*), strCmp );

  //Loop through array, add pack, free string
  for(i=0; i<packDirList->count; i++)
  {
    //add pack
    packAdd( sortme[i], PACK_IS_NOT_DLC );
    //free string
    free( sortme[i] );
  }

  //Append the unsorted list of DLC packs.
  it=&usrPackDirList->begin;
  while( LISTFWD(usrPackDirList,it) )
  {
    packAdd( (char*)it->data, PACK_IS_DLC );
  }

  //Free sortme array
  free(sortme);

  //Free packDirList
  //FIXME: Check if the data or pointers are copied, maybe we could free ?
  listFree( packDirList );

  SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "initPack(); Added %i packs.\n", ps.packs->count);

  //Do not call packSet here, it will be called after setting's are read.

  //Set the packbox graphics ptr 0 before loading it.
  ps.packBoxImg=0;
}
コード例 #6
0
ファイル: leveleditor.c プロジェクト: revcozmo/Wizznic
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);
}
コード例 #7
0
ファイル: main.c プロジェクト: DusteDdk/Wizznic
int main()
{
  int i;
  printf("Test: New list.\n");
  list_t* list = listInit(freeItem);
  listDebugShow(list,LIST_DEBUG_SHOW_BACKWARD|LIST_DEBUG_SHOW_FORWARD);
  listItem* it;

  printf("\nTest: Appending 4 items to list.\n");
  listAppendData(list, mkItem(1, "Fisk") );
  listAppendData(list, mkItem(2, "Hund") );
  it=listAppendData(list, mkItem(3, "Hest") );
  listAppendData(list, mkItem(4, "Rose") );
  listDebugShow(list,LIST_DEBUG_SHOW_SHORT);
  showItems(list);


  printf("\nTest: Prepending 4 items.\n");
  listPrependData(list, mkItem(5, "Laks") );
  listPrependData(list, mkItem(6, "Ko") );
  listPrependData(list, mkItem(7, "Tiger") );
  listPrependData(list, mkItem(8, "Zebra") );
  listDebugShow(list,LIST_DEBUG_SHOW_SHORT);
  showItems(list);


  printf("\nTest: Removing item (Hest) from list.\n");
  listRemoveItem(list,it, LIST_PREV);
  listDebugShow(list,LIST_DEBUG_SHOW_SHORT);
  showItems(list);


  printf("\nTest: Inserting 4 items\n");
  listInsertAtIdx(list, mkItem(1, "New Pos 0"), 0 );
  it=listInsertAtIdx(list, mkItem(1, "New Pos 2"), 2 );
  listInsertAtIdx(list, mkItem(1, "New Pos 8"), 8 );
  listInsertAtIdx(list, mkItem(list->count, "New Last Pos"), list->count );
  listDebugShow(list,LIST_DEBUG_SHOW_SHORT);
  showItems(list);


  printf("\nTest: Insert after item %p (New Pos 2)\n");
  listInsertAfterItem(list, it, mkItem(2, "New Pos 3") );
  listDebugShow(list,LIST_DEBUG_SHOW_SHORT);
  showItems(list);



  printf("\nTest: Getting data.\n");
  for(i=0; i < list->count; i++)
  {
    printf("  Idx %i Got data: %p\n", i, listGetItemAt(list, i )->data );
  }

  printf("\nTest: Filling list into array.\n");
  item** arr = (item**)listAddToArray( malloc(sizeof(void*)*list->count), list );

  int idx;
  for(idx=0; idx < list->count; idx++)
  {
    printf("  Arr[%i] = %p\n",idx,arr[idx] );
    showItem(arr[idx]);
  }

  printf("\nTest: Appending array to list2.\n");
  list_t* list2 = listAddFromArray(listInit(NULL), (void*)arr, list->count);
  listDebugShow(list2,LIST_DEBUG_SHOW_SHORT);
  showItems(list2);

  list_t* list3 = listAddFromArray(listInit(NULL), (void*)arr, list->count);

  free(arr);

  printf("\nRemoving all list2 elements individually in a forward loop.");
  it=&list2->begin;
  while( LISTFWD(list2,it) )
  {
    it=listRemoveItem(list2,it, LIST_PREV);
  }
  listDebugShow(list2, LIST_DEBUG_SHOW_BACKWARD|LIST_DEBUG_SHOW_FORWARD);

  printf("\nRemoving all list3 elements individually in a reverse loop.");
  it=&list3->end;
  while( LISTBCK(list3, it) )
  {
    it=listRemoveItem(list3,it,LIST_NEXT);
  }
  listDebugShow(list3, LIST_DEBUG_SHOW_BACKWARD|LIST_DEBUG_SHOW_FORWARD);



  printf("\nTest: Freeing lists.\n");
  listFree(list);
  listFree(list2);

  printf("\nTests done, it's up to you to figure out if they passed, <nelson>hahaaa!</nelson>\n");

  return(0);
}