//====================================================================
// textured_terrain.v - 纹理地形渲染器
// 第27课：高度图与地形纹理
//====================================================================
module textured_terrain #(
    parameter COORD_WIDTH = 16,
    parameter COLOR_WIDTH = 24,
    parameter GRID_SIZE   = 64,
    parameter FRAC_BITS  = 12,
    parameter FB_WIDTH   = 640,
    parameter FB_HEIGHT  = 480
)(
    input  wire                          clk, rst_n,
    input  wire                          frame_start,
    input  wire signed [COORD_WIDTH-1:0] cam_x, cam_y, cam_z,
    output reg                           frame_done,
    output reg                           fb_wen,
    output reg  [COORD_WIDTH-1:0]        fb_x, fb_y,
    output reg  [COLOR_WIDTH-1:0]        fb_color,
    // 高度图接口
    output reg  [11:0]                   hmap_addr,
    input  wire [7:0]                    hmap_data,
    output reg                           hmap_read,
    input  wire                          hmap_valid,
    // 纹理接口
    output reg  [13:0]                   tex_addr,
    input  wire [COLOR_WIDTH-1:0]        tex_data,
    output reg                           tex_read,
    input  wire                          tex_valid
);
/* verilator lint_off WIDTHEXPAND */
/* verilator lint_off WIDTHTRUNC */
/* verilator lint_off CASEOVERLAP */
/* verilator lint_off CMPCONST */
/* verilator lint_off UNSIGNED */
/* verilator lint_off WIDTHCONCAT */

    reg [5:0] grid_x, grid_z;
    reg signed [COORD_WIDTH-1:0] h00, h10, h01, h11;
    reg signed [COORD_WIDTH-1:0] v0x, v0y, v0z, v1x, v1y, v1z, v2x, v2y, v2z;
    function signed [COORD_WIDTH-1:0] qmul;
        input signed [COORD_WIDTH-1:0] a, b;
        reg signed [2*COORD_WIDTH-1:0] prod;
        begin prod = a * b; qmul = prod[2*COORD_WIDTH-FRAC_BITS-1:COORD_WIDTH-FRAC_BITS]; end
    endfunction
    localparam S_IDLE=3'd0, S_HEIGHT0=3'd1, S_HEIGHT1=3'd2, S_VERT=3'd3, S_RASTER=3'd4, S_NEXT=3'd5, S_DONE=3'd6;
    reg [2:0] state;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin state<=S_IDLE; frame_done<=0; fb_wen<=0; hmap_read<=0; tex_read<=0; end
        else begin
            fb_wen <= 0; hmap_read <= 0; tex_read <= 0; frame_done <= 0;
            case (state)
                S_IDLE: begin
                    if (frame_start) begin grid_x<=0; grid_z<=0; state<=S_HEIGHT0; end
                end
                S_HEIGHT0: begin
                    hmap_addr <= grid_z * GRID_SIZE + grid_x;
                    hmap_read <= 1; state <= S_HEIGHT1;
                end
                S_HEIGHT1: begin
                    if (hmap_valid) begin
                        h00 <= {hmap_data, 4'd0}; // 扩展为Q4.12
                        hmap_addr <= grid_z * GRID_SIZE + grid_x + 1;
                        hmap_read <= 1;
                        state <= S_VERT;
                    end
                end
                S_VERT: begin
                    if (hmap_valid) begin
                        h10 <= {hmap_data, 4'd0};
                        // 生成三角形顶点(简化透视)
                        v0x <= grid_x * 16'd128; v0y <= {4'b0, h00[11:0]}; v0z <= grid_z * 16'd128;
                        v1x <= (grid_x+1) * 16'd128; v1y <= {4'b0, h10[11:0]}; v1z <= grid_z * 16'd128;
                        v2x <= grid_x * 16'd128; v2y <= h00; v2z <= (grid_z+1) * 16'd128;
                        state <= S_RASTER;
                    end
                end
                S_RASTER: begin
                    fb_wen <= 1; fb_x <= v0x; fb_y <= v0y;
                    fb_color <= 24'h228b22; // 绿色地形
                    state <= S_NEXT;
                end
                S_NEXT: begin
                    if (grid_x < GRID_SIZE - 2) grid_x <= grid_x + 1;
                    else begin grid_x <= 0;
                        if (grid_z < GRID_SIZE - 2) grid_z <= grid_z + 1;
                        else state <= S_DONE;
                    end
                    if (state != S_DONE) state <= S_HEIGHT0;
                end
                S_DONE: begin frame_done <= 1; state <= S_IDLE; end
                default: state <= S_IDLE;
            endcase
        end
    end
endmodule