開発環境
  • QuickC

JavaScriptプロトタイプ
https://jsfiddle.net/qvtmzpjd/
4、6キーで左右回転。

sgseena.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
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
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
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
qcl /c sgseena.c
link sgseena;
 

最終更新:2021年03月19日 20:18
添付ファイル