// libvb.h
// standard library for GCC-VB dev
// based off Alberto Covarrubias's VECC standard lib

#ifndef _VECC_H_
#define _VECC_H_


//standard type definitions
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;

typedef signed char s8;
typedef signed short s16;
typedef signed long s32;

typedef unsigned char BYTE;
typedef unsigned short HWORD;
typedef unsigned long WORD;


//definitions
u16* WORLD		= (u16*)0x0003D800;
u16* COLUMN		= (u16*)0x0003DC00;
u16* OBJECT		= (u16*)0x0003E000;

u16* VIP_REGS	= (u16*)0x0005F800;

#define INTPND	0x00
#define INTENB	0x01
#define INTCLR	0x02

#define DPSTTS	0x10
#define DPCTRL	0x11
#define BRTA	0x12
#define BRTB	0x13
#define BRTC	0x14
#define REST	0x15

#define FRMCYC	0x17
#define CTA		0x18

#define XPSTTS	0x20
#define XPCTRL	0x21
#define VER		0x22

#define SPT0	0x24
#define SPT1	0x25
#define SPT2	0x26
#define SPT3	0x27

#define GPLT0	0x30
#define GPLT1	0x31
#define GPLT2	0x32
#define GPLT3	0x33
#define JPLT0	0x34
#define JPLT1	0x35
#define JPLT2	0x36
#define JPLT3	0x37
#define BKCOL	0x38

/* vbSetWorld header flags */
/* (OR these together to build a World Header) */

#define	WRLD_LON	0x8000
#define	WRLD_RON	0x4000
#define	WRLD_BGMAP	0x0000
#define	WRLD_HBIAS	0x1000
#define	WRLD_AFFINE	0x2000
#define	WRLD_OBJ	0x3000

#define	WRLD_1x1	0x0000
#define	WRLD_1x2	0x0100
#define	WRLD_1x4	0x0200
#define	WRLD_1x8	0x0300
#define	WRLD_2x1	0x0400
#define	WRLD_2x2	0x0500
#define	WRLD_2x4	0x0600
#define	WRLD_4x2	0x0900
#define	WRLD_4x1	0x0800
#define	WRLD_8x1	0x0C00

#define	WRLD_OVR	0x0080
#define	WRLD_END	0x0040

static u8 colTable[128] = {
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe0, 0xbc,
	0xa6, 0x96, 0x8a, 0x82, 0x7a, 0x74, 0x6e, 0x6a,
	0x66, 0x62, 0x60, 0x5c, 0x5a, 0x58, 0x56, 0x54,
	0x52, 0x50, 0x50, 0x4e, 0x4c, 0x4c, 0x4a, 0x4a,
	0x48, 0x48, 0x46, 0x46, 0x46, 0x44, 0x44, 0x44,
	0x42, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3c,
	0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
	0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c
};

//functions

void vbSetColTable() {
	int i;

	for (i = 0; i < 128; i++) {
		COLUMN[i] = colTable[i];
		COLUMN[i+0x0080] = colTable[127-i];
		COLUMN[i+0x0100] = colTable[i];
		COLUMN[i+0x0180] = colTable[127-i];
	}
}

void vbWaitFrame(int count) {
	int i = 0,tmp;

	for (i = 0; i <= count; i++) {
		tmp = VIP_REGS[XPSTTS];
		while (tmp == VIP_REGS[XPSTTS]);
	}
}

/* Macros for world manipulation */
#define WORLD_HEAD(n,head)      *(HWORD*)WORLD[n]=head
#define WORLD_GSET(n,gx,gp,gy)  *(HWORD*)(WORLD[n]+2)=gx;\
                                *(HWORD*)(WORLD[n]+4)=gp;\
                                *(HWORD*)(WORLD[n]+6)=gy;
#define WORLD_MSET(n,mx,mp,my)  *(HWORD*)(WORLD[n]+8)=mx;\
                                *(HWORD*)(WORLD[n]+10)=mp;\
                                *(HWORD*)(WORLD[n]+12)=my;
#define WORLD_SIZE(n,w,h)       *(HWORD*)(WORLD[n]+14)=w;\
                                *(HWORD*)(WORLD[n]+16)=h;

void vbSetWorld(int nw, u16 header, u16 gx, u16 gp, u16 gy, u16 mx, u16 mp, u16 my, u16 width, u16 height) {
	u16 tmp = (nw<<5)>>1;

	WORLD[tmp++] = header;
	WORLD[tmp++] = gx;
	WORLD[tmp++] = gp;
	WORLD[tmp++] = gy;
	WORLD[tmp++] = mx;
	WORLD[tmp++] = mp;
	WORLD[tmp++] = my;
	WORLD[tmp++] = width;
	WORLD[tmp] = height;
}

void vbDisplayOn() {
	VIP_REGS[REST] = 0;
	VIP_REGS[XPCTRL] = VIP_REGS[XPSTTS]|2;
	VIP_REGS[DPCTRL] = VIP_REGS[DPSTTS]|0x0302;
	VIP_REGS[FRMCYC] = 0;
	VIP_REGS[INTCLR] = VIP_REGS[INTPND];
	while (!(VIP_REGS[DPSTTS]&0x3C));  //required?
}

void vbFXFadeIn() {
	int i;

	for (i = 0; i <= 20; i++) {
		vbWaitFrame(15);
		VIP_REGS[BRTA] = i;
		VIP_REGS[BRTB] = i*2;
		VIP_REGS[BRTC] = i*3;
	}
}

void copymem(u8* dest, const u8* src, int num) {
	int i;
	for (i = 0; i < num; i++)
		dest[i] = src[i];
}

#endif
