/* old_gfx_plot.c —— 函数曲线（图形界面）
 * old_gfx_plot.c -- function curves (graphical window)
 *
 * 类别：graphic
 * Category: graphic
 * 兼容面：用 `ui_2d_line` 逐段连成曲线 + `ui_2d_pixel` 画散点 + 整数三角函数表。
 * Compatibility: joining segment by segment with `ui_2d_line` to form a curve + `ui_2d_pixel` for scatter points + an integer trig table.
 *         对应 BGI 时代最常见的"画函数图像"练习。
 *         This is the counterpart of the most common "plot a function" exercise of the BGI era.
 * 出处：自写。
 * Origin: self-written.
 *
 * ⚠ 用**整数正弦表**而不是 `sin()`：一来当年 8 位机上算浮点三角函数很贵、
 * ⚠ Use an **integer sine table** instead of `sin()`: for one thing, floating-point trig was expensive on 8-bit machines back then,
 *   老程序普遍预存表；~~二来本平台的浮点数组/64 位几条路尚有问题（见台账）~~，
 *   so old programs commonly pre-stored the table; ~~for another, this platform's float-array / 64-bit paths still had problems (see the ledger)~~,
 *   ✅ **已修好（2026-10-04 复验）**：`float farr[8]; farr[1]=7.0f` 读回 **7.000**、`long la[4]` 四条全落地、
 *   ✅ **fixed (re-checked 2026-10-04)**: `float farr[8]; farr[1]=7.0f` reads back **7.000**, all four `long la[4]` land, and
 *   全局 `double` 数组元素也正确 ⇒ 浮点数组/64 位那几条路现在都通。整数表**照旧保留**（能跑就别动）。
 *   global `double` array elements are correct too => those float-array / 64-bit paths all work now. The integer table **stays** (if it runs, do not touch it).
 */
#include <vml_ui.h>

#define W 320
#define H 240
#define PI2 256          /* 一个周期 256 个单位（老式定点写法）*/
                         /* One period is 256 units (the old fixed-point convention) */

/* 正弦表：值域 -100..100，一个周期 64 项 */
/* Sine table: range -100..100, 64 entries per period */
static int sintab[64] = {
      0,  10,  20,  29,  38,  47,  56,  63,
     71,  77,  83,  88,  92,  95,  98,  99,
    100,  99,  98,  95,  92,  88,  83,  77,
     71,  63,  56,  47,  38,  29,  20,  10,
      0, -10, -20, -29, -38, -47, -56, -63,
    -71, -77, -83, -88, -92, -95, -98, -99,
   -100, -99, -98, -95, -92, -88, -83, -77,
    -71, -63, -56, -47, -38, -29, -20, -10
};

static int isin(int t) { return sintab[t & 63]; }

int main(void)
{
    int x, y0, y1, msg;
    int lang;   /* 界面语言：开局查一次 */
                /* UI language: queried once at start */

    lang = ui_scr_get_language();
    ui_win_open(lang == 0 ? "老式绘图：函数曲线" : "Old-style gfx: function curves", W, H);
    ui_2d_clear(0x101820);

    /* 坐标轴 */
    /* Axes */
    ui_2d_line(0, H / 2, W, H / 2, 0x404A5A, 1);     /* x 轴 */
                                                  /* x axis */
    ui_2d_line(W / 2, 0, W / 2, H, 0x404A5A, 1);     /* y 轴 */
                                                  /* y axis */

    /* 正弦曲线：逐段连（老办法） */
    /* Sine curve: joined segment by segment (the old way) */
    y0 = H / 2;
    for (x = 0; x < W; x++) {
        y1 = H / 2 - isin(x) * (H / 2 - 20) / 100;
        if (x > 0) ui_2d_line(x - 1, y0, x, y1, 0x61AFEF, 2);
        y0 = y1;
    }

    /* 抛物线：y = (x-160)^2 / 40，整数算 */
    /* Parabola: y = (x-160)^2 / 40, computed in integer arithmetic */
    y0 = 0;
    for (x = 0; x < W; x++) {
        int d = x - W / 2;
        y1 = d * d / 40;
        if (y1 > H - 1) y1 = H - 1;
        if (x > 0) ui_2d_line(x - 1, y0, x, y1, 0xE5C07B, 1);
        y0 = y1;
    }

    /* 散点：用 ui_2d_pixel 打点（对照上面两种连法）*/
    /* Scatter points: plotted with ui_2d_pixel (to compare with the two joining methods above) */
    for (x = 0; x < W; x += 8)
        ui_2d_pixel(x, H - 1 - (isin(x * 4) + 100) / 8, 0x98C379);

    ui_2d_text(8, 8, lang == 0 ? "sin / 抛物线 / 散点" : "sin / parabola / scatter", 0xABB2BF, 16, VML_ANCHOR_LEFT);
    ui_2d_present();
    while (!ui_win_is_closed())
        ui_msg_wait(&msg, 0);          /* 画完等关窗，别立刻关（快照会没）*/
                                   /* Wait for the window to close after drawing; do not close right away (the snapshot would be lost) */
    ui_win_close();
    return 0;
}
