Understanding interlace mode

Graphic based area of development (Graphics Processing Unit), including the Geometry Transform Engine (GTE), TIM, STR (MDEC), etc.
Post Reply
jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Understanding interlace mode

Post by jman » February 10th, 2014, 9:43 am

Hello,

I need some advice about using the interlace mode.
There's a couple things I don't understand, and I'm pretty confused.

Apparently the image viewing in interlace mode is OK, but when I compile in non-interlaced mode I have a problem: the screen stays on colour [50,50,50]; when snooping into the VRAM with no$psx I see the bg is loaded, it just seems that the drawing buffer is never swapped into the display buffer.
- If I use libgs to setup an interlaced screen, f.e. to show a static image, do I need to setup also an ordering table? Do I always need an OT?

What is the problem that prevents the 320x240 bg to be correctly seen?

Attached sample code and BIN file.

Thanks!
You do not have the required permissions to view the files attached to this post.

jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Post by jman » March 1st, 2014, 4:10 am

Not many answers, I see :-)

Find the attached source code: I'm doing a little step back and try to simply simply a 320x240 image. The image is correctly loaded but it never gets on the display buffer, it only stays in the drawing buffer (see no$psx VRAM attachment).

If I understand correctly the workflow in the main loop should be:
- setup the Ordering Table in use
- clear it
- wait for the VSync
- swap display /drawing buffers
- load the image into VRAM
- the next iteration should find the image on the display buffer

The strange thing is that this workflow seems ok if I setup an interlaced screen and load a 640x480 image: it appears correctly on screen.

EDIT: some may object that I'm not loading the TIM into a GsSPRITE object. Is it always necessary to allocate a sprite, even when displaying a background? I'm a bit confused on this point.

thanks
You do not have the required permissions to view the files attached to this post.

User avatar
inc^lightforce
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 248
Joined: Mar 07, 2013
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Location: Germany

Post by inc^lightforce » March 1st, 2014, 4:37 pm

320*240 is a big size. when i want load up a full screen picture, i always must split it in 2 screens. left and right side. in my code the maximum size is always: 256*256
see a example here: (the green pic with the eggs in the background)
http://www.psxdev.net/forum/viewtopic.p ... =272#p1973

defined as Sprite :)

SetSpriteInfo(&sprRig,(u_long)rig,235,121,3);//x,y right
SetSpriteInfo(&sprLef,(u_long)lef,80,119,3);//x,y left

jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Post by jman » March 2nd, 2014, 2:51 am

inc^lightforce wrote:320*240 is a big size. when i want load up a full screen picture, i always must split it in 2 screens. left and right side.
This is ok for me, but I don't understand why I don't need any sprite when loading a interlaced background (see attached source code). I'm just loading the TIM file into the frame buffer.

I hope this isn't one of the quirks due to checking code into an emulator.
You do not have the required permissions to view the files attached to this post.

jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Post by jman » March 2nd, 2014, 4:20 am

I got it, it's because of the TIM file. The 320x240 one is positioned at [320,0], the 640x480 one at [0,0].

If I'm not wrong an interlaced background should be positioned at [0,0] and will cover the display+drawing buffers, thus the buffer swap should be disabled. However if I disable the buffer swap the image is not copied on screen.

In case of a 320x240 file, the correct way is to position it just outside the display buffer at [320,0] then create two sprites and copy them onto the display, one at the time.
You do not have the required permissions to view the files attached to this post.

User avatar
inc^lightforce
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 248
Joined: Mar 07, 2013
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Location: Germany

Post by inc^lightforce » March 2nd, 2014, 5:34 am

damn this TIM is phukin bIG ! :D

i suggest to split ! not loading directly the TIM into the vram

Quote
... then create two sprites and copy them onto the display, one at the time. ...
END Quote


my words

PS. i must test your code. MY reply asap.

later

jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Post by jman » March 4th, 2014, 8:07 am

OK, so basically I have to page the texture image by slicing it in steps of 256 pixels (width), advancing to the next page with GetTPage in steps of 4 (see my previous TIM screengrab).

So a 640x480 needs three pages (an array of GsSPRITE): 256+256+128.

How do I manage height? Do I have to page that too?

Thanks, all these pieces are starting to make sense.

User avatar
Shendo
Verified
C Programming Expert
C Programming Expert
Posts: 250
Joined: Mar 21, 2012
I am a: Programmer
Motto: Never settle
PlayStation Model: SCPH-7502
Discord: ShendoXT
Location: Croatia, EU

Post by Shendo » March 4th, 2014, 9:47 am

jman wrote: If I'm not wrong an interlaced background should be positioned at [0,0] and will cover the display+drawing buffers, thus the buffer swap should be disabled. However if I disable the buffer swap the image is not copied on screen.
No. Interlaced mode behaves exactly the same as progressive but because
of increased resolution you can't use double buffering.

That means you need to have your image data placed outside of the buffer (X > 640).
Or else it will get overwritten when you clear the screen for the new frame.
You will need to split 640x480 to 256x256 sprites to plot it on the screen.

If this is for tapper, you can use 512x480 interlaced mode, it should work fine.

Edit: I went ahead and made an example for you. You can grab the source.
I tested it on emulators, PS1 and PS2 and it seems to be working perfectly.

Image Image Image
You do not have the required permissions to view the files attached to this post.
Dev console: SCPH-7502, FreePSXBoot, CH340 serial cable.

jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Post by jman » March 7th, 2014, 2:39 am

Really helpful code you provided, thanks for your time.
However one detail I don't understand is how texture pages are calculated: I thought that one could use getTPage() using the [x,y] coordinates and have the GPU figure out the tpage number by itself. In your example I would have done:

Code: Select all

getTPage(1, 0, 0, 0) /* upper left */
getTPage(1, 0, 256, 0) /* upper right */
getTPage(1, 0, 256, 256) /* lower right */
getTPage(1, 0, 256, 0) /* lower left */
But clearly this is wrong because I get different values.

I've done some tests with a small 16bit (not 8bit like yours) sprite:

Sprite positioned on [0,0] (error), resulting tpage=256
Sprite positioned on [320,0], resulting tpage=(256+5) = 261 (because 5*64 = 320px)
Sprite positioned on [512,0], resulting tpage= (256+8) = 264 (because 8*64 = 512px)

How do I interpret these figures compared to your tpage calculations?

thanks
Last edited by jman on March 7th, 2014, 5:14 am, edited 1 time in total.

User avatar
Shendo
Verified
C Programming Expert
C Programming Expert
Posts: 250
Joined: Mar 21, 2012
I am a: Programmer
Motto: Never settle
PlayStation Model: SCPH-7502
Discord: ShendoXT
Location: Croatia, EU

Post by Shendo » March 7th, 2014, 4:15 am

Since PSXSDK doesn't include such a function I learned to so it myself. It's pretty easy actually.
I don't know why "GetTPage" gives you those values though... Maybe you are reading it wrong.
Return value is unsigned short according to official docs.

VRAM is divided into 64x256 pixel texture pages, going from
top left (0) to top right right (16) and bottom left (17) to bottom right (32).

To get a texture page you divide X by 64 and Y by 256. So [512, 0] texture is at texture page 8.

One thing to remember is that 8bit images take half as much width as 16bit images
so you can place 128x256 8bit texture into one texture page. You will need to account for that if you are working
with palletized textures.
Dev console: SCPH-7502, FreePSXBoot, CH340 serial cable.

jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Post by jman » March 7th, 2014, 7:39 am

Shendo wrote:I don't know why "GetTPage" gives you those values though... Maybe you are reading it wrong.
Return value is unsigned short according to official docs.
What happens to an unsigned short when it overflows? I suspect that 261 is nothing but 255+6 and not 256+5 as I assumed.
Shendo wrote: VRAM is divided into 64x256 pixel texture pages, going from
top left (0) to top right right (16) and bottom left (17) to bottom right (32).
To get a texture page you divide X by 64 and Y by 256. So [512, 0] texture is at texture page 8.
Yes, I imagined something like that and I like it, it is actually more intuitive.
Shendo wrote: One thing to remember is that 8bit images take half as much width as 16bit images
so you can place 128x256 8bit texture into one texture page. You will need to account for that if you are working
with palletized textures.
I'm experimenting with 8bit images too, it's time to learn how to create them with TIMTOOL :-)

User avatar
Shendo
Verified
C Programming Expert
C Programming Expert
Posts: 250
Joined: Mar 21, 2012
I am a: Programmer
Motto: Never settle
PlayStation Model: SCPH-7502
Discord: ShendoXT
Location: Croatia, EU

Post by Shendo » March 10th, 2014, 5:20 am

jman wrote: What happens to an unsigned short when it overflows? I suspect that 261 is nothing but 255+6 and not 256+5 as I assumed.
Don't know for sure, depends on the hardware. Either it goes to zero or it spills in the next byte in memory.
jman wrote: I'm experimenting with 8bit images too, it's time to learn how to create them with TIMTOOL :-)
Timtool looks nice, I never used it before actually. Currently I'm using bmp2tim from PSXSDK suite which allows me to
set magic pink (255, 0, 255) as transparent with black (0, 0, 0) as not transparent which is a damn fine feature to have.
Dev console: SCPH-7502, FreePSXBoot, CH340 serial cable.

jman
Rookie Programmer
Rookie Programmer
Posts: 110
Joined: Aug 13, 2013

Post by jman » March 18th, 2014, 3:47 am

I've understood how to match the texture page value you're using (8,9,10,...), it's also indicated in TIMTOOL.

Image

In this image one can see that a TIM file with the left upper edge at [0,512] (marker 1 and 3) has texture page = 512 / 64 = 8 (marker 2).

I just don't understand why I can't move that image to [320,0] coordinates. After having re-saved the TIM file on that coordinates, I try to load the 4 tiles with the following tpage indexes:
upper left = 5
upper right = 8
lower left = 21
lower right = 24

but the image is garbled:

Image

I should be allowed to do so, right? As long as my TIM stays out of the display/drawing buffers any coordinate should be ok.

I suspect the reason is that an interlaced screen, 512x480 for example, takes more memory than the usual 5 texture pages (5*64 pixels) of the not interlaced one and overlaps with the TIM file.

Using TIMTOOL for a graphic understanding of the video memory (that's what I like of this tool), let's say I have an interlaced screen of 512x480, so I assume the first 8 pages cannot be used to load TIM files as it is all "stuff" shown on screen. The TIM file shall be placed at least on the 9th texture page (x = 512px).

If I'm right, then in theory I should not be able to load and tilemap a 640 wide image because I don't have enough memory to place it outside of the visible area. And this brings me to what you said:
That means you need to have your image data placed outside of the buffer (X > 640).
timtool.png
garbled.png
You do not have the required permissions to view the files attached to this post.

User avatar
Shendo
Verified
C Programming Expert
C Programming Expert
Posts: 250
Joined: Mar 21, 2012
I am a: Programmer
Motto: Never settle
PlayStation Model: SCPH-7502
Discord: ShendoXT
Location: Croatia, EU

Post by Shendo » March 18th, 2014, 10:05 am

You forgot to set "Frame Buffer Options->Set Graphics Mode" in TimTool.
Look at the second picture in my post with the full VRAM exposed.
You can see that active framebuffer ends at 511 and texture begins at 512 pixels.

As for your other question, use palletized textures. That way a 640x480 image becomes 320x480 in memory.
Dev console: SCPH-7502, FreePSXBoot, CH340 serial cable.

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests