We're using cookies to ensure you get the best experience on our website. More info
Understood
@imaspidermanRegistered August 5, 2012Active 6 years, 6 months ago
107 Replies made

what tool did you use to compse your midi?

I used a program called MuseScore.
http://musescore.org/en

It’s really great. You can just compose the musical notes on a score and it plays it for you. It will also import a midi file into all the different tracks and display all the notes/tracks so you can take an existing one and easily modify it. I also attached my java program source code that converts midi files to VB code for me. It works pretty well for my needs. I designed this to be able to play individual tracks of a midi file and then export those tracks to VB code with relative ease. It’s a console app so no gui but it just has a few options to it. It will also parse a wav file and generate output as well.

bigmak:

Also Ben said he would upload a few minutes of the demo to his youtube account sometime today. I recorded it in mednafen and there is a graphics glitch that doesn’t seem to appear on the actual VB. The first few writes to the frame buffer don’t seem to take in mednafen for some reason.

  • This reply was modified 11 years, 8 months ago by Greg Stevens.
  • This reply was modified 11 years, 8 months ago by Greg Stevens.

As far as sound the answer is yes and no. I ended up abandoning trying to use wav data and just composed a midi file using Musescore. I wrote a simple midi file parser using java and used it to calculate the interrupt timing I needed to play my song on the VB with a 20 microsecond timer. Ben has been my tester and although I was happy with getting a wav file to play the midi file makes it much easier to perform other code while the music is playing. Ben said he thought it would be a better experience anyway comparing it to your Game Hero game so I switched it up.

Thanks a bunch for the source code it helped me to quickly change my philosophy.

I’m not going to pretend to be an expert on compiler options but I reproduced the error you were getting and seemed to have worked around it by setting the optimization flags manually. Here is my gcc command with all the flags that would normally be set using -O (minus the ones that weren’t supported by this version). The following is what I now have in my makefile for the VBDE and I was able to compile the program I’ve been working on without getting those errors.

All the flag information I got from

http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

v810-gcc.exe -Wall -fomit-frame-pointer -funit-at-a-time -ftree-ter -ftree-sra -ftree-fre -ftree-dse -ftree-copyrename -ftree-dominator-opts -ftree-ch -ftree-builtin-call-dce -fsplit-wide-types -fmerge-constants -fmerge-constants -fipa-reference -fipa-pure-const -fif-conversion -fif-conversion2 -fguess-branch-probability -fdse -fdefer-pop -fdce -fcprop-registers -fauto-inc-dec -Xassembler -a=game.lst -nodefaultlibs -mv810 -Tc:/vbde/gccvb/v810/lib/vb.ld -xc -o game.o game.c

Finally made the switch to the new vbde. All of a sudden all of my interrupt code that wasn’t working now works. You have no idea how much frustration this just saved me. Great job!

Sorry I wasn’t clear about that. I tried defining a memory buffer so
u32 buff[0x1800];
I tried writing to that and then moving that buffer all at once to the actual frame buffers (using bit string move). It is the above buffer that I clear not the VB frame buffers.
(It was just an experiment to see if writing all my information once and then copying it using bit string moves was more efficient that writing the individual pixels to each buffer). Like I said it seemed to improve a little but not so noticibly that it is going to be a solution for me. I’ve acutally already undone that code.

I have not explored unrolling my loops yet so that’s probably something I’ll try next.

Thanks.

I’ve been messing around some more and I seem to have been able to squeeze out a little better speed by using Bit String operations for buffer copies and clears instead of loops but still noting compared to Red Alarm.

drawPoint is defined as an inline function yes and it calls no other functions. abs() is the C version so it’s not my function. I’m not an expert on C so I’m not sure if it inlines it or not and I haven’t checked the disassembly to be sure but I would have to think that GCC would do that automatically.

This was the cleanest concise one I could find. I’m also using Fixed point Arithmetic so that’s what the F_NUM_DN is just a (x>>7)

	
	/**************************
	The following algorithm was taken from stack overflow
	http://stackoverflow.com/questions/5186939/algorithm-for-drawing-a-4-connected-line
	**************************/
	dx=abs(vx2-vx);
	dy=abs(vy2-vy);
	
	sx = (vxp)>>PARALLAX_SHIFT));
		e1=e+dy;
		e2=e-dx;
		if(abs(e1)
        
    

Very nice. I was able to use the OBJ file to test a process I’ve been working on to import models into homebrew roms. The VB isn’t quite up to the task of moving an object around with such a high polygon count. I was able to display the model in a test rom though… just at a frame rate of about 1 every 10 seconds. Anyway great job, it was nice to have a model done by someone who looks like they know what they are doing.

I’ll check out the double lines. I didn’t notice them but I wouldn’t be surprised. I’m not using exact calculations since I’m using only integer math. I have allowed some error into the routines to hopefully give better speed throughout the whole rendering process. I’m shooting for good, fast, and fun not necessesarily perfect and polished. I’ve tried to use division very sparingly and use right shifts instead. This is very fast but forces you to round up anything that would have been between 1 and 0 so there is some error there for sure. I’m also experimenting with a clipping routine that doesn’t use division so that is actually probably causing the double lines as it hits the minimum z value. As for the coordinates I store them in a simple signed int array. I’m currently using triangles only and the coordinates are stored in counter-clockwise fashion to allow for dot and cross product calculations that I may implement later on. Each coordinate is just an offset from a “center” or “root” point. That point is the center for all rotations and transformations. I’m using a left handed system so the z axis increases as it goes into the screen or away from you. My Y axis is currently inverted so it increases going down (I’ll have to change that at some point) and the x axis is normal increasing from left to right.
Here is the actual array. I only store the coordinates here. The other couple variable are currently stored in a struct that has a pointer to this data.

#define STARFOXSHIPDATASIZE 9*22
/***********************************************
All triangles need to be drawn counter-clockwise
based on looking at them from the front.
(Very Important) or culling won't work right
************************************************/
const s32 starFoxShipData[STARFOXSHIPDATASIZE]={
	/************************
	Nose of ship 4 triangles
	************************/
	0,-5,10, -5,-2,10, 0,-2,40,
	0,-5,10, 5,-2,10, 0,-2,40,
	-5,-2,10, 0,-2,40, 0,0,10,
	5,-2,10, 0,0,10, 0,-2,40, 
	/*************************
	Cockpit 12 triangles (6 squares)
	*************************/
	0,-5,10, -5,-2,10, -5,-2,0,
	0,-5,10, -5,-2,0, 0,-5,0,
	
	-5,-2,10, 0,0,0, -5,-2,0, 
	-5,-2,10, 0,0,10, 0,0,0, 
	
	0,-5,10, 0,-5,0, 5,-2,0,
	0,-5,10, 5,-2,0, 5,-2,10,
	
	0,0,10, 5,-2,0, 0,0,0, 
	0,0,10, 5,-2,10, 5,-2,0,
	
	0,-5,0, -5,-2,0, 0,-2,0,
	-5,-2,0, 0,0,0, 0,-2,0,
	0,0,0, 5,-2,0, 0,-2,0,
	5,-2,0, 0,-5,0, 0,-2,0,
	/***********************
	left wing 3 triangles
	***********************/
	-5,-2,10, -40,-2,-10, -5,-2,0,//top
	-8,-2,10, -8,-2,0, -8,-10,-10,//left side
	-8,-2,0, -8,-2,10, -8,10,-10,//left side
	/***********************
	right wing 3 triangles
	***********************/
	5,-2,10, 40,-2,-10, 5,-2,0,//top
	8,-2,10, 8,-2,0, 8,-10,-10, //left side
	8,-2,0, 8,-2,10, 8,10,-10,  //left side
};

Here is the Arwing able to be rotated around all 3 axis. Just use the left D-Pad for the Z and X axis and the right D-Pad for the Y.

This uses transformation matrices for all rotations.
I think it’s a pretty good start. I still have a lot to learn though.
Wishing I paid better attention in math class when I was younger…

Attachments:

Well, not that anybody probably cares but I solved my Z axis issue. I just needed a few extra temp variables because I was clobbering some values before I acutally needed them. So I can now rotate my objects around all 3 axis. Next I need to rotate an object around an arbitrary vector and I should be done with my rotation matrix code. I’m going to bed….

No, infact it might make it worse but like I said I was also doing it just to learn Assembly. Since my code isn’t complete yet I’m not even sure I’m going to keep the assembly in it if I don’t really notice any speed differences but I haven’t benchmarked anything yet so I can’t be sure. And actually it doesn’t really handle near plane culling. I just simply don’t draw the line if the z value of either end is less than the projection plane z value because it produces some really funky results. Same with the X and Y values but I commented those out and am not currently using that code. I did notice that the virtual boy automatically wraps coordinates to the other side of the screen if they go outside the screen bounds. Maybe there is an obvious reason as to why but I thought it would only do that for BGMaps and Worlds if the OVR[something] flag was set. So if any object goes off the right side of the screen it automatically appears on the left hand side without having to do any special coding. I’m actually going to have to do coding to remove that “feature” if I can’t find a flag or register that is causing that to happen.

I think my main problem was trying to get fancy with the line drawing algorithm. I found what the author purported to be “the fastest line algorithm in the world” and attempted to port it to VB.

While I’m not ready to release all of my code yet, I think the algorithm I’m using is pretty solid for line drawing.

Here it is. I’ve used Assembly to try and optimize it (and learn ASM) but I left the original C code in place and just commented it.

This function also performs the projection calculation for x and y based on the z coordinate before drawing the line.

vector3d is just a typedef
typedef struct{
s32 x;
s32 y;
s32 z;
}vector3d

and p is parallax value which I use in my drawpoint function to offset the left and right screen buffers.

/*******************************
Bresenham Line Algorithm
*******************************/
void drawLine(vector3d v1, vector3d v2, u8 color, s16 p){
	if(v1.z1 || x1>(EYE_X+(SCREEN_WIDTH>>1))) return;
	if(y1<(EYE_Y-(SCREEN_HEIGHT>>1)) || y1>(EYE_Y+(SCREEN_HEIGHT>>1))) return;
	if(x2<(EYE_X-(SCREEN_WIDTH>>1)) || x2>(EYE_X+(SCREEN_WIDTH>>1))) return;
	if(y2<(EYE_Y-(SCREEN_HEIGHT>>1)) || y2>(EYE_Y+(SCREEN_HEIGHT>>1))) return;
	*/
	/**************************
	The following algorithm was taken from stack overflow
	http://stackoverflow.com/questions/5186939/algorithm-for-drawing-a-4-connected-line
	**************************/
	//dx=abs(x2-x1);
	//dy=abs(y2-y1);
	asm(
		"mov %2,r5\n" //x1
		"mov %3,r6\n" //x2
		"mov %4,r7\n" //y1
		"mov %5,r8\n" //y2
		"sub r6,r5\n"
		"bge _next1\n"
		"not r5,r5\n"
		"add 1,r5\n"
		"_next1:\n"
		"mov r5,%0\n"
		"sub r8,r7\n"
		"bge _next2\n"
		"not r7,r7\n"
		"add 1,r7\n"
		"_next2:\n"
		"mov r7,%1\n"
		:"=r"(dx),"=r"(dy)
		:"r"(v1.x),"r"(v2.x),"r"(v1.y),"r"(v2.y)
		:"r5","r6","r7","r8"
		);
	
	//sx = (x1

So when I rotate around the X and Y axis everything looks great. But no matter what I try the Z axis doesn’t work right. I’m still messing around so hopefully something will jump out at me.

Yea it’s handling the signs correctly. I was really hoping that was my issue. It’s weird when I rotate my object to the right, so around the z axis it works great until I hit about 45 degrees. Then every line collapses into a straight line and then as you continue to rotate everything straightens itself out. I’m sure it’s something stupid I’m doing but I just haven’t seen it yet.

Thanks for all the advice. I am aware of the transformation and rotation matrices and I am trying to implement them in my code. So far I have partial success. My challenges are that I’m trying to do everything with integer math so no floats and I’m also trying to use division quite sparingly since it’s an expensive operation. I am aware of fixed point integers which is basically what I’m implementing. For division I’m trying to adjust my values so every divide is just a power of 2 and I can shift it. I’m pretty sure that the compiler I’m using is not doing an arithmetic shift when I use >> and I just need to fix that. I’ll probably just use assembly for that routine since the SAR command should work just fine. I’m still learning and appreciate all the links. Thanks guys.

Long story short yes I do plan on making a game. I’ve never actually made a game before and as many of the programmers here know it’s not something you just go and do on a weekend especially with 0 prior experience. I want my first game to use wireframe graphics and while I’ve never made a game before, I’m no amateur when it comes to programming since I do it for a living so I thought I could attempt to bite off a little more than perhaps a newbie to coding would attempt. I only have a few things left to learn/figure out before I can start on a game. While I can make a wire frame model and move it around in 3d space, I still need the routine to actually rotate the object around the 3 axis. I also need a collision detection algorithm and then I should be set. When I’m done I plan on releasing all my code since other programmers who have never attempted this before will probably benefit from a quick jump start. Since I’ve never coded in C before my code is simple and easy to understand by anybody who knows anything about C. I’m not breaking any new ground here, for example the Hunter source code available on this site has an extremely more advanced 3d engine for designing a game. But if I can use an analogy, sometimes you just need a Ford Escort to get you from point A to point B and not a Corvette. I’m going for the Escort and some simple functions that anybody can just add in to their code and create 3d wireframe graphics. It’s not going to be a full engine just a couple functions to handle the graphics and display.

blitter, thanks for the advice. Mednafen definitly made a difference. Turns out I had it right at one point but reality boy lead me astray. I uncommented those two lines and I also ended up using

void screenControl(){
	VIP_REGS[XPCTRL] = VIP_REGS[XPSTTS] | XPEN;
	while(!(VIP_REGS[INTPND] & XPEND));
	VIP_REGS[XPCTRL] = VIP_REGS[XPSTTS] & XPENOFF;//Disable drawing	
}

I had a line in to clear the XPEND
VIP_REGS[INTCLR] = XPEND

that I took out since it still caused some minor ficker.

I was beginning to think that may have been part of the problem after reading that everyone seemed to be testing on Mednafen. I’ll get that installed and try it out. I’ve just become used to reality boys debug mode which I’ve used for the few translation patches so I continued using it.

  1. x1-EYE_X)*EYE_Z)/(EYE_Z+z1) + EYE_X; x2 = ((x2-EYE_X)*EYE_Z)/(EYE_Z+z2) + EYE_X; y1 = ((y1-EYE_Y)*EYE_Z)/(EYE_Z+z1) + EYE_Y; y2 = ((y2-EYE_Y)*EYE_Z)/(EYE_Z+z2) + EYE_Y; */ //x1 and x2 asm( "mov %2,r5\n" //EYE_X "mov %3,r6\n" //EYE_Z "mov %4,r7\n" //x1 "mov %5,r8\n" //z1 "mov %6,r9\n" //x2 "mov %7,r10\n" //z2 "sub r5,r7\n" //x1-EYE_X "sub r5,r9\n" //x2-EYE_X "add r6,r8\n" //EYE_Z+z1 "add r6,r10\n" //EYE_Z+z2 "mul r6,r7\n" //(x1-EYE_X)*EYE_Z "div r8,r7\n" // /(EYE_Z+z1) "add r5,r7\n" // +EYE_X "mov r7,%0\n" "mul r6,r9\n" //(x2-EYE_X)*EYE_Z "div r10,r9\n" // /(EYE_Z+z2) "add r5,r9\n" // +EYE_X "mov r9,%1\n" :"=r"(v1.x),"=r"(v2.x) :"r"(EYE_X),"r"(EYE_Z),"r"(v1.x), "r"(v1.z),"r"(v2.x),"r"(v2.z) ); //y1 and y2 asm( "mov %2,r5\n" //EYE_Y "mov %3,r6\n" //EYE_Z "mov %4,r7\n" //y1 "mov %5,r8\n" //z1 "mov %6,r9\n" //y2 "mov %7,r10\n" //z2 "sub r5,r7\n" //y1-EYE_Y "sub r5,r9\n" //y2-EYE_Y "add r6,r8\n" //EYE_Z+z1 "add r6,r10\n" //EYE_Z+z2 "mul r6,r7\n" //(y1-EYE_Y)*EYE_Z "div r8,r7\n" // /(EYE_Z+z1) "add r5,r7\n" // +EYE_Y "mov r7,%0\n" "mul r6,r9\n" //(y2-EYE_Y)*EYE_Z "div r10,r9\n" // /(EYE_Z+z2) "add r5,r9\n" // +EYE_Y "mov r9,%1\n" :"=r"(v1.y),"=r"(v2.y) :"r"(EYE_Y),"r"(EYE_Z),"r"(v1.y), "r"(v1.z),"r"(v2.y),"r"(v2.z) ); /* if(x1<(EYE_X-(SCREEN_WIDTH>>1 []