skmp / reicast-emulator

Reicast was a multiplatform Sega Dreamcast emulator
https://reicast.emudev.org
Other
1.1k stars 345 forks source link

Reicast fails to render some KallistiOS scenes #1229

Closed Protofall closed 6 years ago

Protofall commented 6 years ago

Some of my KallistiOS programs, that I have tested on real Dreamcast hardware, fail to render anything in the reicast emulator. Attached is an example CDI of a program that does this. The functions that load the data into memory all return 0 (Success). The problem could have to do with rendering. Also note every program I tested that did work uses PNG assets that are converted into a DC usable format at runtime whereas this program uses the DTEX and DTEX.PAL formats which are loaded straight into memory without needing to convert them.

In this program I draw a 256 by 256 PAL4BPP DTEX spritesheet in the top left corner. Attached is a screenshot of the lxdream emulator running the same program along with a download link for the CDI file

proglxdream

http://www.mediafire.com/file/hm3724c2m7hutyc/Prog.cdi/file

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/61161399-reicast-fails-to-render-some-kallistios-scenes?utm_campaign=plugin&utm_content=tracker%2F500311&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F500311&utm_medium=issues&utm_source=github).
baka0815 commented 6 years ago

Just to be sure, the expected output is the one from the screenshot, right?

Protofall commented 6 years ago

That is correct.

DevilFrost commented 6 years ago

Fixed https://github.com/DevilFrost/reicast-emulator/commit/498e6a6b5452e9e2e5fef7fb6fb20c0e58edf213

Protofall commented 6 years ago

I've ran both the master and @DevilFrost 's fork with multiple KOS tests (Including Prog.cdi and KOS' packed in PNG example that has an opaque background and custom text on translucent polys). Although the main branch does mess up a few times (Such as failing to draw the PNG example's background), the fork messes up the same things and sometimes more (in PNG it draws nothing). The only time I'm seeing Devil's fork out performing master is with Prog.cdi (And other programs using the draw function from Prog.cdi).

If it helps this is the draw function used in Prog.cdi and programs that use Prog.cdi's draw function

uint8_t graphics_draw_sprite(const struct crayon_details *details, float draw_x, float draw_y, float draw_z, float scale_x, float scale_y, uint16_t frame_x, uint16_t frame_y, uint8_t paletteNumber){
//Screen coords. letter0 is top left coord, letter1 is bottom right coord. Z is depth (Layer)
const float x0 = draw_x;
const float y0 = draw_y;
const float x1 = draw_x + (details->width) * scale_x;
const float y1 = draw_y + (details->height) * scale_y;
const float z = draw_z;

//Texture coords. letter0 and letter1 have same logic as before
const float u0 = frame_x / (float)details->texture_dims;
const float v0 = frame_y / (float)details->texture_dims;
const float u1 = (frame_x + details->width) / (float)details->texture_dims;
const float v1 = (frame_y + details->height) / (float)details->texture_dims;

//Get context depending on texture format
//Yes, its hard coded to use TR polys. Later it will let you choose OP and PT lists too
pvr_sprite_cxt_t context;
if(deatils->texture_format == 6){  //PAL8BPP format
    pvr_sprite_cxt_txr(&context, PVR_LIST_TR_POLY, PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(paletteNumber),
    details->texture_dims, details->texture_dims, details->texture, PVR_FILTER_NONE);
}
else if(deatils->texture_format == 5){ //PAL4BPP format
    pvr_sprite_cxt_txr(&context, PVR_LIST_TR_POLY, PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_4BPP_PAL(paletteNumber),
    details->texture_dims, details->texture_dims, details->texture, PVR_FILTER_NONE);
}
else if(deatils->texture_format == 0 || deatils->texture_format == 1 || deatils->texture_format == 2){  //ARGB1555, RGB565 and RGB4444
    pvr_sprite_cxt_txr(&context, PVR_LIST_TR_POLY, (deatils->texture_format) << 27,
    details->texture_dims, details->texture_dims, details->texture, PVR_FILTER_NONE);
}
else{ //Unknown format
    return 1;
}

pvr_sprite_hdr_t header;
pvr_sprite_compile(&header, &context);
pvr_prim(&header, sizeof(header));

pvr_sprite_txr_t vert = {
    .flags = PVR_CMD_VERTEX_EOL,
    .ax = x0, .ay = y0, .az = z, .auv = PVR_PACK_16BIT_UV(u0, v0),
    .bx = x1, .by = y0, .bz = z, .buv = PVR_PACK_16BIT_UV(u1, v0),
    .cx = x1, .cy = y1, .cz = z, .cuv = PVR_PACK_16BIT_UV(u1, v1),
    .dx = x0, .dy = y1
};
pvr_prim(&vert, sizeof(vert));

return 0;
}

The difference I see is that I'm using KOS' sprite system to draw my textures instead of polygons (Like pretty much every other KOS test). This makes sense with another program I have with untextured polys and textured sprites. Master only draws the untextured polys since the textures are all sprites.

Edit: Tested this with @flyinghead 's fh/mymaster branch and it work great (Requires BIOS)

dmiller423 commented 6 years ago

@Protofall thanks for testing, merged 6ffe4c0280ef483527cf804f44f8960ecfef7aa0 for sprite changes to master