Adventures Of Lolo

Use this forum to share and discuss Uzebox games and demos.
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Adventures Of Lolo

Post by D3thAdd3r »

Being able to dump some non-level/enemy tiles out of the limited indices in anyway would negate any worries I have really. You are saying a horizontal side bar is definitely possible, and a vertical HUD like mode 3 currently has might be possible? That would be exceptional news! If horizontal, that saves me from simplifying the powerups display. The vertical HUD like mode 3 would certainly be handy too, for the particulars of this game I don't see a way it can help on the border(because Lolo needs to be able to walk up into a door in the border...unless the level is complete as soon as the treasure is collected like at least 1 version I've seen). For title screens/etc it makes sense, but again with 80 unique ram tiles it's a lot easier to fit that kind of stuff entirely into ram. With only ~40 ram tiles it sometimes took hours trying to design the best possible balance just for simple screens :shock: Yeah, I'm pretty excited about seeing what can be made out of that!

Having the ram tile stuff implemented officially in the kernel would cause it to get used much more. Kind of like a "game amplifier" we'd see the difference afforded in the upcoming games.
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Adventures Of Lolo

Post by uze6666 »

You are saying a horizontal side bar is definitely possible, and a vertical HUD like mode 3 currently has might be possible? That would be exceptional news! If horizontal, that saves me from simplifying the powerups display. The vertical HUD like mode 3 would certainly be handy too
Just to be sure, what I'm proposing is an overlay section like mode 3 that can be either at the top or at the right of the main section. You could have both, that starts to get messy and is a better candidate for a custom mode. If you really need one, I can help on that.
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Adventures Of Lolo

Post by D3thAdd3r »

Thought I would show a couple .GIFs of some story fragments I made to give an idea what the movie items will look like. There is more in the works but too WIP to make much sense right now. So far it works smooth enough in the emulator and I see nothing wrong with the approach. I started this stuff when I had a brief Lolo rebirth and moved to SD. Those images were based and highly modified or created from pieces of scenes from different lolo scenes, and the amount of work was horrible. Now, with ~80 ram tiles I can essentially just put unedited screen grabs in and they work for most things :x So the quality should be better than originally planned, the only issue is now some of the color changing things I planned may have to work a different way. Loading 80 ram tiles now instead of 40 is just fine of course since its the same amount of bytes in Mode 13!
33.gif
33.gif (17.2 KiB) Viewed 6677 times
44.gif
44.gif (41.79 KiB) Viewed 6681 times
88.gif
88.gif (6.38 KiB) Viewed 6678 times
3.gif
3.gif (18.93 KiB) Viewed 6682 times
22.gif
22.gif (27.66 KiB) Viewed 6683 times
I need to re-investigate some things still. I recall drawing radically different frames back to back(like zooming in view of mad Lolo) could have issues. I am using a system(similar to that used in the AE animated Uzebox logo) where it only loads ram tile data within certain indices. The images are designed so that even small movements still reside in certain ram tiles so you can get away with only updating ~1k of data instead of the entire vram and ram tiles buffers. More to come, I will get some work done on more core graphics things like level graphics sets.
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Adventures Of Lolo

Post by uze6666 »

The size of the movie frame is bigger than what I expected...impressive! :D
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Adventures Of Lolo

Post by D3thAdd3r »

I started playing through Lolo 3 again and found there really are some levels that are tricky. Instead of quitting and trying again later like in Lolo 1 or Lolo 2, I just walk out of the building and move over to another one to see if I can get something some levels done there. That way you can try some different levels before you need to beat the one that has you scratching your head. A really nice feature and I think I will try to implement it to make the game more enjoyable to a broader audience. The reason this is quite interesting, is it would probably be useful in making an overworld like SMB3/World have. Basically move around on the overworld, when you overlap some building of interest it loads a screen where it shows a closeup and you can walk in.
underworld.png
underworld.png (10.35 KiB) Viewed 6617 times
door1.png
door1.png (5.68 KiB) Viewed 6608 times
tower.png
tower.png (10.47 KiB) Viewed 6608 times
Several of them will need some simplifications because they rely heavily on horizontal mirroring. Some of them already easily fit in the ram tiles and allow for a small Lolo sprite to move around. No technical unknowns to conquer on it though, just a matter of doing it. It's cool because it is not technically difficult, it's pretty much just a matter of artistic effort that would allow a LOT of content to be packed into Uzebox games.
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Adventures Of Lolo

Post by D3thAdd3r »

Ok I experimented with the best way to implement "user ram tiles" as has been kicked around several years. This solution should work for anyone and anything, since really the kernel can only be expected to stay out of your way but not actually help you do these radical non-generic things. It might seem curious to put user ram tiles at the end of available ram tiles, but I think it works better this way. You basically specify the first ram tile that is reserved and sprites will honor it and use an available free tile to make a copy of it first.

Needs this new asm routine added in videoMode3core.s:

Code: Select all

;***********************************
; COPY RAM TILE
; C-callable
; r24=src ram tile index
; r22=dst ram tile index
;***********************************
CopyRamTile:
	ldi r18,TILE_HEIGHT*TILE_WIDTH

	;compute source adress
	ldi ZL,lo8(ram_tiles)
	ldi ZH,hi8(ram_tiles)
	mul r24,r18
	add ZL,r0
	adc ZH,r1

	;compute destination adress
	ldi XL,lo8(ram_tiles)
	ldi XH,hi8(ram_tiles)
	mul r22,r18
	add XL,r0
	adc XH,r1

	;copy data (fastest possible)
.rept TILE_HEIGHT*TILE_WIDTH
	ld r0,Z+	
	st X+,r0
.endr

	clr r1;***is this needed??******
	ret
And videoMode3.c needs this added/replaced:

Code: Select all

unsigned char reserved_ram_tiles_count;
extern void CopyRamTile(unsigned char src, unsigned char dst);

void ProcessSprites(){
	
	unsigned char i,bx,by,dx,dy,bt,x,y,tx=1,ty=1,wx,wy;
	unsigned int ramPtr,ssx,ssy;

	free_tile_index=0;
	if(!reserved_ram_tiles_count)
		reserved_ram_tiles_count = RAM_TILES_COUNT;

	if(!spritesOn) return;
	
	for(i=0;i<MAX_SPRITES;i++){
		bx=sprites[i].x;

		if(bx==(SCREEN_TILES_H*TILE_WIDTH))
			continue;	
				
		//get tile's screen section offsets
				
	#if SCROLLING == 1
		ssx=sprites[i].x+Screen.scrollX;
		ssy=sprites[i].y+Screen.scrollY;
   	#else
		ssx=sprites[i].x;
		ssy=sprites[i].y;
	#endif

		tx=1;
		ty=1;

		//get the BG tiles that are overlapped by the sprite
		bx=ssx>>3;
		dx=ssx&0x7;
		if(dx>0)
			tx++;

		by=ssy/TILE_HEIGHT;
		dy=ssy%TILE_HEIGHT;
		if(dy>0)
			ty++;			

		for(y=0;y<ty;y++){

			for(x=0;x<tx;x++){
				wy=by+y;
				wx=bx+x;

				//if( (wx-(Screen.scrollX/8))>0 ) {

					//process X-Y wrapping
		#if SCROLLING == 0
			if(wy>=(VRAM_TILES_V*2)){
				wy-=(VRAM_TILES_V*2);
			}else if(wy>=VRAM_TILES_V){
				wy-=VRAM_TILES_V;
			}
		#else
			if(wy>=(Screen.scrollHeight*2)){
			    wy-=(Screen.scrollHeight*2);
			}else if(wy>=Screen.scrollHeight){
				wy-=Screen.scrollHeight;
			}
		#endif
			if(wx>=VRAM_TILES_H)
				wx-=VRAM_TILES_H; //should always be 32

		#if SCROLLING == 0
			ramPtr=(wy*VRAM_TILES_H)+wx;
		#else
			ramPtr=((wy>>3)*256)+(wx*8)+(wy&7);	
		#endif

			bt=vram[ramPtr];

			if(((bt>=RAM_TILES_COUNT) ||(bt>=reserved_ram_tiles_count)) && (free_tile_index < reserved_ram_tiles_count)){

				//tile is mapped to flash. Copy it to next free RAM tile.
				//if no ram free ignore tile
				ram_tiles_restore[free_tile_index].addr=ramPtr;
				ram_tiles_restore[free_tile_index].tileIndex=bt;
				
				if(bt>=RAM_TILES_COUNT)//tile is mapped to flash. Copy it to next free RAM tile.		
					CopyTileToRam(bt,free_tile_index);
				else//RAM tile is reserved. Copy it to next free RAM tile to avoid corrupting it.
					CopyRamTile(bt,free_tile_index);

				vram[ramPtr]=free_tile_index;
				bt=free_tile_index++;									
			
			}

			if(bt<reserved_ram_tiles_count)
				BlitSprite(i,bt,(y<<8)+x,(dy<<8)+dx);

			}//end for X
		}//end for Y
	}//end for Sprites


	//restore BG tiles
	RestoreBackground();

}
This simple program works and a rom of it has been attached. You essentially have free reign over all ram tiles from 20 to RAM_TILES_COUNT in this example.

Code: Select all

const char testsprites[] PROGMEM = {
255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,

0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
};

extern unsigned char reserved_ram_tiles_count;

void main(){

	SetSpritesTileBank(0,testsprites);
	uint8_t spr_xdir[3],spr_ydir[3];

	reserved_ram_tiles_count = 20;//****

	for(unsigned int i=0;i<VRAM_SIZE;i++){//make some ram tile stripes
		vram[i++] = 20;
		vram[i] = 21;
	}

	for(unsigned int i=21*64;i<22*64;i++)//make ram tiles 21 look different than 20
		ram_tiles[i] = 129;

	sprites[0].x = sprites[0].y = sprites[1].y = 38;//setup some sprites moving
	sprites[1].x = 108;
	sprites[1].tileIndex = 1;
	sprites[2].y = 188;
	sprites[2].x = 9;
	spr_ydir[2] = 1;
	spr_xdir[1] = 1;

	WaitVsync(1);

	while(1){

		for(uint16_t i=20*64;i<21*64;i++){//cycle colors a bit
			ram_tiles[i]++;
			ram_tiles[i+64]--;
		}

		for(uint8_t j=0;j<3;j++){
			if(spr_xdir[j]){
				if(++sprites[j].x > (SCREEN_TILES_H*TILE_WIDTH)-8){
					sprites[j].x-= 2;
					spr_xdir[j] = 0;
				}
			}else{
				if(sprites[j].x== 0)
					spr_xdir[j]= 1;
				else
					sprites[j].x--;
			}

			if(spr_ydir[j]){
				if(++sprites[j].y > (SCREEN_TILES_V*TILE_HEIGHT)-8){
					sprites[j].y-= 2;
					spr_ydir[j] = 0;
				}
			}else{
				if(sprites[j].y== 0)
					spr_ydir[j]= 1;
				else
					sprites[j].y--;
			}
		}//for j

		WaitVsync(1);
	}
}
Also might as well eliminate this single instruction from CopyTileToRam while the file is open:

Code: Select all

CopyTileToRam:
	ldi r18,TILE_HEIGHT*TILE_WIDTH

	;compute source adress
	lds ZL,tile_table_lo
	lds ZH,tile_table_hi
	;andi r24,0x7f
	subi r24,RAM_TILES_COUNT
	mul r24,r18
	add ZL,r0
	adc ZH,r1

	;compute destination adress
	ldi XL,lo8(ram_tiles)
	ldi XH,hi8(ram_tiles)
	mul r22,r18
	add XL,r0
	adc XH,r1

	clr r0;***********not needed**************
	;copy data (fastest possible)
.rept TILE_HEIGHT*TILE_WIDTH
	lpm r0,Z+	
	st X+,r0
.endr


	clr r1
	ret
Let me know any thoughts, suggestions, or concerns.

Edit-added remaining part of CopyRamTile code. If you are prone to epilepsy please don't run this rom!!
Attachments
lolo.hex
(25.5 KiB) Downloaded 374 times
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Adventures Of Lolo

Post by uze6666 »

So you had this code all this time? Oh well, seems I wasted some time then. :( I re-implemented more or less the same thing this weekendhttp://uzebox.org/forums/viewtopic.php?p=15752#p15752. I had done this years ago but lost it somehow. Back then I did it with the reserved tiles at the end too. But it seems my user code was less clean and complicated like this, so I put them at the beginning. But now that I think of it, it doesn't make much difference. :|
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Adventures Of Lolo

Post by D3thAdd3r »

Fail on my part. I haven't been keeping up with all the rapid happenings as well as I'd like to lately so I implemented that last night without realizing you had :roll: At least it wasn't much of a time waste since, like you, I had already played with that in the past years and always came up with the same general solution in the end. Majority of my experiments end up in the bit bucket pretty quick if I don't make use of them, but the ideas stick around.

If the current solution does the same thing then there is no point in worrying about it. I'm assuming the ram cost is 1 extra byte? Brings me to the point that it might be worth it to have something like:

Code: Select all

#define SOUND_ENABLED		1
#define SPRITES_ENABLED		2
#define SNES_MOUSE_ENABLED	4

unsigned char kernel_flags; 
//bool snesMouseEnabled;
//bool sound_enabled
//bool spritesOn
At least it doesn't seem many people are using those much in the code I see to spend an extra ~1/32th of a ram tile :lol:
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Adventures Of Lolo

Post by uze6666 »

f the current solution does the same thing then there is no point in worrying about it. I'm assuming the ram cost is 1 extra byte? Brings me to the point that it might be worth it to have something like:
CODE: SELECT ALL
#define SOUND_ENABLED 1
#define SPRITES_ENABLED 2
#define SNES_MOUSE_ENABLED 4

unsigned char kernel_flags;
//bool snesMouseEnabled;
//bool sound_enabled
//bool spritesOn

At least it doesn't seem many people are using those much in the code I see to spend an extra ~1/32th of a ram tile :lol:
The ram cost is 2 bytes in fact. It's probably overkill now that I rethink of it, but it was to buffer the user entry. If he happens to callSetUserRamTiles between the vsync bliter and the rendering , it could screw the frame.

For the flags thing, I did that treatment to the sound engine a while ago. It's probably worth a global pass.
Post Reply