Jump to content

Flipped Sprite Issues


Recommended Posts

Hi Guys,


I am getting back to playing with JagStudio, and I am having some issues when setting is_flipped on a sprite.  Not sure if this is user error, a *nuance* of the Jag hardware, or perhaps an issue in the API.


What I am trying to do is create a scrolling background layer.  My idea is simply to use a single sprite ( 1024x256 BMP, 24bpp ), and alternate between the flipped and non-flipped version to create a seamless, scrolling layer with a single texture.

Currently it is working, but I have two problems

  1. The flipped texture is corrupted, as if the pixels are being shifted vertically in a non-uniform fashion.
  2. The API documentation indicates the flipped sprite will have its x-coordinate offset by the width of the texture.  But if this was the case, I would expect that if I have both instances of this sprite at the same origin, they would be displayed exactly next to each other.  If there was no offset on the x-axis, I would expect that I would need to set the x position of the 2nd instance to be the x position of the first instance plus the width of the sprite to achieve the same result.  However, neither of these seems to actually be true.  To achieve this expected result, I have to set the x-coordinate of the 2nd sprite by 176 ( random number achieved by trial and error )

Here is a screenshot of the current result - the right side of the screen is the original sprite, the left side of the screen is the mirrored, "flipped" sprite.


Attaching the source so anyone interested can examine.


Any input appreciated!


Link to comment
Share on other sites

First up, this will completely drain all your bandwidth and you'll be lucky to get anything else working doing it like this.


You would be better off making one long image that wraps correctly, and using GWDIDTH to truncate the image to 352 pixels wide - that way the OP isn't strugging to draw 2048x224 (regardless of what the screensize is).


Now, what I suspect is actually happening here (for an explanation)



your sprite is 1024 wide.

the second one is 1024 wide.

when its flipped it will have an xpos of 2048 (raptor adds the width to X when mirrored)

if you add *anything* to that, it'll wrap the range the x-pos can be with whatever the 'overflow' bits are.


What you are doing is not a crazy idea, and it would indeed work with an image not so wide, but for the reasons stated at the top I *do not recommend this* and would look at GWIDTH.


Set GWID to the screen width

Set DWID to the image width

move the x-pos from 0 to -16

when its at -16, reset it back to 0 and add (for 16bpp) 32 bytes to the GFX Base address

repeat until the wrap point, then reset the base address to the top of the bitmap.

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Thank you both for the valuable feedback.


I guess I've been spoiled by getting used to deferred, tile-based renderers where you don't have to worry about overdraw outside of the screen's boundaries.  So, good callout regarding the performance problems that having such large sprites will have.


I've implemented the solution you have advised, based on Sporadics example:

rapinit.s relevant attributes:

    dc.l    368                                ; sprite_width                    ; width of sprite (in pixels)
    dc.l    256                                ; sprite_height                    ; height of sprite (in pixels)
    dc.l    368*256*2                     ; sprite_framesz                ; size per frame in bytes of sprite data
    dc.l    368*2                            ; sprite_bytewid                ; width in bytes of one line of sprite data

    dc.l    1024*2                           ; sprite_gwidth                    ; GFX width (of data)
main.c relevant code:

backgroundHandler(short backgroundScrollX, int backgroundGfx) {
    sprite[background1].x -= (1<<16);
    if(sprite[background1].x < -15<<16){
        backgroundScrollX += 64;        
        sprite[background1].gfxbase = backgroundGfx +backgroundScrollX;
        sprite[background1].x = 0<<16;
    return backgroundScrollX;


However, this only partially solves the problem.  My main motivation for wanting to alternate between the normal and mirrored image, is to save on storage / memory footprint.

So, I am still having problems when using the is_flipped parameter, even when cutting the large texture into two halves ( 512x256 ) to avoid the range overflow - the displayed image is still corrupted as displayed in my original post. 

is_flipped - notice the zig-zag pattern on the mountain slope, this is not being displayed correctly


is_normal - displayed correctly

I dont recall seeing this issue before when using smaller sprites, so I'm not sure if its because I am using a 24 bit bitmaps?  Which brings up another question, my source texture is a 24bpp bitmap.  However, looking at the build log, this appears to be converted to a 16bit image?
    Reading assets.txt line
        Processing ASSETS\GFX\00001.bmp
        Converting BMP internally into gfxdata...
        File is 512 pixels wide, 256 pixels high and is 16 bits/pixel
        Adding in RAM...

Which is fine, but the part that confuses me is to get things displayed correctly, I have to configure the attributes in a way that seems like a hybrid between these bit depths - I have to specify 24 as the actual bit depth, but when setting the size I have to multiply by 2 which to me means 16bppp, and not 3 which I would expect for 24bpp. 

    dc.l    24                                ; (BIT DEPTH)                    ; bitmap depth (1/2/4/8/16/24)
    dc.l    is_RGB                            ; (CRY/RGB)                        ; bitmap GFX type
    dc.l    is_opaque                        ; (TRANSPARENCY)                ; bitmap TRANS flag
    dc.l    368*256*2                            ; sprite_framesz                ; size per frame in bytes of sprite data
    dc.l    368*2                            ; sprite_bytewid                ; width in bytes of one line of sprite data
    dc.l    512*2                            ; sprite_gwidth                    ; GFX width (of data)


Edited by OVERRiDE
Link to comment
Share on other sites

I think that :

- the picture is really converted in 16-bit

- in your object list, you specify a 24-bpp bitmap

- the video mode is in 16-bpp


The whole of these make it print properly in "not flipped" mode as all 16-bit pixel will be written back in correct order in the linebuffer : (PIXx = 16-bpp)

[PIX1,PIX2] [PIX3,PIX4] ....


But, in flipped mode, 32-bit (as 24-bpp is in fact 32-bpp) data are written back into the linebuffer making 2 consecutive 16bpp written back into the linebuffer : this will shown as one colonne on two to be "reverted" making those artifacts :


instead of the proper :



To resolve the problem, I think that you just need to set the bitmap as 16-bpp (and eventually correct sizes values)



On the Jaguar, you can't have 24-bpp bitmap in 16-bit mode, (and 16-bpp bitmap in 24-bpp mode)

The parameter is in VMODE register.




  • Like 4
  • Thanks 1
Link to comment
Share on other sites

Thanks for the input again guys.  @SCPCD that sounds like a logical explanation for what I am seeing.


I've gotten a solid grasp of the basics, JagStudio really does make many things very easy to implement, so thanks again to all of you who have contributed!




But all that said, I am not understanding how to get 16-bit images correctly loaded?  Are there any examples that demonstrate true 16bit textures?  8 bit takes the entire CLUT which leaves no room for other assets.  Even using FFMPEG to produce 16-bit RGB565 BMP as input, I can not get these to display properly.

@CyranoJ You are saying that 24bit images are too much for the Jag?  I thought the Jag could handle 64-bit graphics 🙂



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.

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.

  • Recently Browsing   0 members

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