/* * place - Place block of asize bytes at start of free block bp * and split if remainder would be at least minimum block size */ static void place(block_ptr bp, size_t asize) { size_t csize = GET_SIZE(HDRP(bp)), delta = csize - asize; if (delta >= (2 * DSIZE)) { PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); SET_ALLOC(bp); bp = NEXT_BLKP(bp); PUT(HDRP(bp), PACK(delta, 0)); PUT(FTRP(bp), PACK(delta, 0)); SET_UNALLOC(bp); reset_block(bp); insert_free_block(bp, delta); #ifdef DEBUG { printf("Block with size %zu remains a block:\n", asize); printblock(bp); } #endif } else { PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); SET_ALLOC(bp); } }
/* Initialize block struct */ void init_block(struct datablock_stats *d, struct vegas_databuf *db, size_t heap_size, size_t spead_hdr_size, int heaps_per_block) { d->db = db; d->heap_size = heap_size; d->spead_hdr_size = spead_hdr_size; d->heaps_per_block = heaps_per_block; reset_block(d); }
/* * randomizes block and sets the initial positions of the pieces */ static void randomize_block(struct blocks *block) { /* Create a new bag if necessary, then pull the next piece from it */ if (bag_is_empty()) bag_random_generator(); block->type = bag_next_piece(); reset_block(block); }
void change() { enum ALLOW_TYPE is_allow; enum POSITION next_pos = (block_entry_p->pos+1)%4; is_allow = verify(block_entry_p->type, next_pos,ROW_CANVAS); if(is_allow == ALLOW){ reset_block(); block_entry_p->pos = next_pos; draw_picture(ROW_CANVAS, BLUE, IS_DRAW); } }
/* * coalesce - Boundary tag coalescing. Return ptr to coalesced block */ static block_ptr coalesce(block_ptr bp) { /* * TODO Here is the bug: Do update the bins while doing this. * Tried to fix. Not sure what will happen. */ block_ptr prev, next = NEXT_BLKP(bp); /* Use GET_PREV_ALLOC to judge if prev block is allocated */ size_t prev_alloc = GET_PREV_ALLOC(bp); size_t next_alloc = GET_ALLOC(HDRP(next)); size_t size = GET_SIZE(HDRP(bp)); if (prev_alloc && next_alloc) /* Case 1 */ { return bp; } else if (prev_alloc && !next_alloc) /* Case 2 */ { remove_freed_block(next); size += GET_SIZE(HDRP(next)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } else if (!prev_alloc && next_alloc) /* Case 3 */ { prev = PREV_BLKP(bp); remove_freed_block(prev); size += GET_SIZE(HDRP(prev)); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(prev), PACK(size, 0)); bp = prev; } else /* Case 4 */ { prev = PREV_BLKP(bp); remove_freed_block(next); remove_freed_block(prev); size += GET_SIZE(HDRP(prev)) + GET_SIZE(FTRP(next)); PUT(HDRP(prev), PACK(size, 0)); PUT(FTRP(next), PACK(size, 0)); bp = prev; } reset_block(bp); // insert_free_block(bp, size); return bp; }
/* * free */ void free(block_ptr ptr) { block_ptr tmp; size_t size; if (!ptr || !in_heap(ptr) || !aligned(ptr)) return; #ifdef DEBUG { printf("\nFree request: ptr = %p \033[41;37m[ID:%d]\033[0m\n", ptr, operid++); printblock(ptr); } #endif size = GET_SIZE(HDRP(ptr)); PUT(HDRP(ptr), PACK(size, 0)); PUT(FTRP(ptr), PACK(size, 0)); SET_UNALLOC(ptr); reset_block(ptr); tmp = coalesce(ptr); insert_free_block(tmp, GET_SIZE(HDRP(tmp))); }
/* * extend_heap - Extend heap with free block and return its block pointer */ static block_ptr extend_heap(size_t words) { char *bp; size_t size; /* Allocate an even number of words to maintain alignment */ size = (words % 2) ? (words + 1) * WSIZE : words * WSIZE; if ((long)(bp = mem_sbrk(size)) == -1) return NULL; #ifdef DEBUG printf("\nExtended the heap by %zu words.\n", words); #endif /* Initialize free block header/footer and the epilogue header */ PUT(HDRP(bp), PACK(size, 0)); /* Free block header */ PUT(FTRP(bp), PACK(size, 0)); /* Free block footer */ reset_block(bp); PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ /* Coalesce if the previous block was free */ return coalesce(bp); }
/* * User input. Hopefully self explanatory. * * Input keys are currently: * F1 pause * F3 quit * * wasdqe * - w hard drops a piece to the bottom. * - a/d move left/right respectively. * - s soft drops one row. * - qe rotate counter clockwise/clockwise repectively. * * - space is used to hold the currently falling block. */ void *blocks_input(void *vp) { (void) vp; /* unused */ int ch; if (!CURRENT_BLOCK()) return NULL; while ((ch = getch())) { /* prevent modification of the game from blocks_loop in the * other thread */ pthread_mutex_lock(&pgame->lock); switch (ch) { case KEY_F(1): pgame->pause = !pgame->pause; goto draw_game; case KEY_F(3): pgame->pause = false; pgame->quit = true; goto draw_game; } /* remove the current piece from the board */ unwrite_cur_block(); /* modify it */ switch (toupper(ch)) { case 'A': translate_block(CURRENT_BLOCK(), MOVE_LEFT); break; case 'D': translate_block(CURRENT_BLOCK(), MOVE_RIGHT); break; case 'S': if (drop_block(CURRENT_BLOCK())) CURRENT_BLOCK()->soft_drop++; else CURRENT_BLOCK()->lock_delay = 1E9 -1; break; case 'W': /* drop the block to the bottom of the game */ while (drop_block(CURRENT_BLOCK())) CURRENT_BLOCK()->hard_drop++; /* XXX */ CURRENT_BLOCK()->lock_delay = 1E9 -1; break; case 'Q': if (!rotate_block(CURRENT_BLOCK(), ROT_LEFT)) { try_wall_kick(CURRENT_BLOCK(), ROT_LEFT); } break; case 'E': if (!rotate_block(CURRENT_BLOCK(), ROT_RIGHT)) { try_wall_kick(CURRENT_BLOCK(), ROT_RIGHT); } break; case ' ': { struct blocks *tmp; /* We can hold each block exactly once */ if (CURRENT_BLOCK()->hold == true) break; tmp = CURRENT_BLOCK(); /* Effectively swap the first and second elements in * the linked list. The "Current Block" is element 2. * And the "Hold Block" is element 1. So we remove the * current block and reinstall it at the head, pushing * the hold block to the current position. */ LIST_REMOVE(tmp, entries); LIST_INSERT_HEAD(&pgame->blocks_head, tmp, entries); reset_block(HOLD_BLOCK()); HOLD_BLOCK()->hold = true; break; } } /* then rewrite it */ write_cur_block(); draw_game: screen_draw_game(); pthread_mutex_unlock(&pgame->lock); } return NULL; }