MSX PCGアニメ

- Ver.1

```walk.c
/*
z88dk / WebMSX
zcc +msx -lndos -create-app -bnwalk walk.c
*/

#include <msx/gfx.h>

#define BYTE unsigned char

void main()
{
	const BYTE *pjiffy = (BYTE *)0xfc9e;
	const BYTE human[][8] = {
		{ 0x18, 0x58, 0x7e, 0x19, 0x18, 0x24, 0x22, 0x20 },
		{ 0x18, 0x1a, 0x7e, 0x98, 0x18, 0x24, 0x44, 0x04 }
	};

	int count = 0;

	set_mode(mode_1);
	vpoke(0x1800, 0);

	while (! get_trigger(0)) {

		BYTE jiffy = *pjiffy;
		while (jiffy == *pjiffy) ;

		vwrite(&(human[count & 1]), 0, 8);
		count++;
	}
}
```

- Ver.2

矢印キーでウェイト変更、スペースキーで終了。

```walk.c
/*
z88dk / WebMSX
zcc +msx -lndos -create-app -bnwalk walk.c
*/

#include <msx/gfx.h>
#include <string.h>

#define BYTE unsigned char

const BYTE space[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const BYTE wall[8] = { 0xfe, 0xfe, 0xfe, 0x00, 0xf7, 0xf7, 0xf7, 0x00 };
const BYTE human[][8] = {
	{ 0x18, 0x58, 0x7e, 0x19, 0x18, 0x24, 0x22, 0x20 },
	{ 0x18, 0x1a, 0x7e, 0x98, 0x18, 0x24, 0x44, 0x04 }
};

BYTE vvr[32*24];	// 仮想VRAM
BYTE anim[2][8*2];	// アニメ

void gen_map()
{
	for (int x = 0; x < 32; x++) {
		vvr[ 0*32+x] = 1;
		vvr[23*32+x] = 1;
	}
	for (int y = 0; y < 24; y++) {
		vvr[y*32+ 0] = 1;
		vvr[y*32+31] = 1;
	}
	for (int y = 1; y < 23; y += 2) {
		for (int x = 1; x < 31; x++) {
			vvr[    y*32+ x] = 2;
			vvr[(y+1)*32+ x] = 3;
		}
	}
}

void gen_anim()
{
	memcpy(&(anim[0])+0, &(human[0]), 8);
	memcpy(&(anim[0])+8, &(human[1]), 8);
	memcpy(&(anim[1])+0, &(human[1]), 8);
	memcpy(&(anim[1])+8, &(human[0]), 8);
}

void main()
{
	const BYTE *pjiffy = (BYTE *)0xfc9e;

	int wait = 1;
	int count = 0;
	int phase = 0;

	set_mode(mode_1);
	gen_map();
	gen_anim();

	vwrite(space, 0, 8);
	vwrite(wall, 8, 8);
	vwrite(vvr, 0x1800, 32*24);

	while (! get_trigger(0)) {
		int st = get_stick(0);
		if (st) {
			wait = st;
		}

		BYTE jiffy = *pjiffy;
		while (jiffy == *pjiffy) ;

		if (++count >= wait) {
			count = 0;
			vwrite(&(anim[phase]), 16, 16);
			if (++phase >= 2) {
				phase = 0;
			}
		}
	}
}
```

[WebMSX カセット版](http://webmsx.org/?tape=http://www.maroon.dti.ne.jp/lance/file/walk.cas
)

- Ver.3

```walk.c
/*
z88dk / WebMSX
zcc +msx -lndos -create-app -bnwalk walk.c
*/

#include <msx/gfx.h>
#include <string.h>

#define BYTE unsigned char
#define WORD unsigned int
#define HIWORD(w) ((w)>>8)
#define LOWORD(w) ((w)&0xff)
#define _countof(arr) (sizeof(arr)/sizeof(arr[0]))

const BYTE space[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const BYTE wall[8] = { 0xfe, 0xfe, 0xfe, 0x00, 0xf7, 0xf7, 0xf7, 0x00 };
const BYTE human[][8] = {
	{ 0x18, 0x58, 0x7e, 0x19, 0x18, 0x24, 0x22, 0x20 },
	{ 0x18, 0x1a, 0x7e, 0x98, 0x18, 0x24, 0x44, 0x04 }
};
const int seq[] = { 0,1,2,3,4,5,6,7,6,5,4,3,2,1 };

BYTE vvr[32*24];	// 仮想VRAM
BYTE anim[8][8*8];	// アニメ phase, byte * name

void put_name(x, y, n)
{
	vvr[y*32+x] = n;
}

void gen_map()
{
	for (int x = 0; x < 32; x++) {
		put_name(x, 0, 1);
		put_name(x, 23, 1);
	}
	for (int y = 0; y < 24; y++) {
		put_name(0, y, 1);
		put_name(31, y, 1);
	}
	for (int y = 1; y < 23; y += 2) {
		for (int x = 1; x < 31; x += 4) {
			put_name(x,   y,   2);
			put_name(x,   y+1, 3);
			put_name(x+1, y,   4);
			put_name(x+1, y+1, 5);
		}
		for (int x = 3; x < 31; x += 4) {
			put_name(x,   y,   6);
			put_name(x+1, y,   7);
			put_name(x,   y+1, 8);
			put_name(x+1, y+1, 9);
		}
	}
}

void gen_anim()
{
	for (int ph = 0; ph < 8; ph++) {
		BYTE *dst = &(anim[ph]);
		BYTE *src = &(human[ph & 1]);
		memcpy(dst+8*0+ph, src, 8);
		memcpy(dst+8*3-ph, src, 8);
		for (int y = 0; y < 8; y++) {
			WORD w;
			w = src[y] << (8-ph);
			dst[8*4+y] = HIWORD(w);
			dst[8*5+y] = LOWORD(w);
			w = src[y] << ph;
			dst[8*6+y] = HIWORD(w);
			dst[8*7+y] = LOWORD(w);
		}
	}
}

void main()
{
	const BYTE *pjiffy = (BYTE *)0xfc9e;

	int wait = 1;
	int count = 0;
	int phase = 0;

	set_mode(mode_1);
	gen_map();
	gen_anim();

	vwrite(space, 0, 8);
	vwrite(wall, 8, 8);
	vwrite(vvr, 0x1800, 32*24);

	while (! get_trigger(0)) {
		int st = get_stick(0);
		if (st) {
			wait = st;
		}

		BYTE jiffy = *pjiffy;
		while (jiffy == *pjiffy) ;

		if (++count >= wait) {
			count = 0;
			vwrite(&(anim[seq[phase]]), 16, 8*8);
			if (++phase >= _countof(seq)) {
				phase = 0;
			}
		}
	}
}
```

[WebMSX カセット版(2)](http://webmsx.org/?tape=http://www.maroon.dti.ne.jp/lance/file/walk2.cas
)