/* free_block -- free a block, merging it with its neighbours */ static header *free_block(header *h, bool mapped) { /* Mapped is true if this memory is being recycled: it's already in the page table, but we'll need to zero it. */ header *prev = left_neighbour(h), *next = right_neighbour(h); /* Base and size of area where page table needs updating */ uchar *pg_memory = h->h_memory; unsigned pg_size = (mapped ? 0 : h->h_size); #ifdef TRACE if (debug['l']) { printf("Freeing block at %p, size %#x\n", h->h_memory, h->h_size); if (prev == NULL) printf("prev=null, "); else printf("prev=%p, ", prev->h_memory); if (next == NULL) printf("next=null\n"); else printf("next=%p\n", next->h_memory); } #endif if (mapped) memset(h->h_memory, 0, h->h_size); if (prev != NULL && prev->h_objsize == 0) { DEBUG_PRINT('l', ("Merging with prev\n")); unlink(prev); prev->h_size += h->h_size; pg_memory = h->h_memory; pg_size = h->h_size; free_header(h); h = prev; } if (next != NULL && next->h_objsize == 0) { DEBUG_PRINT('l', ("Merging with next\n")); unlink(next); next->h_memory = h->h_memory; next->h_size += h->h_size; pg_memory = h->h_memory; pg_size = h->h_size; free_header(h); h = next; } if (pg_size > 0) page_setup(pg_memory, pg_size, h); make_free(h); /* Return the merged block */ return h; }
bool LOSfinder::bresen_y(PosPoint source, PosPoint target) { int x = source.posx; int error = 0; int delta_y = std::abs(source.posy - target.posy); int deltaerr = std::abs(source.posx - target.posx); int deltastep = sign(target.posx - source.posx); int incrstep = sign(target.posy - source.posy); for (int y = source.posy; y != target.posy; y += incrstep) { if ((x % RAY_MULTIPLIER) == 0 && (y % RAY_MULTIPLIER) == 0) { // when in corner check side neighbours // if both of them are not transparent then corner is not transparent PosPoint left_neighbour(x + deltastep, y, source.posz); PosPoint right_neighbour(x, y + incrstep, source.posz); if (!is_transparent(left_neighbour) && !is_transparent(right_neighbour)) { return false; } } else if (x % RAY_MULTIPLIER == 0) { // when ray hits an edge check both tiles. Since ray travels through edge both of them // must be transparent PosPoint left_neighbour(x - deltastep, y, source.posz); PosPoint right_neighbour(x + deltastep, y, source.posz); if (!is_transparent(left_neighbour) || !is_transparent(right_neighbour)) { return false; } } else if (y % RAY_MULTIPLIER == 0) { // second case of edge handling PosPoint left_neighbour(x, y - incrstep, source.posz); PosPoint right_neighbour(x, y + incrstep, source.posz); if (!is_transparent(left_neighbour) || !is_transparent(right_neighbour)) { return false; } } else { PosPoint new_point(x, y, source.posz); if (!is_transparent(new_point)) { return false; } } error += deltaerr; if (error >= delta_y) { x += deltastep; error -= delta_y; } } return true; }