Jo Engine Forum

Sega Saturn Development => General Jo Engine Help => Topic started by: FranMatsusaka on January 19, 2022, 10:50:41 am

Title: TGA 8-bit in background
Post by: FranMatsusaka on January 19, 2022, 10:50:41 am
Hi,

I'm doing a Resident Evil like game, with 3d characters moving on a prerendered backgound, and I'm finding memory out problems.
I've seen that 8bit sprite is implemented and working, but I couldn't find a way to load TGA 8bit background. I've seen that there's a jo_img_8bits object type, and a jo_set_background_8bits_sprite, but I couldn't find a 8bit version of jo_tga_loader function. How can I load a 8bit TGA into a jo_img_8bits object?

Thanks in advance.

(https://i.ibb.co/L5RKN2p/bridget-b.png) (https://ibb.co/L5RKN2p)
Title: Re: TGA 8-bit in background
Post by: ponut64 on January 21, 2022, 11:07:40 pm
Check the "demo - vdp2 plane".

While not exactly what you want, it does demonstrate the process of loading an indexed color targa file to a VDP2 background layer.
You could copy this structure entirely, and simply not rotate the background layer.
Title: Re: TGA 8-bit in background
Post by: FranMatsusaka on January 22, 2022, 06:03:39 pm
Check the "demo - vdp2 plane".

While not exactly what you want, it does demonstrate the process of loading an indexed color targa file to a VDP2 background layer.
You could copy this structure entirely, and simply not rotate the background layer.

Thank you very much! I fell a little silly because I couldn't find that jo_set_background_8bits_sprite by myself... Anyway, I have removed old code and substituted by all 8bit versions. I have not worked properly on the palette yet, but besides that it looks like there's some kind of corruption.

Here's the old code commented and the new:
Code: [Select]
        //jo_img  bg;
        //bg.data = NULL;
        //jo_tga_loader(&bg, "BGO", image_to_load, JO_COLOR_Transparent);
        //if (bg.data != NULL) {
            //jo_set_background_sprite(&bg, 0, 0);
            //jo_free_img(&bg);
        //}
       
        jo_img_8bits bg;
        bg.data = NULL;
        jo_tga_8bits_loader(&bg, "BG8", image_to_load, JO_COLOR_Transparent);
       
        if (bg.data != NULL) {
            jo_set_background_8bits_sprite(&bg, 0, false);
            jo_free_img(&bg);
        }

And here's te result... it looks like the tiles are displayed with some extra offset. Also, it looks like the tiles are 90ยบ rotated
(https://i.ibb.co/92W8MZn/tga8bit.png) (https://ibb.co/92W8MZn)

This is the original TGA in case anybody wants to check
https://drive.google.com/file/d/1qvcGEQqIViJUClh37X4_T9KCrY5eNPUk/view?usp=sharing
Title: Re: TGA 8-bit in background
Post by: FranMatsusaka on January 22, 2022, 09:20:25 pm
Palette fixed:

(https://i.ibb.co/9YQTQF0/tga8bit.png) (https://ibb.co/9YQTQF0)
Title: Re: TGA 8-bit in background
Post by: FranMatsusaka on January 23, 2022, 06:50:03 pm
I was able to "fix" it by making few changes in the library. It seems it was storing cells/tiles and map indexes horizontally. I don't know if this was done like this because of mode7 plane . If anybody want's to load 8bit tgas in the background, you will need to make small hacks/changes in __jo_create_map and jo_img_to_vdp2_cells in vdp2.c

Though, this could potentially break something else...

Code: [Select]
void                            jo_img_to_vdp2_cells(const jo_img_8bits * const img, const bool vertical_flip, unsigned char *cell)
{
    register int                x;
    register int                y;
    register int                cell_x;
    register int                cell_y;
    register int                line_y;
    register int                i;


#ifdef JO_DEBUG
        if (img == JO_NULL)
        {
            jo_core_error("img is null");
            return ;
        }
        if (JO_MOD_POW2(img->width, 8) != 0)
        {
            jo_core_error("Image width must be multiple of 8");
            return ;
        }
        if (JO_MOD_POW2(img->height, 8) != 0)
        {
            jo_core_error("Image height must be multiple of 8");
            return ;
        }
#endif

    for (JO_ZERO(y), JO_ZERO(line_y); y < img->height; y += CELL_HEIGHT, line_y += JO_MULT_BY_8(img->width))
    {
        for (JO_ZERO(x); x < img->width; x += CELL_WIDTH)
        {
            cell_x = x;
            cell_y = line_y;
            for (JO_ZERO(i); i < CELL_SIZE; ++i, ++cell, ++cell_x)
            {
                if (i != 0 && JO_MOD_POW2(i, CELL_WIDTH) == 0)
                {
                    cell_x -= CELL_WIDTH;
                    cell_y += img->width;
                }
                /**/
                if (vertical_flip)
                    *cell = img->data[(img->width - cell_x - 1) + cell_y];
                else
                 /**/
                    *cell = img->data[cell_x + cell_y];
            }
        }
    }
}

static void                     __jo_create_map(const jo_img_8bits * const img, unsigned short *map, const unsigned short palette_id, const int map_offset)
{
    register int                x;
    register int                y;
    register int                x2;
    register int                y2;
    register int                i;
    unsigned short              paloff;

    paloff = JO_MULT_BY_4096(palette_id);
    y = JO_DIV_BY_8(img->height);
    x = JO_DIV_BY_8(img->width);
    JO_ZERO(y2);
    JO_ZERO(x2);
    for (JO_ZERO(i); i < MAP_LENGTH; ++i)
    {
/*
        if (i != 0 && JO_MOD_POW2(i, CELL_COUNT_PER_ROW) == 0)
            ++y2;
        if (y2 >= y)
            JO_ZERO(y2);
        *map = (JO_MULT_BY_2(x2 + y2 * y) | paloff) + map_offset;
            ++map;
        ++x2;
        if (x2 >= x)
            JO_ZERO(y2);

/**/
        if (i != 0 && JO_MOD_POW2(i, CELL_COUNT_PER_ROW) == 0) {
            JO_ZERO(x2);
            ++y2;
            /*
            if (y2 >= y) {
                JO_ZERO(y2);
            }*/
        }
        *map = (JO_MULT_BY_2(x2 + y2 * x) | paloff) + map_offset;
       
        ++map;
        ++x2;
/**/       
    }
}