How can I layer TIM's and use multiple CLUT's?

Graphic based area of development (Graphics Processing Unit), including the Geometry Transform Engine (GTE), TIM, STR (MDEC), etc.
Post Reply
User avatar
Shadow
Admin / PSXDEV
Admin / PSXDEV
Posts: 2459
Joined: December 31st, 2012, 5:37 pm
PlayStation Model: H2000/5502

How can I layer TIM's and use multiple CLUT's?

Post by Shadow » July 21st, 2012, 11:05 pm

How can I layer TIM's like the image below?
Image
tim_layering.png
Thanks
You do not have the required permissions to view the files attached to this post.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

Mdrb
Curious PSXDEV User
Curious PSXDEV User
Posts: 15
Joined: July 18th, 2012, 9:43 pm

Re: How can I layer TIM's?

Post by Mdrb » July 29th, 2012, 11:45 am

Well I think it depends of the way you display these TIMs on screen.

If your TIMs are smaller than 256*256px, the easiest way is, in my opinion, to use a GsSPRITE structure and display them by calling the GsSortSprite function. The third parameter is its position in the ordering table, and if I'm remember well, the bigger this value is, the nearest from the camera the sprite will be (a kind of z-index).
Also note that the order in which the different calls to GsSortSprite are made doesn't affect the result. So calling GsSortSprite(&spr1, ot, 8); and then GsSortSprite(&spr2, ot, 4); will display spr2 below spr1.

Another way could be to use MoveImage(), but that's a bit more complicated because it's a non-blocking function, so you need to call DrawSync (or use DrawSyncCallback) after each MoveImage call to wait the drawing function ends (well, that's what the libref46.pdf say, I haven't tried yet).

I hope this may help you! :P

User avatar
Shadow
Admin / PSXDEV
Admin / PSXDEV
Posts: 2459
Joined: December 31st, 2012, 5:37 pm
PlayStation Model: H2000/5502

Re: How can I layer TIM's?

Post by Shadow » July 29th, 2012, 2:36 pm

Hmm... I just tried and it did not work.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

isufje
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 64
Joined: April 11th, 2012, 2:33 pm

Re: How can I layer TIM's?

Post by isufje » July 30th, 2012, 2:22 am

No, it does work.

GsSortSprite(&tim3, ot, 0);
GsSortSprite(&tim2, ot, 0);
GsSortSprite(&tim1, ot, 0);

^works. tim3 gets drawn on top. tim2 gets drawn down one. tim1 gets drawn down one more. (That's the way i do it anyway)

Mdrb
Curious PSXDEV User
Curious PSXDEV User
Posts: 15
Joined: July 18th, 2012, 9:43 pm

Re: How can I layer TIM's?

Post by Mdrb » July 30th, 2012, 7:13 am

the bigger this value is, the nearest from the camera the sprite will be
Whoops sorry, that's the contrary :oops:

You can also try like that, it should work :

Code: Select all

GsSortSprite(&tim1, ot, 2);
GsSortSprite(&tim2, ot, 1);
GsSortSprite(&tim3, ot, 0);
The GPU will draw tim1 in first since its priority in ot is the highest, then tim2 (which will recover tim1), and finaly tim3 (which will recover tim2 and tim1).

User avatar
Shadow
Admin / PSXDEV
Admin / PSXDEV
Posts: 2459
Joined: December 31st, 2012, 5:37 pm
PlayStation Model: H2000/5502

Re: How can I layer TIM's?

Post by Shadow » September 4th, 2012, 8:44 pm

Okay, I finally got around to fixing my code up and it works fantastically. Thank you mdrb and isufje!

A problem I am having now is that the colours of the image on top of the other image seems to be inverted.
IE: blue becomes black, white becomes green, green becomes yellow, and so on.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

Mdrb
Curious PSXDEV User
Curious PSXDEV User
Posts: 15
Joined: July 18th, 2012, 9:43 pm

Re: How can I layer TIM's and use multiple CLUT's?

Post by Mdrb » September 7th, 2012, 1:29 am

Hi Shadow, I'm happy to see that you finally managed to get your code working ! :clap
I think my CLUT from the first image is getting used on the second image.
That's also the first thing I though while reading your message. I suggest you to :
- try with some 16bit TIMs, just to be sure this is really a CLUT problem
- edit the CLUT position of your TIMs in the framebuffer memory with TimTool (it looks like a line of colored pixels). Be sure there's no CLUT overriding.
- modify the function you use to load the TIM files (eg: specifying an argument to TRUE if your loading function have to load the CLUT of the TIM (no need to load the CLUT of all your TIMs files if they share the same color palette) .

Here is a function I use to load TIMs located in memory. It's extracted from my files, so it may probably not work as is (I've commented the debug function and added some comments). Maybe it may inspired you to write your own.

Code: Select all

/* This is a header value stored at the beginning at the TIM file */
#define TIM_HEADER 0x00000010

/**
 * Transfer a TIM file from main memory to the video frame buffer.
 *
 * @param addr_tim Pointer to the TIM in memory
 * @param img_info Pointer to a GsIMAGE structure in which the image informations will be stored
 */
void
tim_load_from_mem(u_long *addr_tim, GsIMAGE *img_info)
{
	/* Position in the framebuffer where the image will be loaded */
	RECT 	img_rect;

	/* Checks the header of the file, to be sure it's a TIM file */
	if (*addr_tim != TIM_HEADER)
	{
		// debug_printf(DEBUG_LOG, "error: not a tim file");
		return;
	}

	// debug_printf(DEBUG_LOG, "loading tim from mem");

	/* Skip this header */
	addr_tim++;

	/* Extract the image info from the TIM file */
	GsGetTimInfo(addr_tim, img_info);

	/* Set the position rect in the framebuffer */
	img_rect.x = img_info->px;
	img_rect.y = img_info->py;
	img_rect.w = img_info->pw;
	img_rect.h = img_info->ph;

	/* Transfer the pixels of the image in the framebuffer */
	LoadImage(&img_rect, img_info->pixel);
	
	/* LoadImage is a non blocking function, so we need to vait the loadng finished */
	DrawSync(0);
	
	// debug_printf(DEBUG_LOG, "pmode: %lu", img_info->pmode);

	/* If a CLUT exists in the TIM, transfer it in VRAM */
/*
16bits: pmode=2,  0010b
 8bits: pmode=9,  1001b
 4bits: pmode=8, 1000b
Only 8 et 4 bits uses a CLUT.
*/

	if ((img_info->pmode >> 3) & 0x1)
	{
		// debug_printf(DEBUG_LOG, "loading tim clut");

		img_rect.x = img_info->cx;
		img_rect.y = img_info->cy;
		img_rect.w = img_info->cw;
		img_rect.h = img_info->ch;

		LoadImage(&img_rect, img_info->clut);
		DrawSync(0);
	}
}
Good luck ;)

(If I've understood well, a CLUT looks like a 16bits image of 256*1px, where each pixel defines a palette entry, so loading a clut is similar to loading an image)

isufje
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 64
Joined: April 11th, 2012, 2:33 pm

Re: How can I layer TIM's and use multiple CLUT's?

Post by isufje » September 7th, 2012, 1:22 pm

simple, turn off gawd damm transparency. problem solved.

User avatar
Shadow
Admin / PSXDEV
Admin / PSXDEV
Posts: 2459
Joined: December 31st, 2012, 5:37 pm
PlayStation Model: H2000/5502

Re: How can I layer TIM's and use multiple CLUT's?

Post by Shadow » September 7th, 2012, 4:24 pm

Nope. Not a transparency issue.

When I ran my program, the animation would cycle through, and at the top of the image there was some flickering. I had just ignored it all this time. The problem was that it was the CLUT being drawn. So, there were tiny pixels and then a huge black line drawn across the top. I loaded the TIM into TIMTOOL, and noticed it was being draw in first buffer. So, I moved it over a few hundred pixels, and it was gone (I also had to change the logic in my code to compensate for the adjustment). The next problem was that the layered image was no longer being drawn, or, the screen would go crazy. This was because the CLUT I just moved over was mixing with the second image. In the end, I got it all working fine. It was just because I mixed all the images CLUT's together :naughty
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests