void dungeon2_cave_draw_map(u8 *map, int type, dungeon_generator2 *dg2) { // Initialize a queue for all walls that might be problematic ring_queue_t queue; ring_queue_new(&queue, (size_t)(dg2->width * dg2->height)); // First iterate over the entire map and find "problematic walls" for (int x = 0; x < dg2->width; x++) { for (int y = 0; y < dg2->height; y++) { if (x == 0 || x == dg2->width - 1 || y == 0 || y == dg2->height - 1) { // The border is ensured to be untouched block_set_by_pos((s16)(x + 7), (s16)(y + 7), 0x291 | BLOCK_SOLID); continue; } // Count wall neighbours in the cross neighbourhood if (map[y * dg2->width + x] == DG2_WALL ) { if(dungeon2_cave_wall_can_be_drawn(map, x, y, dg2)) { // Draw this wall right now dungeon2_cave_set_wall(x, y, map, type, dg2); } else { // Enqueue this wall as it can not be drawn ring_queue_enqueue(&queue, COORDINATE_PACK(x, y)); } } else if (type == WALL_SET_GROUND){ // Set ground block if we are at ground level dungeon2_cave_set_ground(x, y, dg2); } } } // Fix the walls that were enqueued while (!ring_queue_empty(&queue)) { int head = ring_queue_pop(&queue); int x = COORDINATE_UNPACK_X(head), y = COORDINATE_UNPACK_Y(head); //dprintf("Fixing (%d, %d)\n", x, y); // Set this to a rock dungeon2_cave_set_rock(x, y, type, dg2); map[y * dg2->width + x] = DG2_ROCK; // Enqueue adjacent wall tiles, we changed their adjacenent wall count for (int dx = -1; dx < 2; dx++) { for (int dy = -1; dy < 2; dy++) { if (dx == 0 && dy == 0) continue; int x2 = dx + x, y2 = dy + y; if (x2 > 0 && x2 < dg2->width - 1 && y2 > 0 && y2 < dg2->height - 1 && map[y2 * dg2->width + x2] == DG2_WALL) { if (dungeon2_cave_wall_can_be_drawn(map, x2, y2, dg2)) { // Simply redraw the wall dungeon2_cave_set_wall(x2, y2, map, type, dg2); } else { // Fix this tile as well ring_queue_enqueue(&queue, COORDINATE_PACK(x2, y2)); } } } } } ring_queue_del(&queue); }
static bool test_SPSC_add_and_remove_elem(void) { struct ring_queue *queue; int on_stack = 123; int *obj = &on_stack; int *deq_obj = NULL; queue = ring_queue_create(128, RING_F_SP_ENQ|RING_F_SC_DEQ); if (queue == NULL) return false; /* enqueue */ if (ring_queue_enqueue(queue, obj) < 0) goto fail; /* count */ if (ring_queue_count(queue) != 1) goto fail; /* dequeue */ if (ring_queue_dequeue(queue, (void **)&deq_obj) < 0) goto fail; /* compare pointer values from enq and deq */ if (verbose) pr_info("%s(): ptr deq_obj:0x%p obj:0x%p &on_stack:0x%p\n", __func__, deq_obj, obj, &on_stack); if (obj != deq_obj) goto fail; /* compare int values stored (by ptr) from enq and deq */ if (verbose) pr_info("%s(): int deq_obj:%d obj:%d on_stack:%d\n", __func__, *deq_obj, *obj, on_stack); if (*deq_obj != *obj) goto fail; /* empty */ if (!ring_queue_empty(queue)) goto fail; return ring_queue_free(queue); fail: ring_queue_free(queue); return false; }