multimediamike/dreamroq

A few updates to the player

QuzarDC opened this issue · 2 comments

Hi Mike. I took the liberty of adding a few updates to the player based primarily on the comments on your DCEmulation thread about this. These include caching the headers and vertices as well as not twiddling each frame. Additionally I've added for the graphics to reinitialize on a change in width, height, or stride (I'm sure this isn't really possible in a single video, but still).

I don't have a development environment handy, so this is just 'eyeballed'. If you have any questions feel free to let me know. Below is the body of the code (not sure how to upload a patch like one would in sourceforge...).

/*

  • Dreamroq by Mike Melanson
    *
  • This is the sample Dreamcast player app, designed to be run under
  • the KallistiOS operating system.
    */

include "kos.h"

include "dreamroqlib.h"

/* Video vars */

static pvr_ptr_t textures[2];
static pvr_poly_cxt_t cxt;
static pvr_poly_hdr_t hdr[2];
static pvr_vertex_t vert[4];
static int current_frame = 0;

/* 'old' values of width, height, and stride. */
static int old_width =0, old_height =0, old_stride =0;

static int render_cb(unsigned short buf, int width, int height, int stride,
int texture_height)
{
/
Any time width, height, or stride change the graphics have to be re-initialized /
if ((old_width != width) || (old_height != height) || (old_stride != stride))
{
float ratio;
/
screen coordinates of upper left and bottom right corners */
int ul_x, ul_y, br_x, br_y;

    textures[0] = pvr_mem_malloc(stride * texture_height * 2);
    textures[1] = pvr_mem_malloc(stride * texture_height * 2);
    if (!textures[0] || !textures[1])
    {
        return ROQ_RENDER_PROBLEM;
    }

    /* Precompile the poly headers */
    pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED, stride, texture_height, textures[0], PVR_FILTER_NONE);
    pvr_poly_compile(&hdr[0], &cxt);
    pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED, stride, texture_height, textures[1], PVR_FILTER_NONE);
    pvr_poly_compile(&hdr[1], &cxt);

    /* this only works if width ratio <= height ratio */
    ratio = 640.0 / width;
    ul_x = 0;
    br_x = (ratio * stride);
    ul_y = ((480 - ratio * height) / 2);
    br_y = ul_y + ratio * texture_height;

    /* Precompile all vertices */

    /* Things common to vertices */
    vert[0].z     = vert[1].z     = vert[2].z     = vert[3].z     = 1.0f; 
    vert[0].argb  = vert[1].argb  = vert[2].argb  = vert[3].argb  = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);    
    vert[0].oargb = vert[1].oargb = vert[2].oargb = vert[3].oargb = 0;  
    vert[0].flags = vert[1].flags = vert[2].flags = PVR_CMD_VERTEX;         
    vert[3].flags = PVR_CMD_VERTEX_EOL; 

    vert[0].x = ul_x;
    vert[0].y = ul_y;
    vert[0].u = 0.0;
    vert[0].v = 0.0;

    vert[1].x = br_x;
    vert[1].y = ul_y;
    vert[1].u = 1.0;
    vert[1].v = 0.0;

    vert[2].x = ul_x;
    vert[2].y = br_y;
    vert[2].u = 0.0;
    vert[2].v = 1.0;

    vert[3].x = br_x;
    vert[3].y = br_y;
    vert[3].u = 1.0;
    vert[3].v = 1.0;

    old_width = width;
    old_height = height;
    old_stride = stride;
}

/* send the video frame as a texture over to video RAM */
pvr_txr_load(buf, textures[current_frame], stride * texture_height * 2);

pvr_wait_ready();

/* Instruct the pvr on what to render */
pvr_scene_begin();    
pvr_list_begin(PVR_LIST_OP_POLY);   

/* Send all the polygon info previously compiled */
pvr_prim(&hdr[current_frame], sizeof(pvr_poly_hdr_t));
pvr_prim(&vert[0], sizeof(pvr_vertex_t)); 
pvr_prim(&vert[1], sizeof(pvr_vertex_t)); 
pvr_prim(&vert[2], sizeof(pvr_vertex_t));
pvr_prim(&vert[3], sizeof(pvr_vertex_t));   

pvr_list_finish();
pvr_scene_finish();

if (current_frame)
    current_frame = 0;
else
    current_frame = 1;

return ROQ_SUCCESS;

}

Thanks for these suggestions. I plan to incorporate some of them.

Changes have been incorporated. Thanks.