void showItems(list_t* list) { listItem* it=&list->begin; while( LISTFWD(list,it) ) { showItem((item*)it->data); } }
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; }
//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; }
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); }
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; }
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); }
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); }