diff --git a/paint/assets/plugins/dev/blocks.c b/paint/assets/plugins/dev/blocks.c new file mode 100644 index 00000000..f3ee0f5b --- /dev/null +++ b/paint/assets/plugins/dev/blocks.c @@ -0,0 +1,222 @@ + +int COLS = 10; +int ROWS = 20; +int cur_type; +int cur_rot; +int cur_x; +int cur_y; +float fall_timer; +float fall_speed; +float cell_size; +float block_scale; +slot_material_t *block_mat; +i32_array_t *board; +i32_array_t *masks; +any_array_t *cells; +any_array_t *active; + +float type_hue(int type) { + return type * 0.142857; +} + +void setup_colors() { + block_mat = script_material_create("blocks"); + ui_node_t *info = script_material_create_node_at("OBJECT_INFO", -600.0, 0.0); + ui_node_t *hsv = script_material_create_node_at("HUE_SAT", -300.0, 0.0); + ui_node_t *out = script_material_get_node("OUTPUT_MATERIAL_PBR"); + script_material_set_color(hsv, 1, 4, 1.0, 0.0, 0.0, 1.0); + script_material_connect(info, 3, hsv, 0); + script_material_connect(hsv, 0, out, 0); + script_material_update(); +} + +int mask_get(int type, int rot) { + return masks->buffer[type * 4 + rot]; +} + +bool piece_fits(int type, int rot, int px, int py) { + int m = mask_get(type, rot); + for (int i = 0; i < 16; ++i) { + if ((m & (32768 >> i)) == 0) continue; + int cx = px + (i % 4); + int cy = py + (i / 4); + if (cx < 0 || cx > COLS - 1 || cy > ROWS - 1) return false; + if (cy < 0) continue; + if (board->buffer[cy * COLS + cx] != 0) return false; + } + return true; +} + +void board_clear() { + for (int i = 0; i < ROWS * COLS; ++i) board->buffer[i] = 0; +} + +void spawn_piece() { + cur_type = iron_random_get_max(6); + cur_rot = 0; + cur_x = 3; + cur_y = 0; + if (!piece_fits(cur_type, cur_rot, cur_x, cur_y)) board_clear(); +} + +void clear_lines() { + int y = ROWS - 1; + while (y > -1) { + int full = 1; + for (int x = 0; x < COLS; ++x) { + if (board->buffer[y * COLS + x] == 0) full = 0; + } + if (full == 0) { + y = y - 1; + } + else { + for (int yy = y; yy > 0; --yy) { + for (int x = 0; x < COLS; ++x) { + board->buffer[yy * COLS + x] = board->buffer[(yy - 1) * COLS + x]; + } + } + for (int x = 0; x < COLS; ++x) board->buffer[x] = 0; + } + } +} + +void lock_piece() { + int m = mask_get(cur_type, cur_rot); + for (int i = 0; i < 16; ++i) { + if ((m & (32768 >> i)) == 0) continue; + int cy = cur_y + (i / 4); + if (cy < 0) continue; + board->buffer[cy * COLS + cur_x + (i % 4)] = cur_type + 1; + } + clear_lines(); + spawn_piece(); +} + +void set_block(object_t *o, int cx, int cy, int visible) { + transform_t *t = o->transform; + o->visible = visible; + t->loc.x = (cx - COLS * 0.5) * cell_size; + t->loc.y = 0.0; + t->loc.z = (ROWS * 0.5 - cy) * cell_size; + t->loc.w = 1.0; + t->rot.x = 0.0; + t->rot.y = 0.0; + t->rot.z = 0.0; + t->rot.w = 1.0; + t->scale.x = block_scale; + t->scale.y = block_scale; + t->scale.z = block_scale; + t->scale.w = 1.0; + t->scale_world = 1.0; + transform_build_matrix(t); +} + +void refresh() { + for (int i = 0; i < ROWS * COLS; ++i) { + object_t *o = cells->buffer[i]; + int v = board->buffer[i]; + o->visible = v != 0; + if (v != 0) o->urandom = type_hue(v - 1); + } + + int m = mask_get(cur_type, cur_rot); + int n = 0; + for (int j = 0; j < 16; ++j) { + if ((m & (32768 >> j)) == 0) continue; + object_t *a = active->buffer[n]; + a->urandom = type_hue(cur_type); + set_block(a, cur_x + (j % 4), cur_y + (j / 4), 1); + n = n + 1; + } +} + +void try_move(int dx) { + if (piece_fits(cur_type, cur_rot, cur_x + dx, cur_y)) cur_x = cur_x + dx; +} + +bool rotate_to(int rot, int x) { + if (!piece_fits(cur_type, rot, x, cur_y)) return false; + cur_rot = rot; + cur_x = x; + return true; +} + +void try_rotate() { + int r = (cur_rot + 1) % 4; + if (rotate_to(r, cur_x)) return; + if (rotate_to(r, cur_x - 1)) return; + rotate_to(r, cur_x + 1); +} + +void step_down() { + if (piece_fits(cur_type, cur_rot, cur_x, cur_y + 1)) cur_y = cur_y + 1; + else lock_piece(); +} + +void update() { + if (keyboard_started("left")) try_move(-1); + if (keyboard_started("right")) try_move(1); + if (keyboard_started("up")) try_rotate(); + if (keyboard_started("space")) { + while (piece_fits(cur_type, cur_rot, cur_x, cur_y + 1)) cur_y = cur_y + 1; + lock_piece(); + } + + float speed = fall_speed; + if (keyboard_down("down")) speed = 0.05; + fall_timer = fall_timer + sys_delta(); + if (fall_timer > speed) { + fall_timer = 0.0; + step_down(); + } + refresh(); +} + +void main() { + cell_size = 0.25; + block_scale = 0.11; + fall_speed = 0.5; + fall_timer = 0.0; + + board = i32_array_create(ROWS * COLS); + board_clear(); + + masks = i32_array_create(28); + masks->buffer[0] = 0x0F00; masks->buffer[1] = 0x2222; masks->buffer[2] = 0x00F0; masks->buffer[3] = 0x4444; + masks->buffer[4] = 0x8E00; masks->buffer[5] = 0x6440; masks->buffer[6] = 0x0E20; masks->buffer[7] = 0x44C0; + masks->buffer[8] = 0x2E00; masks->buffer[9] = 0x4460; masks->buffer[10] = 0x0E80; masks->buffer[11] = 0xC440; + masks->buffer[12] = 0x6600; masks->buffer[13] = 0x6600; masks->buffer[14] = 0x6600; masks->buffer[15] = 0x6600; + masks->buffer[16] = 0x6C00; masks->buffer[17] = 0x4620; masks->buffer[18] = 0x06C0; masks->buffer[19] = 0x8C40; + masks->buffer[20] = 0x4E00; masks->buffer[21] = 0x4640; masks->buffer[22] = 0x0E40; masks->buffer[23] = 0x4C40; + masks->buffer[24] = 0xC600; masks->buffer[25] = 0x2640; masks->buffer[26] = 0x0C60; masks->buffer[27] = 0x4C80; + + setup_colors(); + + object_t *proto = script_shape_add("box"); + mesh_object_t *proto_mo = proto->ext; + mesh_data_t *shared_data = proto_mo->data; + material_data_t *shared_mat = proto_mo->material; + + cells = any_array_create(ROWS * COLS); + for (int i = 0; i < ROWS * COLS; ++i) { + object_t *o = proto; + if (i > 0) { + mesh_object_t *mo = scene_add_mesh_object(shared_data, shared_mat, NULL); + o = mo->base; + } + cells->buffer[i] = o; + script_object_set_material(o, block_mat); + set_block(o, i % COLS, i / COLS, 0); + } + + active = any_array_create(4); + for (int j = 0; j < 4; ++j) { + mesh_object_t *mo = scene_add_mesh_object(shared_data, shared_mat, NULL); + active->buffer[j] = mo->base; + script_object_set_material(mo->base, block_mat); + set_block(mo->base, 0, 0, 0); + } + spawn_piece(); + refresh(); + script_notify_on_update(update); +} diff --git a/paint/assets/plugins/game_pca.c b/paint/assets/plugins/dev/game_pca.c similarity index 100% rename from paint/assets/plugins/game_pca.c rename to paint/assets/plugins/dev/game_pca.c