#include #include #include #include #include #define PL_MPEG_IMPLEMENTATION #include "pl_mpeg.h" static pvr_ptr_t texture_ptr; static int video_width = 0; static int video_height = 0; static const int tex_size = 512; void draw_error(const char *msg) { uint16_t *vram = vram_s; int x = 20, y = 20; for(int i = 0; i < 640 * 480; i++) vram[i] = 0x000F; bfont_draw_str(vram + y * 640 + x, 640, 0, msg); while(1) { MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st) if(st->buttons & CONT_START) return; MAPLE_FOREACH_END() } } void draw_frame() { pvr_poly_cxt_t cxt; pvr_poly_hdr_t hdr; pvr_vertex_t vert; pvr_wait_ready(); pvr_scene_begin(); pvr_list_begin(PVR_LIST_OP_POLY); pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED, tex_size, tex_size, texture_ptr, PVR_FILTER_BILINEAR); pvr_poly_compile(&hdr, &cxt); pvr_prim(&hdr, sizeof(hdr)); float u_max = (float)video_width / (float)tex_size; float v_max = (float)video_height / (float)tex_size; vert.flags = PVR_CMD_VERTEX; vert.z = 1.0f; vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f); vert.x = 0; vert.y = 0; vert.u = 0; vert.v = 0; pvr_prim(&vert, sizeof(vert)); vert.x = 640; vert.y = 0; vert.u = u_max; vert.v = 0; pvr_prim(&vert, sizeof(vert)); vert.x = 0; vert.y = 480; vert.u = 0; vert.v = v_max; pvr_prim(&vert, sizeof(vert)); vert.flags = PVR_CMD_VERTEX_EOL; vert.x = 640; vert.y = 480; vert.u = u_max; vert.v = v_max; pvr_prim(&vert, sizeof(vert)); pvr_list_finish(); pvr_scene_finish(); } void list_files_on_screen() { DIR *dir; struct dirent *ent; int x = 20, y = 50; uint16_t *vram = vram_s; dir = opendir("/cd"); if (dir == NULL) { bfont_draw_str(vram + (y * 640) + x, 640, 0, "Error: Could not open /cd"); return; } bfont_draw_str(vram + (y * 640) + x, 640, 0, "Files found on /cd:"); y += 20; while ((ent = readdir(dir)) != NULL) { char msg[128]; sprintf(msg, " -> %s", ent->d_name); bfont_draw_str(vram + (y * 640) + x, 640, 0, msg); y += 20; if (y > 450) break; } closedir(dir); } void play_video(const char *filename) { plm_t *plm = plm_create_with_filename(filename); if (!plm) { char err[128]; sprintf(err, "FATAL: Could not open %s", filename); draw_error(err); return; } video_width = plm_get_width(plm); video_height = plm_get_height(plm); while (!plm_has_ended(plm)) { plm_frame_t *frame = plm_decode_video(plm); if (frame) { uint16_t *pix = (uint16_t *)texture_ptr; uint8_t *y_plane = frame->y.data; for (int y = 0; y < video_height; y++) { for (int x = 0; x < video_width; x++) { uint8_t brightness = y_plane[y * video_width + x]; uint16_t r = (brightness >> 3) & 0x1F; uint16_t g = (brightness >> 2) & 0x3F; uint16_t b = (brightness >> 3) & 0x1F; pix[y * tex_size + x] = (r << 11) | (g << 5) | b; } } draw_frame(); } MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st) if(st->buttons & CONT_START) return; MAPLE_FOREACH_END() vid_waitvbl(); } plm_destroy(plm); } int main(int argc, char **argv) { pvr_init_defaults(); texture_ptr = pvr_mem_malloc(tex_size * tex_size * 2); if (!texture_ptr) return -1; play_video("/cd/VIDEO.MPG"); pvr_mem_free(texture_ptr); return 0; }