Jump to content
IGNORED

Rush Hour


lucien2

Recommended Posts

Here is my first GCC game: Rush Hour.

http://en.wikipedia.org/wiki/Rush_Hour_(board_game)

 

RUSH_HOUR.zip

 

Only one level at the moment, no sounds.

 

http://www.youtube.com/watch?v=g9Qa_xmiuMU

 

 

#define TOP 0
#define MIDDLE_VERTICAL 1
#define BOTTOM 2
#define LEFT 3
#define MIDDLE_HORIZONTAL 4
#define RIGHT 5

#define UP 0
#define DOWN 2

#define RED_BLOCK_CHARS 128
#define YELLOW_BLOCKS_CHARS 144
#define SELECTED_BLOCK_CHARS 160
#define WALL_CHARS 176

int block_patterns[9][4]= {
{ 0x001F, 0x3F7F, 0x7F7F, 0x7F7F }, // TL
{ 0x00FF, 0xFFFF, 0xFFFF, 0xFFFF }, // TOP
{ 0x00F8, 0xFCFE, 0xFEFE, 0xFEFE }, // TR
{ 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F }, // ML
{ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, // M
{ 0xFEFE, 0xFEFE, 0xFEFE, 0xFEFE }, // MR
{ 0x7F7F, 0x7F7F, 0x7F3F, 0x1F00 }, // BL
{ 0xFFFF, 0xFFFF, 0xFFFF, 0xFF00 }, // BOT
{ 0xFEFE, 0xFEFE, 0xFEFC, 0xF800 }  // BR
};

int wall_patterns[8][4]= {
{ 0xFF80, 0x8080, 0x8080, 0x8081 }, // TL
{ 0xFF00, 0x0000, 0x0000, 0x00FF }, // HORIZ
{ 0xFF01, 0x0101, 0x0101, 0x0181 }, // TR
{ 0x8181, 0x8181, 0x8181, 0x8181 }, // VERT
{ 0x8181, 0x8181, 0x8181, 0x81FF }, // BOT
{ 0xFF81, 0x8181, 0x8181, 0x8181 }, // TOP
{ 0x8101, 0x0101, 0x0101, 0x01FF }, // BR
{ 0x8180, 0x8080, 0x8080, 0x80FF }  // BL
};

int sprite_patterns[8][4]= {
{ 0x1814, 0x1211, 0x1010, 0x1010 }, // BLACK
{ 0x1010, 0x1215, 0x1900, 0x0000 },
{ 0x0000, 0x0000, 0x8040, 0x2010 },
{ 0x0870, 0x4020, 0x2090, 0x9060 },
{ 0x0008, 0x0C0E, 0x0F0F, 0x0F0F }, // WHITE
{ 0x0F0F, 0x0D08, 0x0000, 0x0000 },
{ 0x0000, 0x0000, 0x0080, 0xC0E0 },
{ 0xF080, 0x80C0, 0xC060, 0x6000 }
};

char block_parts[6][9]= {
{ 0,1,2,3,4,5,3,4,5 }, //TOP
{ 3,4,5,3,4,5,3,4,5 }, //MIDDLE_VERTICAL
{ 3,4,5,3,4,5,6,7,8 }, //BOTTOM
{ 0,1,1,3,4,4,6,7,7 }, //LEFT
{ 1,1,1,4,4,4,7,7,7 }, //MIDDLE_HORIZONTAL
{ 1,1,2,4,4,5,7,7,8 }  //RIGHT
};

char blocks[6][6]= {
{  2,  3,  3,  3,  0,  0 },
{  2,  4,  4,  4,  5,  0 },
{  0,  6,  1,  1,  5,  0 },
{  0,  6,  7,  7,  5,  0 },
{  0,  6,  0,  8,  9,  9 },
{ 10, 10, 10,  8,  0,  0 }
};

typedef struct {
char x;
char y;
} point;

point cursor= { 3, 3 };
//int selected_block=0; // GCC bug, "unrocognizable insn"
char selected_block=0;

void show_parts(int type,char color,int x,int y) {
//******** GCC BUG: with FOR loop,
//******** compiler error: in gen_low_part_general, at rtlhooks.c:59
/*int i=0;
int x2,y2;
char c;
for(y2=y;y2<=y+2;y2++) {
	for(x2=x;x2<=x+2;x2++) {
		c=block_parts[type][i]+color;
		vdp_copy_from_sys((y2+3)*32+x2+7,&c,1);
		i++;
	}
}*/

int i=0;
int x2=x;
int y2=y;
char c;
do {
	do {
		c=block_parts[type][i]+color;
		vdp_copy_from_sys((y2+3)*32+x2+7,&c,1);
		i++;
		x2++;
	} while(x2<=x+2);
	x2=x;
	y2++;
} while(y2<=y+2);
}

void show_space(int x,int y) {
int x2=x;
int y2=y;
char c;
do {
	do {
		c=' ';
		vdp_copy_from_sys((y2+3)*32+x2+7,&c,1);
		x2++;
	} while(x2<=x+2);
	x2=x;
	y2++;
} while(y2<=y+2);	
}

void show_blocks() {
char c,c2,c3;
int x,y,x2,y2;
for(x=0;x<=5;x++) {
	for(y=0;y<=5;y++) {
		c=blocks[y][x];
		if(c) {
			c3=0;
			
			y2=y;
			x2=x-1;
			if(x2>=0)c2=blocks[y2][x2];
			else c2=0;
			if(c2==c)c3=RIGHT;			
			x2=x+1;
			if(x2<=5)c2=blocks[y2][x2];
			else c2=0;
			if(c2==c) {
				if(!c3)c3=LEFT;
				else c3=MIDDLE_HORIZONTAL;
			}
			
			x2=x;			
			y2=y-1;
			if(y2>=0)c2=blocks[y2][x2];
			else c2=0;
			if(c2==c)c3=BOTTOM;
			y2=y+1;
			if(y2<=5)c2=blocks[y2][x2];
			else c2=0;
			if(c2==c) {
				if(!c3)c3=TOP;
				else c3=MIDDLE_VERTICAL;
			}
			
			if(c==selected_block)c2=SELECTED_BLOCK_CHARS;
			else {
				if(c==1)c2=RED_BLOCK_CHARS;
				else c2=YELLOW_BLOCKS_CHARS;
			}
			show_parts(c3,c2,x*3,y*3);
		}
		else show_space(x*3,y*3);
	}
}
}

void show_wall() {
pchar(WALL_CHARS+0,2,6);
hchar(WALL_CHARS+1,2,7,18);
pchar(WALL_CHARS+2,2,25);
vchar(WALL_CHARS+3,3,25,5);
pchar(WALL_CHARS+4,8,25);
pchar(WALL_CHARS+5,12,25);
vchar(WALL_CHARS+3,13,25,;
pchar(WALL_CHARS+6,21,25);
hchar(WALL_CHARS+1,21,7,18);
pchar(WALL_CHARS+7,21,6);
vchar(WALL_CHARS+3,3,6,18);
}

void show_cursor() {
position(0,cursor.y*8*3+4*8,cursor.x*8*3+8*8-1);
position(1,cursor.y*8*3+4*8,cursor.x*8*3+8*8-1);
}

void selection() {
if(selected_block==0)selected_block=blocks[cursor.y][cursor.x];
else selected_block=0;
show_blocks();
}

void endgame() {
}

int move_block(char dx,char dy) {
int x=cursor.x; int y=cursor.y;
char c=selected_block;
int ret=0;
x+=dx; y+=dy;
if(x==6 && y==2) {
	if(c==1) {
		endgame();
		ret=1;
	}
}
else {
	if(blocks[y][x]==c || blocks[y][x]==0) {			
		int xfront=x;
		int yfront=y;
		int xtail=cursor.x;
		int ytail=cursor.y;
		
		if(dx) {
			while(blocks[yfront][xfront]==c && xfront<5 && xfront>0)xfront+=dx;
			while(blocks[ytail][xtail]==c && xtail<5 && xtail>0)xtail-=dx;
		}
		else {
			while(blocks[yfront][xfront]==c && yfront<5 && yfront>0)yfront+=dy;
			while(blocks[ytail][xtail]==c && ytail<5 && ytail>0)ytail-=dy;
		}
		if(blocks[ytail][xtail]!=c) { xtail+=dx; ytail+=dy; }
		if(blocks[yfront][xfront]==0) {
			blocks[yfront][xfront]=c;
			blocks[ytail][xtail]=0;
			ret=1;
		}
	}
}
if(ret)show_blocks();
return ret;
}

void move(char dx,char dy) {
//void move(int dx,int dy) { // GCC bug, R2 saved "mov r2,r9", restored "movb r9,r2"
int ok=1;
if(selected_block)ok=move_block(dx,dy);
if(ok) {
	cursor.x+=dx;
	if(cursor.x<0)cursor.x=0;
	if(cursor.x>5)cursor.x=5;
	cursor.y+=dy;
	if(cursor.y<0)cursor.y=0;
	if(cursor.y>5)cursor.y=5;
	show_cursor();
}
}

void main() {
// Test file functions
/*pab p;
if(!open(&p,"DSK1.TEST",OUTPUT)) {
	write(&p,"blabla",6);
	close(&p);
}*/

load_standard_characters();
screen(CYAN);

int i=0;
color(4,BLACK,CYAN);
color(16,DARK_RED,CYAN);
color(17,DARK_RED,CYAN);
for(i=0;i<=8;i++)defchar2(RED_BLOCK_CHARS+i,block_patterns[i]);
color(18,DARK_YELLOW,CYAN);
color(19,DARK_YELLOW,CYAN);
for(i=0;i<=8;i++)defchar2(YELLOW_BLOCKS_CHARS+i,block_patterns[i]);
color(20,MEDIUM_GREEN,CYAN);
color(21,MEDIUM_GREEN,CYAN);
for(i=0;i<=8;i++)defchar2(SELECTED_BLOCK_CHARS+i,block_patterns[i]);	
color(22,DARK_BLUE,LIGHT_BLUE);
for(i=0;i<=7;i++)defchar2(WALL_CHARS+i,wall_patterns[i]);

for(i=0;i<=7;i++)defsprite2(i,sprite_patterns[i]);
sprite(0,0,BLACK);
sprite(1,4,WHITE);
magnify(3);

show_cursor();
show_blocks();
show_wall();

i=0;
char c;
while(1) {
	interrupts();
	if(key_scan(&c)) {
		magnify(3);
		
		switch(c) {
			case 'S':
			case 8:
				move(-1,0);
				break;
			case 9:
			case 'D':
				move(1,0);
				break;
			case 10:
			case 'X':
				move(0,1);
				break;
			case 11:
			//case 'E': GCC bug, too much cases?
				move(0,-1);
				break;
		}
		if(c=='E')move(0,-1);
		if(c==' ')selection();
	}
}
}

 

  • Like 1
Link to comment
Share on other sites

Great job! That's just too darn cool.

 

Unfortunately, I see you've had to put in a lot of effort to work around problems in the compiler. I'm sorry about that. You've also pointed out how badly a library of basic functions is needed (display stuff, keyboard support, file IO, sound), but it may be a while before I have a chance to get to that.

 

First thing's first. Let me see if I can get rid of the problems you've found so far.

Link to comment
Share on other sites

Unfortunately, I see you've had to put in a lot of effort to work around problems in the compiler. I'm sorry about that.

 

That's part of the fun. It's the first time I'm a beta tester.

 

You've also pointed out how badly a library of basic functions is needed (display stuff, keyboard support, file IO, sound), but it may be a while before I have a chance to get to that.

 

I like to start from scratch. I don't have the ambition to make a standard library. For exemple, my file functions only support DV80, because I know I will never need other formats.

Link to comment
Share on other sites

Can you make a .bin cart image so we can run it on Classic99?

You can. It's a standard EA5 file (E/A cartridge, "RUN PROGRAM FILE").

 

Here's your .bin file: cartridge binary for OX.zip

It's not finished yet, don't put it in your gamebase! icon_wink.gif

 

I think I need to increase the gap between the blocks. icon_neutral.gif

 

gap.jpg

Edited by lucien2
Link to comment
Share on other sites

I studied the linker (LD) manual. Now the code loads at >A000 instead of >6000 and it can be run on real hardware. :ponder:

 

Three levels, press (N)ext or (P)revious to switch, (space) to select a block and (ESDX) to move.

Rules: Push the red block to the exit.

 

RUSH_HOUR2.zip

Is this your final version or are you still tweaking it?

Link to comment
Share on other sites

Is this your final version or are you still tweaking it?

 

Not finished.

 

TO DO:

- Scores (moves)

- Highscores and current level saved into a file

- Small animation and sound when a level is finished

- 30 levels (minimum)

- There is still a strange bug when you move a 3-tiles block

Link to comment
Share on other sites

Is this your final version or are you still tweaking it?

 

Not finished.

 

TO DO:

- Scores (moves)

- Highscores and current level saved into a file

- Small animation and sound when a level is finished

- 30 levels (minimum)

- There is still a strange bug when you move a 3-tiles block

Really looking forward to seeing the finished product :)

Link to comment
Share on other sites

TO DO:

- Scores (moves)

- Highscores and current level saved into a file

- Small animation and sound when a level is finished

- 30 levels (minimum)

- There is still a strange bug when you move a 3-tiles block

 

Now, I can call it finished! :)

 

RUSH_HOUR3.zip

Damn! I'm going to have to update the gameshelf site again much sooner than I expected! And the beauty of it is that most of the material I have has been recent projects! I can definitely tell that the TI is currently undergoing a renaissance :) Can I assume that you are OK with your program being posted on the site?

Link to comment
Share on other sites

Can I assume that you are OK with your program being posted on the site?

 

Sure, I would be honored. :)

 

Maybe don't upload the source until the GCC bugs are removed. I don't know if it would be good advertising for GCC.

Great! Is Insomnia the programmer of GCC for the TI?

Link to comment
Share on other sites

  • 6 months later...

Now that the compiler has had a lot of fixes applied, I can replace some of the workarounds with the code which was originally intended, This makes for more compact and much easier to understand code.

 

My intent was just to undo the damage which was forced upon this code by the problems in the compiler. I've also added a rush.dsk disk image (containing an EA5 file named RUSH) to make it easier to try the resulting program.

 

Hopefully this will make lucien feel better about making the source code available.

RUSH_HOUR4.zip

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...