void ttFree(tetris_table* t) { for (uint16_t i = 0; i < t->size.y; ++i) free(t->tab[i]); free(t->tab); if (t->next_block[0]) { blockFree(t->next_block[0]); free(t->next_block[0]); } if (t->next_block[1]) { blockFree(t->next_block[1]); free(t->next_block[1]); } }
void freeLBMallocBlocks(LBMallocBlock_t * block) { while (block != NULL) { LBMallocBlock_t * nextBlock = block->next; blockFree(block->block, block->size); free(block); block = nextBlock; } }
void blockInitWithKind(block* b, block_kind k) { blockInit(b, 4, (block_type)k); if (k >= kind_end) blockFree(b); else { for (uint16_t i = 0; i < 4; ++i) b->pos[i] = blocks[(uint16_t)k][i]; } }
char ttCanTurn(tetris_table* t, char right) { block b; blockInitWithBlock(&b, t->next_block[0]); blockRotate(&b, right); for (uint16_t i = 0; i < blockSize(&b); ++i) { position p = blockPosition(&b, i); p.x += t->currentPos.x; p.y += t->currentPos.y; if (p.x < 0 || p.y >= t->size.y || p.x >= t->size.x || (p.y >= 0 && !t->tab[p.y][p.x].empty)) { blockFree(&b); return 0; } } blockFree(&b); return 1; }
void ttNewNextBlock(tetris_table* t) { if (t->next_block[0]) { blockFree(t->next_block[0]); free(t->next_block[0]); } t->next_block[0] = t->next_block[1]; t->next_block[1] = (block*)malloc(sizeof(block)); assert(t->next_block[1]); blockInitWithKind(t->next_block[1], (block_kind)(rand()%kind_end)); uint16_t times = rand()%4; for (uint16_t i = 0; i < times; ++i) blockRotate(t->next_block[1], 1); }
void PRUloader::pruEvt0_thread(){ // log start time struct timespec time_now; printf("\r\n"); clock_gettime(CLOCK_MONOTONIC_RAW, &time_now); double start_time = time_now.tv_sec + time_now.tv_nsec / 1e9; double dt = 0.0; double time_now_s; float writeBlock = 0; unsigned int writeBlock_u = 0; int unwritten_blocks = 0; unsigned int blocks_free = 0; rx_thread_running = true; while(!quit_rx_thread){ prussdrv_pru_wait_event(PRU_EVTOUT_0); prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT); switch (mode){ case PRU_FILE: if (last_block){ // break out of this loop, data transfer is complete break; } while(blockFree() >= 1){ delta = bufferUpdate(); } // display time from start clock_gettime(CLOCK_MONOTONIC_RAW, &time_now); time_now_s = time_now.tv_sec + time_now.tv_nsec / 1e9; dt = (time_now_s - start_time); printf("%s%4.0f%s%4.0f\r", "Time = ", dt, ", Interval between writes (ms) = ", delta * 1e3); fflush(stdout); break; case PRU_STREAM: // use the block free signal as an interrupt to check whether sufficient data has been loaded // we here because a block is free - no need to check! blocks_free++; // get current write block // determine which block is being written to currently // we end up chasing alsaWritePointer writeBlock = (float)(*alsaWritePointer)/BLOCK_512K; writeBlock_u = floor(writeBlock); writeBlock_u &= 0x3; // is there data that we have not copied to PRU? unwritten_blocks = (int)writeBlock_u - (int)alsaNextReadPointer; //printf("\r\n%10s >> %5u %5d %5.2f\r\n", "while", blocks_free, unwritten_blocks, writeBlock); while (blocks_free && (unwritten_blocks != 0)){ memcpy((char*)ddrMemOrigin + arm_write_pointer*BLOCK_512K, fifoBasePointer + alsaNextReadPointer*BLOCK_512K, BLOCK_512K); blocks_free--; alsaNextReadPointer++; alsaNextReadPointer &= 0x3; // keep track of write pointer arm_write_pointer++; arm_write_pointer &= 0x3; writeBlock = (float)(*alsaWritePointer)/BLOCK_512K; writeBlock_u = floor(writeBlock); writeBlock_u &= 0x3; unwritten_blocks = (int)writeBlock_u - (int)alsaNextReadPointer; // printf("%10s >> %5u %5u %5d %5d\r\n", "pru_stream" ,alsaNextReadPointer, arm_write_pointer, unwritten_blocks, writeBlock_u); } break; case PRU_GEN: break; default: //printf("PRUloader >> Unknown mode\r\n"); break; } } rx_thread_running = false; }