非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

X68000(25)

ピクセルごとの描画を行う関数を作成しました。これをインラインアセンブラに書きたいのですが、どうやってやるか検討中です。

スーパーバイザーモードへの切り替えを別の関数にするやり方は、うまく動作しませんでした。スーパーバイザーモードから戻るのができないようで、これは別の関数にすることは難しいのかもしれません。

楕円の弧を描く関数

deg_to_rad 関数は double と入力すると Visual Studio で自動的に補完されました。内容は機械的なものなのですが、これを入力しようとしていることが Visual Studio にはわかるようです。

double deg_to_rad(int angle) {
    return angle * 3.14159 / 180.0;
}
void DirectDrawArcTo(HDC hdc, int x1, int y1, int w, int h, int start_angle, int sweep_angle, COLORREF color) {
    int cx = x1 + w / 2;
    int cy = y1 + h / 2;
    for (int a = start_angle; a < start_angle + sweep_angle; a += 5) {
        int x = cx + (int)(cos(deg_to_rad(a)) * w / 2);
        int y = cy - (int)(sin(deg_to_rad(a)) * h / 2);
        DirectDrawLineTo(hdc, x, y, color);
    }
    {
        int a = start_angle + sweep_angle;
        int x = cx + (int)(cos(deg_to_rad(a)) * w / 2);
        int y = cy - (int)(sin(deg_to_rad(a)) * h / 2);
        DirectDrawLineTo(hdc, x, y, color);
    }
}
void DirectDrawArc(HDC hdc, int x1, int y1, int w, int h, int start_angle, int sweep_angle, COLORREF color) {
    DirectDrawLineInit();
    DirectDrawArcTo(hdc, x1, y1, w, h, start_angle, sweep_angle, color);
}

楕円を描く関数

void DirectDrawEllipse(HDC hdc, int x1, int y1, int w, int h, COLORREF color) {
    DirectDrawLineInit();
    DirectDrawArcTo(hdc, x1, y1, w, h, 0, 360, color);
}

楕円の扇型を描く関数

void DirectDrawPie(HDC hdc, int x1, int y1, int w, int h, int start_angle, int sweep_angle, COLORREF color) {
    DirectDrawLineInit();
    DirectDrawLineTo(hdc, x1 + w / 2, y1 + h / 2, color);
    DirectDrawArcTo(hdc, x1, y1, w, h, start_angle, sweep_angle, color);
    DirectDrawLineTo(hdc, x1 + w / 2, y1 + h / 2, color);
}

角が丸い四角形を描く関数

void DirectDrawRoundedRectangle(HDC hdc, int x1, int y1, int w, int h, int rx, int ry, COLORREF color) {
    // 角丸矩形を描く
    DirectDrawLineInit();
    // 右上の弧を描く
    DirectDrawArcTo(hdc, x1 + w - rx * 2, y1, rx * 2, ry * 2, 0, 90, color);
    // 上の直線を描く
    DirectDrawLineTo(hdc, x1 + rx, y1, color);
    // 左上の弧を描く
    DirectDrawArcTo(hdc, x1, y1, rx * 2, ry * 2, 90, 90, color);
    // 左の直線を描く
    DirectDrawLineTo(hdc, x1, y1 + h - ry, color);
    // 左下の弧を描く
    DirectDrawArcTo(hdc, x1, y1 + h - ry * 2, rx * 2, ry * 2, 180, 90, color);
    // 下の直線を描く
    DirectDrawLineTo(hdc, x1 + w - rx, y1 + h, color);
    // 右下の弧を描く
    DirectDrawArcTo(hdc, x1 + w - rx * 2, y1 + h - ry * 2, rx * 2, ry * 2, 270, 90, color);
    // 右の直線を描く
    DirectDrawLineTo(hdc, x1 + w, y1 + ry, color);
}

塗りつぶした楕円を描く関数

void DirectFillEllipse(HDC hdc, int x1, int y1, int w, int h, COLORREF color) {
    int cx = x1 + w / 2;
    int cy = y1 + h / 2;
    for (int y = y1; y < y1 + h; ++y) {
        double uy = ((double)y - cy) * 2 / h; // 単位円のy座標
        int ex = (int)(sqrt(1 - uy * uy) * w / 2); // 楕円のx座標
        for (int x = cx - ex; x <= cx + ex; ++x) {
            SetPixel(hdc, x, y, color);
        }
    }
}

塗りつぶした角が丸い四角形を描く関数

void DirectFillRoundedRectangle(HDC hdc, int x1, int y1, int w, int h, int rx, int ry, COLORREF color) {
    int cx = x1 + rx;
    int cy = y1 + ry;
    for (int y = y1; y < y1 + ry; ++y) {
        double uy = ((double)y - cy) / ry; // 単位円のy座標
        int ex = (int)(sqrt(1 - uy * uy) * rx); // 楕円のx座標
        int y2 = y1 + h - (y - y1) - 1;
        for (int x = cx - ex; x <= x1 + w - rx + ex; ++x) {
            SetPixel(hdc, x, y, color);
            SetPixel(hdc, x, y2, color);
        }
    }
    for (int y = y1 + ry; y < y1 + h - ry; ++y) {
        for (int x = x1; x < x1 + w; ++x) {
            SetPixel(hdc, x, y, color);
        }
    }
}