static void qtree_destroy (QTree *root) { if (!root) return; if (root->image) { cairo_surface_destroy (root->image); root->image = NULL; } qtree_destroy (root->l0); qtree_destroy (root->l1); qtree_destroy (root->l2); qtree_destroy (root->l3); g_slice_free (QTree, root); }
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); }