Beispiel #1
0
Datei: object.c Projekt: hsk/docs
void *
sml_obj_dup(void *obj)
{
	void **slot, *newobj;
	size_t obj_size;

	switch (OBJ_TYPE(obj)) {
	case OBJTYPE_UNBOXED_ARRAY:
	case OBJTYPE_BOXED_ARRAY:
	case OBJTYPE_UNBOXED_VECTOR:
	case OBJTYPE_BOXED_VECTOR:
		obj_size = OBJ_SIZE(obj);
		slot = sml_push_tmp_rootset(1);
		*slot = obj;
		newobj = sml_obj_alloc(OBJ_TYPE(obj), obj_size);
		memcpy(newobj, *slot, obj_size);
		sml_pop_tmp_rootset(slot);
		return newobj;

	case OBJTYPE_RECORD:
		obj_size = OBJ_SIZE(obj);
		slot = sml_push_tmp_rootset(1);
		*slot = obj;
		newobj = sml_record_alloc(obj_size);
		memcpy(newobj, *slot,
		       obj_size + SIZEOF_BITMAP * OBJ_BITMAPS_LEN(obj_size));
		sml_pop_tmp_rootset(slot);
		return newobj;

	default:
		sml_fatal(0, "BUG: invalid object type : %d", OBJ_TYPE(obj));
	}
}
Beispiel #2
0
void
sml_obj_enum_ptr(void *obj, void (*trace)(void **, void *), void *data)
{
	unsigned int i;
	unsigned int *bitmaps;

	/*
	DBG("%p: size=%lu, type=%08x",
	    obj, (unsigned long)OBJ_SIZE(obj), (unsigned int)OBJ_TYPE(obj));
	*/

	switch (OBJ_TYPE(obj)) {
	case OBJTYPE_UNBOXED_ARRAY:
	case OBJTYPE_UNBOXED_VECTOR:
	case OBJTYPE_INTINF:
		break;

	case OBJTYPE_BOXED_ARRAY:
	case OBJTYPE_BOXED_VECTOR:
		for (i = 0; i < OBJ_SIZE(obj) / sizeof(void*); i++)
			trace((void**)obj + i, data);
		break;

	case OBJTYPE_RECORD:
		bitmaps = OBJ_BITMAP(obj);
		for (i = 0; i < OBJ_SIZE(obj) / sizeof(void*); i++) {
			if (BITMAP_BIT(bitmaps, i) != TAG_UNBOXED)
				trace((void**)obj + i, data);
		}
		break;

	default:
		sml_fatal(0, "BUG: invalid object type : %d", OBJ_TYPE(obj));
	}
}
Beispiel #3
0
Datei: object.c Projekt: hsk/docs
/* for debug */
static void
obj_dump__(int indent, void *obj)
{
	unsigned int i;
	unsigned int *bitmap;
	void **field = obj;
	char *buf;

	if (obj == NULL) {
		sml_debug("%*sNULL\n", indent, "");
		return;
	}

	switch (OBJ_TYPE(obj)) {
	case OBJTYPE_UNBOXED_ARRAY:
	case OBJTYPE_UNBOXED_VECTOR:
		sml_debug("%*s%p:%u:%s\n",
			  indent, "", obj, OBJ_SIZE(obj),
			  (OBJ_TYPE(obj) == OBJTYPE_UNBOXED_ARRAY)
			  ? "UNBOXED_ARRAY" : "UNBOXED_VECTOR");
		for (i = 0; i < OBJ_SIZE(obj) / sizeof(unsigned int); i++)
			sml_debug("%*s0x%08x\n",
				  indent + 2, "", ((unsigned int *)field)[i]);
		for (i = i * sizeof(unsigned int); i < OBJ_SIZE(obj); i++)
			sml_debug("%*s0x%02x\n",
				  indent + 2, "", ((unsigned char*)field)[i]);
		break;

	case OBJTYPE_BOXED_ARRAY:
	case OBJTYPE_BOXED_VECTOR:
		sml_debug("%*s%p:%u:%s\n",
			  indent, "", obj, OBJ_SIZE(obj),
			  (OBJ_TYPE(obj) == OBJTYPE_BOXED_ARRAY)
			  ? "BOXED_ARRAY" : "BOXED_VECTOR");
		for (i = 0; i < OBJ_SIZE(obj) / sizeof(void*); i++)
			obj_dump__(indent + 2, field[i]);
		for (i = i * sizeof(void*); i < OBJ_SIZE(obj); i++)
			sml_debug("%*s0x%02x\n",
				  indent + 2, "", ((char*)field)[i]);
		break;

	case OBJTYPE_RECORD:
		sml_debug("%*s%p:%u:RECORD\n",
			  indent, "", obj, OBJ_SIZE(obj));
		bitmap = OBJ_BITMAP(obj);
		for (i = 0; i < OBJ_SIZE(obj) / sizeof(void*); i++) {
			if (BITMAP_BIT(bitmap, i) != TAG_UNBOXED)
				obj_dump__(indent + 2, field[i]);
			else
				sml_debug("%*s%p\n", indent + 2, "", field[i]);
		}
		break;

	default:
		sml_debug("%*s%p:%u:unknown type %u",
			  indent, "", obj, OBJ_SIZE(obj), OBJ_TYPE(obj));
		break;
	}
}
void
SpriteRenderer::update()
{
  for(int i = 0; i < 128; ++i)
    {
      // OAM[i].attr0 = OBJ_Y(80)  | OBJ_SHAPE(0) | OBJ_256_COLOR;
      // OAM[i].attr1 = OBJ_X(120) | OBJ_SIZE(2);
      // OAM[i].attr2 = OBJ_CHAR(8) | OBJ_PALETTE(0) | OBJ_PRIORITY(0);
      Sprite& sprite = sprites[i];
      if (sprite.is_enabled())
        {
          OAM[i].attr0 = OBJ_Y((sprite.get_y() - sprite.get_data().get_y_align() - y_offset) & 0xFF) | OBJ_SHAPE(0) | OBJ_256_COLOR;
          OAM[i].attr1 = 
            OBJ_X((sprite.get_x() - sprite.get_data().get_x_align() - x_offset) & 0xFF) |
            OBJ_SIZE(2) |
            (sprite.get_vflip() ? OBJ_VFLIP : 0) |
            (sprite.get_hflip() ? OBJ_HFLIP : 0);
          OAM[i].attr2 = OBJ_CHAR(sprite.get_data().get_char_addr(sprite.get_frame())) | OBJ_PALETTE(0) | OBJ_PRIORITY(0);          
        }
      else
        {
          OAM[i].attr0 = OBJ_DISABLE; // OBJ_Y(80)  | OBJ_SHAPE(0) | OBJ_256_COLOR;
          OAM[i].attr1 = 0; // OBJ_X(120) | OBJ_SIZE(2);
          OAM[i].attr2 = 0; // OBJ_CHAR(8) | OBJ_PALETTE(0) | OBJ_PRIORITY(0);
        }
    }
}
Beispiel #5
0
int
prim_Timer_getTimes(int *ret)
{
#ifdef HAVE_TIMES
	struct tms tms;
	static long clocks_per_sec = 0;
	clock_t clk;

	ASSERT(OBJ_TYPE(ret) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_SIZE(ret) >= sizeof(int) * 6);

	if (clocks_per_sec == 0)
		clocks_per_sec = sysconf(_SC_CLK_TCK);

	clk = times(&tms);
	ret[0] = tms.tms_stime / clocks_per_sec;
	ret[1] = (tms.tms_stime % clocks_per_sec) * 1000000 / clocks_per_sec;
	ret[2] = tms.tms_utime / clocks_per_sec;
	ret[3] = (tms.tms_utime % clocks_per_sec) * 1000000 / clocks_per_sec;
	/* FIXME: do we put GC time still here? */
	ret[4] = 0;  /* GC seconds */
	ret[5] = 0;  /* GC microseconds */

	return (clk == (clock_t)-1 ? -1 : 0);
#else
	struct timeval tv;
	int err;

	ASSERT(OBJ_TYPE(ret) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_SIZE(ret) >= sizeof(int) * 6);

	err = gettimeofday(&tv, NULL);
	ret[0] = 0;  /* sys seconds */
	ret[1] = 0;  /* sys microseconds */
	ret[2] = tv.tv_sec;
	ret[3] = tv.tv_usec;
	/* FIXME: do we put GC time still here? */
	ret[4] = 0;  /* GC seconds */
	ret[5] = 0;  /* GC microseconds */
	return err;
#endif /* HAVE_TIMES */
}
Beispiel #6
0
void sprite_init(Sprite* sprite, int gfxID)
{
    const int oamIdx = oam_pool_find_fist_empty();

    sprite->gfxID = gfxID;

    SpriteEntry* oam = &sm_OAMCopy[oamIdx];
    sprite->oam = oam;

    oam->attribute[0] = OBJ_256_COLOR | OBJ_SHAPE(0);
    oam->attribute[1] = OBJ_SIZE(1);
    oam->attribute[2] = gfxID;
}
Beispiel #7
0
int
prim_GenericOS_read(int fd, char *buf, unsigned int offset, unsigned int len)
{
	ASSERT(OBJ_TYPE(buf) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(offset + len <= OBJ_SIZE(buf));

#ifdef HAVE_INTERACTIVE_MODE
	if (interactive_mode && fd == 0)
		return interact_prim_read(fd, buf, offset, len);
#endif /* HAVE_INTERACTIVE_MODE */

	return read(fd, buf + offset, len);
}
Beispiel #8
0
int
prim_Time_gettimeofday(int *ret)
{
	struct timeval tv;
	int err;

	ASSERT(OBJ_TYPE(ret) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_SIZE(ret) >= sizeof(int) * 2);

	err = gettimeofday(&tv, NULL);
	ret[0] = tv.tv_sec;
	ret[1] = tv.tv_usec;
	return err;
}
Beispiel #9
0
void
prim_CopyMemory(void *dst, unsigned int doff,
		const void *src, unsigned int soff,
		unsigned int len, unsigned int tag)
{
	void **writeaddr, **srcaddr;
	unsigned int i;

	ASSERT((tag == TAG_UNBOXED
		&& (OBJ_TYPE(dst) == OBJTYPE_UNBOXED_ARRAY
		    || OBJ_TYPE(dst) == OBJTYPE_UNBOXED_VECTOR))
	       || (tag == TAG_BOXED
		   && (OBJ_TYPE(dst) == OBJTYPE_BOXED_ARRAY
		       || OBJ_TYPE(dst) == OBJTYPE_BOXED_VECTOR)));
	ASSERT((tag == TAG_UNBOXED
		&& (OBJ_TYPE(src) == OBJTYPE_UNBOXED_ARRAY
		    || OBJ_TYPE(src) == OBJTYPE_UNBOXED_VECTOR))
	       || (tag == TAG_BOXED
		   && (OBJ_TYPE(src) == OBJTYPE_BOXED_ARRAY
		       || OBJ_TYPE(src) == OBJTYPE_BOXED_VECTOR)));
	ASSERT(doff + len <= OBJ_SIZE(dst));
	ASSERT(soff + len <= OBJ_SIZE(src));

	if (tag == TAG_UNBOXED) {
		memmove((char*)dst + doff, (char*)src + soff, len);
	} else if (src != dst || doff < soff) {
		writeaddr = (void**)((char*)dst + doff);
		srcaddr = (void**)((char*)src + soff);
		for (i = 0; i < len / sizeof(void*); i++)
			sml_write(dst, writeaddr++, *(srcaddr++));
	} else {
		writeaddr = (void**)((char*)dst + doff + len);
		srcaddr = (void**)((char*)src + soff + len);
		for (i = 0; i < len / sizeof(void*); i++)
			sml_write(dst, --writeaddr, *(--srcaddr));
	}
}
Beispiel #10
0
static void
set_stat(struct stat *st, unsigned int *ret)
{
	ASSERT(OBJ_TYPE(ret) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_SIZE(ret) >= sizeof(unsigned int) * 6);

	ret[0] = st->st_dev;
	ret[1] = st->st_ino;
	ret[3] = st->st_atime;
	ret[4] = st->st_mtime;
	ret[5] = st->st_size;

#if S_IFIFO == ML_S_IFIFO \
	&& S_IFCHR == ML_S_IFCHR \
	&& S_IFDIR == ML_S_IFDIR \
	&& S_IFBLK == ML_S_IFBLK \
	&& S_IFREG == ML_S_IFREG \
	&& S_IFLNK == ML_S_IFLNK \
	&& S_IFSOCK == ML_S_IFSOCK \
	&& S_ISUID == ML_S_ISUID \
	&& S_ISGID == ML_S_ISGID \
	&& S_ISVTX == ML_S_ISVTX \
	&& S_IRUSR == ML_S_IRUSR \
	&& S_IWUSR == ML_S_IWUSR \
	&& S_IXUSR == ML_S_IXUSR
	ret[2] = st->st_mode;
#else
	{
		unsigned int mode = 0;
		mode |= (st->st_mode & S_IFIFO) ? ML_S_IFIFO : 0;
		mode |= (st->st_mode & S_IFCHR) ? ML_S_IFCHR : 0;
		mode |= (st->st_mode & S_IFDIR) ? ML_S_IFDIR : 0;
		mode |= (st->st_mode & S_IFBLK) ? ML_S_IFBLK : 0;
		mode |= (st->st_mode & S_IFREG) ? ML_S_IFREG : 0;
		mode |= (st->st_mode & S_IFLNK) ? ML_S_IFLNK : 0;
		mode |= (st->st_mode & S_IFSOCK) ? ML_S_IFSOCK : 0;
		mode |= (st->st_mode & S_ISUID) ? ML_S_ISUID : 0;
		mode |= (st->st_mode & S_ISGID) ? ML_S_ISGID : 0;
		mode |= (st->st_mode & S_ISVTX) ? ML_S_ISVTX : 0;
		mode |= (st->st_mode & S_IRUSR) ? ML_S_IRUSR : 0;
		mode |= (st->st_mode & S_IWUSR) ? ML_S_IWUSR : 0;
		mode |= (st->st_mode & S_IXUSR) ? ML_S_IXUSR : 0;
		ret[2] = mode;
	}
#endif
}
Beispiel #11
0
Datei: object.c Projekt: hsk/docs
void *
sml_obj_alloc(unsigned int objtype, size_t payload_size)
{
	void *obj;

	ASSERT(((unsigned int)payload_size & OBJ_SIZE_MASK) == payload_size);

	obj = sml_alloc(payload_size, sml_load_frame_pointer());
	OBJ_HEADER(obj) = OBJ_HEADER_WORD(objtype, payload_size);

	ASSERT(OBJ_SIZE(obj) == payload_size);
	ASSERT(OBJ_TYPE(obj) == OBJTYPE_UNBOXED_VECTOR
	       || OBJ_TYPE(obj) == OBJTYPE_BOXED_VECTOR
	       || OBJ_TYPE(obj) == OBJTYPE_UNBOXED_ARRAY
	       || OBJ_TYPE(obj) == OBJTYPE_BOXED_ARRAY);
	ASSERT(OBJ_GC1(obj) == 0 && OBJ_GC2(obj) == 0);

	return obj;
}
Beispiel #12
0
Datei: object.c Projekt: hsk/docs
void *
sml_record_alloc(size_t payload_size)
{
	void *obj;
	size_t bitmap_size;

	ASSERT(((unsigned int)payload_size & OBJ_SIZE_MASK) == payload_size);

	payload_size = ALIGNSIZE(payload_size, sizeof(void*));
	bitmap_size = OBJ_BITMAPS_LEN(payload_size) * SIZEOF_BITMAP;
	obj = sml_alloc(payload_size + bitmap_size, sml_load_frame_pointer());
	OBJ_HEADER(obj) = OBJ_HEADER_WORD(OBJTYPE_RECORD, payload_size);

	ASSERT(OBJ_SIZE(obj) == payload_size);
	ASSERT(OBJ_TYPE(obj) == OBJTYPE_RECORD);
	ASSERT(OBJ_GC1(obj) == 0 && OBJ_GC2(obj) == 0);

	return obj;
}
Beispiel #13
0
/* for debug */
void
sml_heap_dump()
{
	char *cur;
	unsigned int size, allocsize;

	sml_debug("from space : %p - %p\n",
		  HEAP_START(sml_heap_from_space),
		  sml_heap_from_space.limit);

	cur = HEAP_START(sml_heap_from_space);

	while (cur < sml_heap_from_space.free) {
		size = OBJ_TOTAL_SIZE(cur);
		allocsize = HEAP_ROUND_SIZE(size);
		sml_debug("%p : type=%08x, size=%u, total=%u, alloc=%u\n",
			  cur, OBJ_TYPE(cur), OBJ_SIZE(cur), size, allocsize);
		cur += allocsize;
	}
}
Beispiel #14
0
void *
sml_obj_alloc(unsigned int objtype, size_t payload_size)
{
	void *obj;

	assert(sml_saved());
	assert(((unsigned int)payload_size & OBJ_SIZE_MASK) == payload_size);

	obj = sml_alloc(payload_size);
	OBJ_HEADER(obj) = OBJ_HEADER_WORD(objtype, payload_size);

	assert(OBJ_SIZE(obj) == payload_size);
	assert(OBJ_TYPE(obj) == OBJTYPE_UNBOXED_VECTOR
	       || OBJ_TYPE(obj) == OBJTYPE_BOXED_VECTOR
	       || OBJ_TYPE(obj) == OBJTYPE_UNBOXED_ARRAY
	       || OBJ_TYPE(obj) == OBJTYPE_BOXED_ARRAY
	       || OBJ_TYPE(obj) == OBJTYPE_INTINF);

	return obj;
}
Beispiel #15
0
static int finalizer_cmp(void *, void *);
static sml_tree_t finalizer_set =
	SML_TREE_INITIALIZER(finalizer_cmp, xmalloc, free);
static struct finalizer *active_finalizers;

static void *
persistent_node_alloc(size_t size)
{
	return sml_obstack_alloc(&persistent_node_obstack, size);
}

static void
dump_malloc(void *item, void *data ATTR_UNUSED)
{
	sml_notice("%p (flags=%08x, size=%lu)", item,
		   MALLOC_HEAD(item)->flags, (unsigned long)OBJ_SIZE(item));
}

static void
dump_finalizer(void *item, void *data ATTR_UNUSED)
{
	struct finalizer *final = item;
	sml_notice("active=%d, obj=%p, fn=%p",
		   final->active, final->obj, final->finalizer);
}

static void
dump_callback(void *item, void *data ATTR_UNUSED)
{
	struct callback_item *cls = item;
	while (cls) {
Beispiel #16
0
int
prim_GenericOS_poll(int *fdary, unsigned int *evary, int timeout_sec,
		    int timeout_usec)
{
#if (defined(HAVE_CONFIG_H) && defined(HAVE_SELECT)) || !defined(MINGW32) || !defined(HAVE_CONFIG_H)
	fd_set infds, outfds, prifds;
	struct timeval timeout;
	unsigned int i;
	int nfds, err;

	/* FIXME: untested */
	ASSERT(OBJ_TYPE(fdary) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_TYPE(evary) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_SIZE(fdary) == OBJ_SIZE(evary));

	FD_ZERO(&infds);
	FD_ZERO(&outfds);
	FD_ZERO(&prifds);
	nfds = 0;

	for (i = 0; i < OBJ_SIZE(fdary) / sizeof(int); i++) {
		int fd = ((int*)fdary)[i], setfd = 0;
		unsigned int ev = ((unsigned int*)evary)[i];
		if (ev & SML_POLLIN) {
			setfd = fd;
			FD_SET(fd, &infds);
		}
		if (ev & SML_POLLOUT) {
			setfd = fd;
			FD_SET(fd, &outfds);
		}
		if (ev & SML_POLLPRI) {
			setfd = fd;
			FD_SET(fd, &prifds);
		}
		nfds = (nfds > setfd) ? nfds : setfd;
	}
	nfds++;

	if (timeout_sec < 0 || timeout_usec < 0) {
		err = select(nfds, &infds, &outfds, &prifds, NULL);
	} else {
		timeout.tv_sec = timeout_sec;
		timeout.tv_usec = timeout_usec;
		err = select(nfds, &infds, &outfds, &prifds, &timeout);
	}

	if (err < 0)
		return err;

	for (i = 0; i < OBJ_SIZE(evary) / sizeof(unsigned int); i++) {
		unsigned int ev = 0;
		if (!FD_ISSET(((int*)fdary)[i], &infds))
			ev |= SML_POLLIN;
		if (!FD_ISSET(((int*)fdary)[i], &outfds))
			ev |= SML_POLLOUT;
		if (!FD_ISSET(((int*)fdary)[i], &prifds))
			ev |= SML_POLLPRI;
		((unsigned int*)evary)[i] = ev;
	}
	return err;

#elif defined(HAVE_POLL)
	struct pollfd *fds;
	nfds_t nfds, i;
	int err;

	/* FIXME: untested */
	ASSERT(OBJ_TYPE(fdary) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_TYPE(evary) == OBJTYPE_UNBOXED_ARRAY);
	ASSERT(OBJ_SIZE(fdary) == OBJ_SIZE(evary));

	nfds = OBJ_SIZE(fdary) / sizeof(int);
	fds = xmalloc(nfds * sizeof(struct pollfd));

	for (i = 0; i < nfds; i++) {
		unsigned int ev = ((unsigned int*)evary)[i];
		fds[i].fd = ((int*)fdary)[i];
		fds[i].events = 0;
		if (ev & SML_POLLIN)
			fds[i].events |= POLLIN;
		if (ev & SML_POLLOUT)
			fds[i].events |= POLLOUT;
		if (ev & SML_POLLPRI)
			fds[i].events |= POLLPRI;
	}

	if (timeout_sec < 0 || timeout_usec < 0) {
		err = poll(fds, nfds, -1);
	} else {
		/* ToDo: overflow check is needed? */
		int timeout = timeout_sec * 1000 + timeout_usec / 1000;
		err = poll(fds, nfds, timeout);
	}

	if (err < 0)
		return err;

	for (i = 0; i < nfds; i++) {
		unsigned int ev = 0;
		if (fds[i].revents & POLLIN)
			ev |= SML_POLLIN;
		if (fds[i].revents & POLLOUT)
			ev |= SML_POLLOUT;
		if (fds[i].revents & POLLPRI)
			ev |= SML_POLLPRI;
		((unsigned int*)evary)[i] = ev;
	}
	return err;

#else
	errno = EIO;
	return -1;
#endif /* HAVE_SELECT | HAVE_POLL */
}
Beispiel #17
0
SML_PRIMITIVE int
sml_obj_equal(void *obj1, void *obj2)
{
	unsigned int i, tag;
	unsigned int *bitmap1, *bitmap2;
	void **p1, **p2;

	if (obj1 == obj2)
		return 1;

	if (obj1 == NULL || obj2 == NULL)
		return 0;

	if (OBJ_SIZE(obj1) != OBJ_SIZE(obj2))
		return 0;

	if (OBJ_TYPE(obj1) != OBJ_TYPE(obj2)) {
		if (OBJ_TYPE(obj1) == OBJTYPE_RECORD) {
			void *tmp = obj1;
			obj1 = obj2, obj2 = tmp;
		}
		else if (OBJ_TYPE(obj2) != OBJTYPE_RECORD)
			return 0;
		if (OBJ_TYPE(obj1) == OBJTYPE_UNBOXED_VECTOR)
			tag = TAG_UNBOXED;
		else if (OBJ_TYPE(obj1) == OBJTYPE_BOXED_VECTOR)
			tag = TAG_BOXED;
		else
			return 0;

		assert(OBJ_SIZE(obj2) % sizeof(void*) == 0);
		bitmap2 = OBJ_BITMAP(obj2);
		for (i = 0; i < OBJ_SIZE(obj2) / sizeof(void*); i++) {
			if (BITMAP_BIT(bitmap2, i) != tag)
				return 0;
		}
	}

	switch (OBJ_TYPE(obj1)) {
	case OBJTYPE_UNBOXED_ARRAY:
	case OBJTYPE_BOXED_ARRAY:
		return 0;

	case OBJTYPE_UNBOXED_VECTOR:
		return memcmp(obj1, obj2, OBJ_SIZE(obj1)) == 0;

	case OBJTYPE_BOXED_VECTOR:
		p1 = obj1;
		p2 = obj2;
		assert(OBJ_SIZE(obj1) % sizeof(void*) == 0);
		for (i = 0; i < OBJ_SIZE(obj1) / sizeof(void*); i++) {
			if (!sml_obj_equal(p1[i], p2[i]))
				return 0;
		}
		return 1;

	case OBJTYPE_INTINF:
		return sml_intinf_cmp((sml_intinf_t*)obj1,
				      (sml_intinf_t*)obj2) == 0;

	case OBJTYPE_RECORD:
		bitmap1 = OBJ_BITMAP(obj1);
		bitmap2 = OBJ_BITMAP(obj2);
		p1 = obj1;
		p2 = obj2;

		assert(OBJ_NUM_BITMAPS(obj1) == OBJ_NUM_BITMAPS(obj2));
		assert(OBJ_SIZE(obj1) % sizeof(void*) == 0);

		for (i = 0; i < OBJ_NUM_BITMAPS(obj1); i++) {
			if (bitmap1[i] != bitmap2[i])
				return 0;
		}
		for (i = 0; i < OBJ_SIZE(obj1) / sizeof(void*); i++) {
			if (BITMAP_BIT(bitmap1, i) == TAG_UNBOXED) {
				if (p1[i] != p2[i])
					return 0;
			} else {
				if (!sml_obj_equal(p1[i], p2[i]))
					return 0;
			}
		}
		return 1;

	default:
		sml_fatal(0, "BUG: invalid object type : %d", OBJ_TYPE(obj1));
	}
}
Beispiel #18
0
int main()
{
	irqInit();
	SetMode((LCDC_BITS)(MODE_1 | BG0_ON | BG2_ON | OBJ_ENABLE));
	
	irqSet(IRQ_VBLANK, vblank);
	irqEnable(IRQ_VBLANK);
	
	float xpos = 0;
	float ypos = 0;
	
	float xdir = 0;
	float ydir = 0;
	int dir = 0;
	
	BG_COLORS[0] = RGB5(31, 0, 31);
	CpuFastSet(tileset_img, OBJ_BASE_ADR, COPY32 | (256 * 16) / 4);
	CpuFastSet(tileset_pal, OBJ_COLORS, COPY32 | (256 / 4));
	
	CpuFastSet(tileset_img, PATRAM4(0, 0), COPY32 | (256 * 16) / 4);
	CpuFastSet(tileset_pal, BG_COLORS, COPY32 | (256 / 4));
	
	// mock up a map
/*	((vu16*)MAP_BASE_ADR(MAP_BASE_BLOCK))[0] = 0;
	((vu16*)MAP_BASE_ADR(MAP_BASE_BLOCK))[1] = 1;
	((vu16*)MAP_BASE_ADR(MAP_BASE_BLOCK))[32] = 32;
	((vu16*)MAP_BASE_ADR(MAP_BASE_BLOCK))[33] = 33;
	((vu16*)MAP_BASE_ADR(MAP_BASE_BLOCK))[64] = 64;
	((vu16*)MAP_BASE_ADR(MAP_BASE_BLOCK))[65] = 65; */
	
	for (int y = 0; y < 32; ++y)
	{
		for (int x = 0; x < 32; ++x)
		{
			((vu16*)MAP_BASE_ADR(MAP_BASE_BLOCK + 1))[x + y * 32] = 5;
		}
	}
	for (int x = 0; x < 32; ++x) ((vu8*)MAP_BASE_ADR(MAP_BASE_BLOCK + 1))[x] = 16;
	for (int x = 0; x < 32; ++x) ((vu8*)MAP_BASE_ADR(MAP_BASE_BLOCK + 1))[31 * 32 + x] = 16;
	for (int y = 0; y < 32; ++y) ((vu8*)MAP_BASE_ADR(MAP_BASE_BLOCK + 1))[y * 32] = 16;
	for (int y = 0; y < 32; ++y) ((vu8*)MAP_BASE_ADR(MAP_BASE_BLOCK + 1))[y * 32 + 31] = 16;
	
	BGCTRL[0] = SCREEN_BASE(MAP_BASE_BLOCK + 0) | CHAR_BASE(0) | BG_SIZE_0 | BG_16_COLOR | BG_PRIORITY(1); // | CHAR_PALETTE(1);
	BGCTRL[2] = SCREEN_BASE(MAP_BASE_BLOCK + 1) | CHAR_BASE(0) | BG_SIZE_1 | BG_16_COLOR | BG_PRIORITY(0); // | CHAR_PALETTE(1);
	
	float rot = 0.0f;
	float last_rot = rot;
	float bg_scroll = 0;
	
	int frame = 0;
	while (1)
	{
		int sprite_frame = (int(floor(bg_scroll)) >> 3) & 1;
		if (fabs(xdir) < 1e-1) sprite_frame = 0;
//		if (ypos > 0) sprite_frame = 2;
		int tile_start = sprite_frame * 2;
		int pal = 0;
		
		for (int i = 0; i < 128; ++i)
		{
			sprites[i].attr0 = ATTR0_DISABLED;
		}
		
		int sprite = 0;
//		sprites[sprite].attr0 = OBJ_Y(int(ypos) + 80 - 8) | ATTR0_COLOR_16 | ATTR0_WIDE;
//		sprites[sprite].attr1 = OBJ_X(int(xpos) + 120) | OBJ_SIZE(Sprite_16x8) | (dir ? ATTR1_FLIP_X : 0);
		sprites[sprite].attr0 = OBJ_Y(int(0) + 80 - 16) | ATTR0_COLOR_16 | ATTR0_WIDE;
		sprites[sprite].attr1 = OBJ_X(int(0) + 120 - 8) | OBJ_SIZE(Sprite_16x8) | (dir ? ATTR1_FLIP_X : 0);
		sprites[sprite].attr2 = OBJ_CHAR(tile_start) | ATTR2_PALETTE(pal); // | OBJ_TRANSLUCENT;
		sprite++;

//		sprites[sprite].attr0 = OBJ_Y(int(ypos) + 80)  | ATTR0_COLOR_16 | ATTR0_SQUARE;
//		sprites[sprite].attr1 = OBJ_X(int(xpos) + 120) | OBJ_SIZE(Sprite_16x16) | (dir ? ATTR1_FLIP_X : 0);
		sprites[sprite].attr0 = OBJ_Y(int(0) + 80 - 8)  | ATTR0_COLOR_16 | ATTR0_SQUARE;
		sprites[sprite].attr1 = OBJ_X(int(0) + 120 - 8) | OBJ_SIZE(Sprite_16x16) | (dir ? ATTR1_FLIP_X : 0);
		sprites[sprite].attr2 = OBJ_CHAR(tile_start + 32)   | ATTR2_PALETTE(pal); // | OBJ_TRANSLUCENT;
		sprite++;

		float st = sin(last_rot);
		float ct = cos(last_rot);
		
		last_rot = last_rot + (rot - last_rot) * 0.1;
		
		int pa = int(0x100 * ct);
		int pb =-int(0x100 * st);
		int pc = int(0x100 * st);
		int pd = int(0x100 * ct);
		
		// don't setup any hw-regs until vblank
		VBlankIntrWait();
		
		// setup bg0 scroll
		REG_BG0HOFS = int(bg_scroll) & 0xFFFF;
		
		// setup bg2 transform
		REG_BG2PA = pa;
		REG_BG2PB = pb;
		REG_BG2PC = pc;
		REG_BG2PD = pd;
		REG_BG2X = (int(xpos) << 8) - (pa * 120 + pb * 80);
		REG_BG2Y = (int(ypos) << 8) - (pc * 120 + pd * 80);		
		
		++frame;
		CpuSet(sprites,  OAM, (128 * sizeof(OAM[0])) / 2);
		
		scanKeys();
		u32 held = keysHeld();
		u32 down = keysDown();
		u32 up = keysUp();
		
		float upx =  sin(rot);
		float upy = -cos(rot);
		float leftx =  upy;
		float lefty = -upx;
		
		if (KEY_UP    & down) { xdir = upx * 5; ydir = upy * 5; }
		if (KEY_L     & down) { rot += M_PI / 2; }
		if (KEY_R     & down) { rot -= M_PI / 2; }
/*		if (KEY_L     & up) { rot += M_PI / 4; }
		if (KEY_R     & up) { rot -= M_PI / 4; } */
		
		// external forces
#if 0
		xdir *= 0.95; // friction
		ydir *= 0.95; // friction
#else
		float a = leftx * xdir + lefty * ydir; // dot(dir, left)
		float b = upx   * xdir +   upy * ydir; // dot(dir, up)
		float new_xdir = upx * b + 0.85 * leftx * a;
		float new_ydir = upy * b + 0.85 * lefty * a;
		xdir = new_xdir;
		ydir = new_ydir;
#endif	
		if (fabs(xdir) < 1e-1) xdir = 0;
		if (fabs(ydir) < 1e-1) ydir = 0;
		
		if (KEY_RIGHT & held) { xdir -= leftx * 0.5f; ydir -= lefty * 0.5f; dir = 0; }
		if (KEY_LEFT  & held) { xdir += leftx * 0.5f; ydir += lefty * 0.5f; dir = 1; }
		
		xdir -= upx * 0.25;   // gravity
		ydir -= upy * 0.25;   // gravity
		
		float last_xpos = xpos;
		float last_ypos = ypos;
		
		// apply forces
		xpos += xdir;
		ypos += ydir;
		
		// resolve constraints
		if (xpos < 0)   xpos = 0;
		if (xpos > 255) xpos = 255;
		if (ypos < 0)   ypos = 0;
		if (ypos > 255) ypos = 255;
		
		float delta_xpos = last_xpos - xpos;
		float delta_ypos = last_ypos - ypos;
		
		bg_scroll += (delta_xpos * leftx + delta_ypos * lefty) * 0.5f;
	}
	return 0;
}