How can I layer TIM's and use multiple CLUT's?
-
Administrator Verified
- Admin / PSXDEV
- Posts: 2691
- Joined: Dec 31, 2012
- I am a: Shadow
- PlayStation Model: H2000/5502
How can I layer TIM's and use multiple CLUT's?
How can I layer TIM's like the image below?
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.
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.
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!
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!

-
Administrator Verified
- Admin / PSXDEV
- Posts: 2691
- Joined: Dec 31, 2012
- I am a: Shadow
- PlayStation Model: H2000/5502
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.
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.
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)
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)
Whoops sorry, that's the contrarythe bigger this value is, the nearest from the camera the sprite will be

You can also try like that, it should work :
Code: Select all
GsSortSprite(&tim1, ot, 2);
GsSortSprite(&tim2, ot, 1);
GsSortSprite(&tim3, ot, 0);
-
Administrator Verified
- Admin / PSXDEV
- Posts: 2691
- Joined: Dec 31, 2012
- I am a: Shadow
- PlayStation Model: H2000/5502
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.
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.
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.
Hi Shadow, I'm happy to see that you finally managed to get your code working !
- 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.
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)

That's also the first thing I though while reading your message. I suggest you to :I think my CLUT from the first image is getting used on the second image.
- 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);
}
}

(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)
simple, turn off gawd damm transparency. problem solved.
-
Administrator Verified
- Admin / PSXDEV
- Posts: 2691
- Joined: Dec 31, 2012
- I am a: Shadow
- PlayStation Model: H2000/5502
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
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

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.
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.
Who is online
Users browsing this forum: No registered users and 4 guests