// Assume position starts from 1 NOT 0 bool list_insert( unsigned int position, itemType value, List L ) { //*** Runs in O(n) int length = list_length ( L ); // number of items in the list if (position >= length + 1 || length == -1) // insert value to end of list because position is greater than size of the list or empty list { return list_insertBack (value, L); } else if (position == 1) // insert value in the front of the list { return list_insertFront (value, L); // call existing function } else // insert in between the list { int i; nodeType *newNode = (nodeType*) malloc (sizeof(nodeType)); if (newNode == NULL) { return false;//dynamic storage exhausted } else { newNode -> data = value; float length_f = length; // avoid integer division to calculate the ratio of position with respect to length of the list nodeType *temp; if ((position / length_f) <= 0.5) // if the ratio of position / length is less or equal to 0.5 than it is closer to start at the head { temp = L -> head; // save the position of the head for (i = 1; i < position - 1; i++)// go down the list to the point before insertion { L -> head = L -> head -> next; } newNode -> previous = L -> head; // newNode -> next = L -> head -> next; L -> head -> next = newNode; L -> head -> next -> previous = newNode; L -> head = temp; // return the head to the original position } else // start at tail because it is closer (more efficent for larger lists) { temp = L -> tail; // preserve the position of tail for (i = length; i > position; i--)// go up the list to the point after insertion { L -> tail = L -> tail -> previous; } newNode -> next = L -> tail; // newNode -> previous = L -> tail -> previous; L -> tail -> previous -> next = newNode; L -> tail -> previous = newNode; L -> tail = temp; // return the tail to the original position } L -> size += 1; return true; } } }
void core_run() { srand(time(NULL)); bool quit = false; SDL_Event e; timer fpsTimer; timer capTimer; int countedFrames = 0; timer_start(&fpsTimer); // Um pequeno hack para carregar uma textura otimizada do SDL // escondendo toda a implementaĆ§Ć£o do header de entidade. SDL_Surface *ballTexture = IMG_Load("circle.png"); if (SDL_GetWindowSurface(gCore.window) == NULL) { printf("[Error] Window Surface is NULL: %s\n", SDL_GetError()); exit(0); } SDL_Surface *optimizedTexture = SDL_ConvertSurface(ballTexture, SDL_GetWindowSurface(gCore.window)->format, 0); SDL_FreeSurface(ballTexture); // Popula a lista inicial de objetos com a textura. node *cur = gCore.entities->head; while (cur != NULL) { cur->b->texture = optimizedTexture; cur = cur->next; } int nIterations = 0; while (!quit) { int startTicks = timer_getTicks(&capTimer); timer_start(&capTimer); gCore.tree = qtree_create(gCore.width, gCore.height, gCore.maxDepth, gCore.maxObjectsPerNode); node *prevEntities = gCore.entities->head; while (prevEntities != NULL) { qtree_insert(gCore.tree, gCore.tree->root, prevEntities->b); prevEntities = prevEntities->next; } while (SDL_PollEvent(&e) != 0) { switch (e.type) { case SDL_QUIT: quit = true; break; case SDL_MOUSEBUTTONDOWN: { printf("[Warn] Spawning ball.\n"); int mX, mY; SDL_GetMouseState(&mX, &mY); ball *b = entity_createBall(0, mX - optimizedTexture->w / 2, mY - optimizedTexture->h / 2, (2 * (rand() % MAX_ABS_SPEED) - MAX_ABS_SPEED) / SCREEN_FPS, (2 * (rand() % MAX_ABS_SPEED) - MAX_ABS_SPEED) / SCREEN_FPS, optimizedTexture->w / 2); b->texture = optimizedTexture; list_insertBack(gCore.entities, b); qtree_insert(gCore.tree, gCore.tree->root, b); break; } } } float avgFPS = countedFrames / ( timer_getTicks(&fpsTimer) / 1000.f ); if(avgFPS > 2000000 ) { avgFPS = 0; } if (gCore.maxIterations == -1 || nIterations < gCore.maxIterations) { core_update(startTicks); } nIterations++; SDL_SetRenderDrawColor(gCore.renderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderClear(gCore.renderer); core_render(); SDL_RenderPresent(gCore.renderer); ++countedFrames; int frameTicks = timer_getTicks(&capTimer); if (frameTicks < SCREEN_TICK_PER_FRAME) { SDL_Delay(SCREEN_TICK_PER_FRAME - frameTicks); } qtree_destroy(gCore.tree); } SDL_FreeSurface(optimizedTexture); }