/*
 * wnix, a Unix-like operating system for WebAssembly applications.
 * Copyright (C) 2025  Xavier Del Campo Romero
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef GFX_PS1_H
#define GFX_PS1_H

#include <stdint.h>

union gfx_common
{
    struct
    {
        uint32_t tpagex :4, tpagey :1, stp :2, bpp :2, dither :1,
            draw_to_disp :1, disable :1, xflip :1, yflip :1, :10;
        uint8_t cmd;
    } f;

    uint32_t mask;
};

union gfx_sznext
{
    struct
    {
        uint32_t next :24, sz :8;
    } f;

    uint32_t cmd_next;
};

struct gfx_sprite
{
    union gfx_sznext sznext;
    union gfx_common common;
    uint8_t r, g, b;
    uint8_t cmd;
    int16_t x, y;
    uint8_t u, v;
    uint16_t clutid;
    uint16_t w, h;
};

struct quad
{
    union gfx_sznext sznext;
    uint8_t r, g, b;
    uint8_t cmd;
    int16_t x0, y0;
    uint8_t u0, v0;
    uint16_t clutid;
    int16_t x1, y1;
    uint8_t u1, v1;

    union
    {
        struct
        {
            /* 0-8 Same as GP0(E1h).Bit0-8. */
            uint16_t lb :9;
            uint16_t :2;
            /* 11 Same as GP0(E1h).Bit11. */
            uint16_t hb :1;
            uint16_t :4;
        } bit;

        uint16_t mask;
    } tpage;

    int16_t x2, y2;
    uint8_t u2, v2;
    uint16_t :16;
    int16_t x3, y3;
    uint8_t u3, v3;
    uint16_t :16;
};

struct gfx_rect
{
    union gfx_sznext sznext;
    union gfx_common common;
    uint8_t r, g, b;
    uint8_t cmd;
    int16_t x, y;
    uint16_t w, h;
};

struct stp_4line
{
    union gfx_sznext sznext;
    union gfx_common common;
    uint8_t r, g, b;
    uint8_t cmd;
    int16_t x, y;

    struct stp_4line_vtx
    {
        uint32_t r :8, g :8, b :8, :8;
        int16_t x, y;
    } vertices[4];

    uint32_t end;
};

void gfx_add_to_list(union gfx_sznext *p);
void *gfx_heap_top(void);
struct gfx_sprite *gfx_sprite_get(void);
struct quad *quad_get(void);
struct gfx_rect *gfx_rect_get(void);
struct stp_4line *stp_4line_get(void);

#endif
