「PC-98/sgseena」の編集履歴(バックアップ)一覧はこちら

PC-98/sgseena」(2021/03/19 (金) 20:18:14) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

開発環境 -QuickC JavaScriptプロトタイプ https://jsfiddle.net/qvtmzpjd/ 4、6キーで左右回転。 sgseena.c #highlight(c){{ #include <conio.h> #include <dos.h> #define BASE 0x100 #define CYCLE 256 #define FOV 80 #define TRUE 1 typedef unsigned char BYTE; typedef unsigned short WORD; typedef signed short SWORD; typedef signed long SDWORD; typedef struct { SWORD x; SWORD y; } vec2; typedef struct { SWORD x; SWORD y; BYTE d; } CAR; // 関数プロトタイプ宣言 void setup(); void draw(); SWORD rayBlock(vec2 rd, BYTE *pFace); BYTE getMap(int x, int y); SWORD mul(SWORD x, SWORD y); SWORD div(SWORD x, SWORD y); // 外部変数 #include "wall.h" #include "map.h" #include "sint.h" CAR car = {0x400, 0x400, 0}; int main() { setup(); while (! kbhit()) { draw(); car.d++; } return 0; } void setup() { union REGS inregs, outregs; inregs.h.ah = 0x0a; // テキスト画面モードの設定 inregs.h.al = 0x04; // 簡易グラフ int86(0x18, &inregs, &outregs); inregs.h.ah = 0x16; // テキストVRAMのクリア inregs.h.dh = 0x91; // アトリビュートデータ inregs.h.dl = 0x00; // ANK文字コード int86(0x18, &inregs, &outregs); } void draw() { BYTE t, h, face; const BYTE *pWall; SWORD st, ct, x, d; vec2 rd; int i, y; char far *lp; t = car.d; st = sint[t]; t += (CYCLE/4); ct = sint[t]; x = -6 * FOV / 2; for (i = 0; i < FOV; i++) { rd.x = mul(ct, x) + st; rd.y = ct - mul(st, x); d = rayBlock(rd, &face); h = 0; if (d > 0) { h = (BYTE)(12 * BASE / d); if (h > 50) h = 50; } else if (d == 0) { h = 50; } lp = (char far *)(0xa0000000 + i * 2); pWall = wall[face][h]; for (y = 0; y < 25; y++) { *lp = pWall[y]; lp += 160; } x += 6; } } SWORD rayBlock(vec2 rd, BYTE *pFace) { vec2 p = {car.x, car.y}; vec2 v = rd; vec2 s = {1, 1}; // sign vec2 a = {0, 0}; vec2 c, e; int x, y; BYTE m, f = 0; SWORD d = 0; if (v.x < 0) { p.x = -p.x; v.x = -v.x; s.x = -1; a.x = BASE; } if (v.y < 0) { p.y = -p.y; v.y = -v.y; s.y = -1; a.y = BASE; } c.x = s.x * ((car.x & 0xff00) + a.x); c.y = s.y * ((car.y & 0xff00) + a.y); *pFace = 0; while (TRUE) { x = (s.x * (c.x + a.x)) / BASE; y = (s.y * (c.y + a.y)) / BASE; m = getMap(x, y); if (m) { if (m == 1) m = f; *pFace = m; break; } e.x = div(c.x + BASE - p.x, v.x); e.y = div(c.y + BASE - p.y, v.y); d = (e.x <= e.y) ? e.x : e.y; if (d > 0x1000) return -1; if (e.x <= e.y) { c.x += BASE; f = 0; } else { c.y += BASE; f = 1; } } return d; } BYTE getMap(int x, int y) { return map[y][x]; } SWORD mul(SWORD x, SWORD y) { return (SWORD)((SDWORD)x * (SDWORD)y / BASE); } SWORD div(SWORD x, SWORD y) { if (-2 <= y && y <= 2) { return (y < 0) ? 0x8000 : 0x7fff; } return (SWORD)((SDWORD)x * BASE / (SDWORD)y); } }} map.h #highlight(c){{ const BYTE map[8][8] = { {2,1,2,1, 2,1,2,1}, {1,0,0,0, 0,0,0,2}, {2,0,0,0, 0,0,0,1}, {1,0,0,0, 0,0,0,2}, {2,0,0,0, 0,0,0,1}, {1,0,1,0, 0,2,0,2}, {2,0,0,0, 0,0,0,1}, {1,2,1,2, 1,2,1,2}, }; }} sint.h #highlight(c){{ const SWORD sint[256] = { 0x0000,0x0006,0x000d,0x0013,0x0019,0x001f,0x0026,0x002c, 0x0032,0x0038,0x003e,0x0044,0x004a,0x0050,0x0056,0x005c, 0x0062,0x0068,0x006d,0x0073,0x0079,0x007e,0x0084,0x0089, 0x008e,0x0093,0x0098,0x009d,0x00a2,0x00a7,0x00ac,0x00b1, 0x00b5,0x00b9,0x00be,0x00c2,0x00c6,0x00ca,0x00ce,0x00d1, 0x00d5,0x00d8,0x00dc,0x00df,0x00e2,0x00e5,0x00e7,0x00ea, 0x00ed,0x00ef,0x00f1,0x00f3,0x00f5,0x00f7,0x00f8,0x00fa, 0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,0x00ff,0x0100,0x0100, 0x0100,0x0100,0x0100,0x00ff,0x00ff,0x00fe,0x00fd,0x00fc, 0x00fb,0x00fa,0x00f8,0x00f7,0x00f5,0x00f3,0x00f1,0x00ef, 0x00ed,0x00ea,0x00e7,0x00e5,0x00e2,0x00df,0x00dc,0x00d8, 0x00d5,0x00d1,0x00ce,0x00ca,0x00c6,0x00c2,0x00be,0x00b9, 0x00b5,0x00b1,0x00ac,0x00a7,0x00a2,0x009d,0x0098,0x0093, 0x008e,0x0089,0x0084,0x007e,0x0079,0x0073,0x006d,0x0068, 0x0062,0x005c,0x0056,0x0050,0x004a,0x0044,0x003e,0x0038, 0x0032,0x002c,0x0026,0x001f,0x0019,0x0013,0x000d,0x0006, 0x0000,0xfffa,0xfff3,0xffed,0xffe7,0xffe1,0xffda,0xffd4, 0xffce,0xffc8,0xffc2,0xffbc,0xffb6,0xffb0,0xffaa,0xffa4, 0xff9e,0xff98,0xff93,0xff8d,0xff87,0xff82,0xff7c,0xff77, 0xff72,0xff6d,0xff68,0xff63,0xff5e,0xff59,0xff54,0xff4f, 0xff4b,0xff47,0xff42,0xff3e,0xff3a,0xff36,0xff32,0xff2f, 0xff2b,0xff28,0xff24,0xff21,0xff1e,0xff1b,0xff19,0xff16, 0xff13,0xff11,0xff0f,0xff0d,0xff0b,0xff09,0xff08,0xff06, 0xff05,0xff04,0xff03,0xff02,0xff01,0xff01,0xff00,0xff00, 0xff00,0xff00,0xff00,0xff01,0xff01,0xff02,0xff03,0xff04, 0xff05,0xff06,0xff08,0xff09,0xff0b,0xff0d,0xff0f,0xff11, 0xff13,0xff16,0xff19,0xff1b,0xff1e,0xff21,0xff24,0xff28, 0xff2b,0xff2f,0xff32,0xff36,0xff3a,0xff3e,0xff42,0xff47, 0xff4b,0xff4f,0xff54,0xff59,0xff5e,0xff63,0xff68,0xff6d, 0xff72,0xff77,0xff7c,0xff82,0xff87,0xff8d,0xff93,0xff98, 0xff9e,0xffa4,0xffaa,0xffb0,0xffb6,0xffbc,0xffc2,0xffc8, 0xffce,0xffd4,0xffda,0xffe1,0xffe7,0xffed,0xfff3,0xfffa, }; }} wall.h #highlight(c){{ const BYTE wall[3][51][25] = { { {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0xa5,0x25,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0xa5,0x25,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0xa5,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa5,0xa5,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, 以下略 }} mk.bat #highlight(txt){{ qcl /c sgseena.c link sgseena; }} &image(sgseena.png)
開発環境 -QuickC [[JavaScript]]プロトタイプ https://jsfiddle.net/qvtmzpjd/ 4、6キーで左右回転。 sgseena.c #highlight(c){{ #include <conio.h> #include <dos.h> #define BASE 0x100 #define CYCLE 256 #define FOV 80 #define TRUE 1 typedef unsigned char BYTE; typedef unsigned short WORD; typedef signed short SWORD; typedef signed long SDWORD; typedef struct { SWORD x; SWORD y; } vec2; typedef struct { SWORD x; SWORD y; BYTE d; } CAR; // 関数プロトタイプ宣言 void setup(); void draw(); SWORD rayBlock(vec2 rd, BYTE *pFace); BYTE getMap(int x, int y); SWORD mul(SWORD x, SWORD y); SWORD div(SWORD x, SWORD y); // 外部変数 #include "wall.h" #include "map.h" #include "sint.h" CAR car = {0x400, 0x400, 0}; int main() { setup(); while (! kbhit()) { draw(); car.d++; } return 0; } void setup() { union REGS inregs, outregs; inregs.h.ah = 0x0a; // テキスト画面モードの設定 inregs.h.al = 0x04; // 簡易グラフ int86(0x18, &inregs, &outregs); inregs.h.ah = 0x16; // テキストVRAMのクリア inregs.h.dh = 0x91; // アトリビュートデータ inregs.h.dl = 0x00; // ANK文字コード int86(0x18, &inregs, &outregs); } void draw() { BYTE t, h, face; const BYTE *pWall; SWORD st, ct, x, d; vec2 rd; int i, y; char far *lp; t = car.d; st = sint[t]; t += (CYCLE/4); ct = sint[t]; x = -6 * FOV / 2; for (i = 0; i < FOV; i++) { rd.x = mul(ct, x) + st; rd.y = ct - mul(st, x); d = rayBlock(rd, &face); h = 0; if (d > 0) { h = (BYTE)(12 * BASE / d); if (h > 50) h = 50; } else if (d == 0) { h = 50; } lp = (char far *)(0xa0000000 + i * 2); pWall = wall[face][h]; for (y = 0; y < 25; y++) { *lp = pWall[y]; lp += 160; } x += 6; } } SWORD rayBlock(vec2 rd, BYTE *pFace) { vec2 p = {car.x, car.y}; vec2 v = rd; vec2 s = {1, 1}; // sign vec2 a = {0, 0}; vec2 c, e; int x, y; BYTE m, f = 0; SWORD d = 0; if (v.x < 0) { p.x = -p.x; v.x = -v.x; s.x = -1; a.x = BASE; } if (v.y < 0) { p.y = -p.y; v.y = -v.y; s.y = -1; a.y = BASE; } c.x = s.x * ((car.x & 0xff00) + a.x); c.y = s.y * ((car.y & 0xff00) + a.y); *pFace = 0; while (TRUE) { x = (s.x * (c.x + a.x)) / BASE; y = (s.y * (c.y + a.y)) / BASE; m = getMap(x, y); if (m) { if (m == 1) m = f; *pFace = m; break; } e.x = div(c.x + BASE - p.x, v.x); e.y = div(c.y + BASE - p.y, v.y); d = (e.x <= e.y) ? e.x : e.y; if (d > 0x1000) return -1; if (e.x <= e.y) { c.x += BASE; f = 0; } else { c.y += BASE; f = 1; } } return d; } BYTE getMap(int x, int y) { return map[y][x]; } SWORD mul(SWORD x, SWORD y) { return (SWORD)((SDWORD)x * (SDWORD)y / BASE); } SWORD div(SWORD x, SWORD y) { if (-2 <= y && y <= 2) { return (y < 0) ? 0x8000 : 0x7fff; } return (SWORD)((SDWORD)x * BASE / (SDWORD)y); } }} map.h #highlight(c){{ const BYTE map[8][8] = { {2,1,2,1, 2,1,2,1}, {1,0,0,0, 0,0,0,2}, {2,0,0,0, 0,0,0,1}, {1,0,0,0, 0,0,0,2}, {2,0,0,0, 0,0,0,1}, {1,0,1,0, 0,2,0,2}, {2,0,0,0, 0,0,0,1}, {1,2,1,2, 1,2,1,2}, }; }} sint.h #highlight(c){{ const SWORD sint[256] = { 0x0000,0x0006,0x000d,0x0013,0x0019,0x001f,0x0026,0x002c, 0x0032,0x0038,0x003e,0x0044,0x004a,0x0050,0x0056,0x005c, 0x0062,0x0068,0x006d,0x0073,0x0079,0x007e,0x0084,0x0089, 0x008e,0x0093,0x0098,0x009d,0x00a2,0x00a7,0x00ac,0x00b1, 0x00b5,0x00b9,0x00be,0x00c2,0x00c6,0x00ca,0x00ce,0x00d1, 0x00d5,0x00d8,0x00dc,0x00df,0x00e2,0x00e5,0x00e7,0x00ea, 0x00ed,0x00ef,0x00f1,0x00f3,0x00f5,0x00f7,0x00f8,0x00fa, 0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,0x00ff,0x0100,0x0100, 0x0100,0x0100,0x0100,0x00ff,0x00ff,0x00fe,0x00fd,0x00fc, 0x00fb,0x00fa,0x00f8,0x00f7,0x00f5,0x00f3,0x00f1,0x00ef, 0x00ed,0x00ea,0x00e7,0x00e5,0x00e2,0x00df,0x00dc,0x00d8, 0x00d5,0x00d1,0x00ce,0x00ca,0x00c6,0x00c2,0x00be,0x00b9, 0x00b5,0x00b1,0x00ac,0x00a7,0x00a2,0x009d,0x0098,0x0093, 0x008e,0x0089,0x0084,0x007e,0x0079,0x0073,0x006d,0x0068, 0x0062,0x005c,0x0056,0x0050,0x004a,0x0044,0x003e,0x0038, 0x0032,0x002c,0x0026,0x001f,0x0019,0x0013,0x000d,0x0006, 0x0000,0xfffa,0xfff3,0xffed,0xffe7,0xffe1,0xffda,0xffd4, 0xffce,0xffc8,0xffc2,0xffbc,0xffb6,0xffb0,0xffaa,0xffa4, 0xff9e,0xff98,0xff93,0xff8d,0xff87,0xff82,0xff7c,0xff77, 0xff72,0xff6d,0xff68,0xff63,0xff5e,0xff59,0xff54,0xff4f, 0xff4b,0xff47,0xff42,0xff3e,0xff3a,0xff36,0xff32,0xff2f, 0xff2b,0xff28,0xff24,0xff21,0xff1e,0xff1b,0xff19,0xff16, 0xff13,0xff11,0xff0f,0xff0d,0xff0b,0xff09,0xff08,0xff06, 0xff05,0xff04,0xff03,0xff02,0xff01,0xff01,0xff00,0xff00, 0xff00,0xff00,0xff00,0xff01,0xff01,0xff02,0xff03,0xff04, 0xff05,0xff06,0xff08,0xff09,0xff0b,0xff0d,0xff0f,0xff11, 0xff13,0xff16,0xff19,0xff1b,0xff1e,0xff21,0xff24,0xff28, 0xff2b,0xff2f,0xff32,0xff36,0xff3a,0xff3e,0xff42,0xff47, 0xff4b,0xff4f,0xff54,0xff59,0xff5e,0xff63,0xff68,0xff6d, 0xff72,0xff77,0xff7c,0xff82,0xff87,0xff8d,0xff93,0xff98, 0xff9e,0xffa4,0xffaa,0xffb0,0xffb6,0xffbc,0xffc2,0xffc8, 0xffce,0xffd4,0xffda,0xffe1,0xffe7,0xffed,0xfff3,0xfffa, }; }} wall.h #highlight(c){{ const BYTE wall[3][51][25] = { { {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0xa5,0x25,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0xa5,0x25,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0xa5,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa5,0xa5,0xa5,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,}, 以下略 }} mk.bat #highlight(txt){{ qcl /c sgseena.c link sgseena; }} &image(sgseena.png)

表示オプション

横に並べて表示:
変化行の前後のみ表示: