static UBytePtr update_palette() {
        char[] mo_map = new char[16];
        char[] pf_map = new char[16];
        int i, j;

        /* reset color tracking */
        memset(mo_map, 0, sizeof(mo_map));
        memset(pf_map, 0, sizeof(pf_map));
        palette_init_used_colors();

        /* update color usage for the playfield */
        atarigen_pf_process(pf_color_callback, pf_map, Machine.drv.visible_area);

        /* update color usage for the mo's */
        /*TODO*///        atarigen_mo_process(mo_color_callback, mo_map);

        /* rebuild the playfield palette */
        for (i = 0; i < 16; i++) {
            char used = pf_map[i];
            if (used != 0) {
                for (j = 0; j < 16; j++) {
                    if ((used & (1 << j)) != 0) {
                        palette_used_colors.write(0x100 + i * 16 + j, PALETTE_COLOR_USED);
                    }
                }
            }
        }

        /* rebuild the motion object palette */
        for (i = 0; i < 16; i++) {
            char used = mo_map[i];
            if (used != 0) {
                palette_used_colors.write(0x000 + i * 16 + 0, PALETTE_COLOR_TRANSPARENT);
                for (j = 1; j < 16; j++) {
                    if ((used & (1 << j)) != 0) {
                        palette_used_colors.write(0x000 + i * 16 + j, PALETTE_COLOR_USED);
                    }
                }
            }
        }

        /* special case color 15 of motion object palette 15 */
        palette_used_colors.write(0x000 + 15 * 16 + 15, PALETTE_COLOR_TRANSPARENT);

        return palette_recalc();
    }