nkeynes@297: /** nkeynes@561: * $Id$ nkeynes@297: * nkeynes@297: * Scene-save loader support. This is the other side of rendsave.c nkeynes@297: * nkeynes@297: * Copyright (c) 2005 Nathan Keynes. nkeynes@297: * nkeynes@297: * This program is free software; you can redistribute it and/or modify nkeynes@297: * it under the terms of the GNU General Public License as published by nkeynes@297: * the Free Software Foundation; either version 2 of the License, or nkeynes@297: * (at your option) any later version. nkeynes@297: * nkeynes@297: * This program is distributed in the hope that it will be useful, nkeynes@297: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@297: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@297: * GNU General Public License for more details. nkeynes@297: */ nkeynes@297: nkeynes@297: #include nkeynes@297: #include nkeynes@297: #include "lib.h" nkeynes@297: #include "asic.h" nkeynes@297: #include "pvr.h" nkeynes@297: nkeynes@297: char *scene_magic = "%!-lxDream!Scene"; nkeynes@297: nkeynes@297: #define PVR2_BASE 0xA05F8000 nkeynes@297: nkeynes@297: #define COPYREG(x) long_write( (PVR2_BASE+x), scene_header.pvr2_regs[(x>>2)] ) nkeynes@297: nkeynes@297: int pvr2_render_load_scene( FILE *f ) nkeynes@297: { nkeynes@297: struct { nkeynes@297: char magic[16]; nkeynes@297: uint32_t version; nkeynes@297: uint32_t timestamp; nkeynes@297: uint32_t frame_count; nkeynes@297: uint32_t pvr2_regs[0x400]; nkeynes@297: uint32_t palette[0x400]; nkeynes@297: } scene_header; nkeynes@297: uint32_t start = 0xFFFFFFFF, length; nkeynes@297: nkeynes@297: if( fread( &scene_header, sizeof(scene_header), 1, f ) != 1 ) { nkeynes@297: fprintf( stderr, "Failed to read scene header (%s)\n", strerror(errno) ); nkeynes@297: return -1; nkeynes@297: } nkeynes@297: if( memcmp( scene_magic, scene_header.magic, 16 ) != 0 ) { nkeynes@297: fprintf( stderr, "Failed to load scene data: Header not found\n" ); nkeynes@297: fclose(f); nkeynes@297: return -1; nkeynes@297: } nkeynes@297: nkeynes@297: fprintf( stdout, "Loaded header\n" ); nkeynes@297: /* Load the VRAM sections */ nkeynes@297: while(1) { nkeynes@297: fread( &start, sizeof(uint32_t), 1, f ); nkeynes@297: if( start == 0xFFFFFFFF ) { /* EOF */ nkeynes@297: break; nkeynes@297: } nkeynes@297: fread( &length, sizeof(uint32_t), 1, f ); nkeynes@297: int read = fread( (char *)(0xA5000000 + start), 1, length, f ); nkeynes@297: if( read != length ) { nkeynes@297: fprintf( stderr, "Failed to load %d bytes at %08X (Got %d - %s)\n", nkeynes@297: length, start, read, strerror(errno) ); nkeynes@297: fclose(f); nkeynes@297: return -2; nkeynes@297: } else { nkeynes@297: fprintf( stdout, "Loaded %d bytes at %08X\n", length, start ); nkeynes@297: } nkeynes@297: } nkeynes@297: nkeynes@297: /* Copy the fog table */ nkeynes@297: memcpy( (char *)0xA05F8200, ((char *)scene_header.pvr2_regs) + 0x200, 0x200 ); nkeynes@297: /* Copy the palette data */ nkeynes@297: memcpy( (char *)0xA05F9000, scene_header.palette, 4096 ); nkeynes@297: /* And now the other registers */ nkeynes@297: COPYREG(0x018); nkeynes@297: COPYREG(0x020); nkeynes@297: COPYREG(0x02C); nkeynes@297: COPYREG(0x030); nkeynes@297: COPYREG(0x044); nkeynes@297: COPYREG(0x048); nkeynes@297: COPYREG(0x04C); nkeynes@297: COPYREG(0x05C); nkeynes@297: COPYREG(0x060); nkeynes@297: COPYREG(0x064); nkeynes@297: COPYREG(0x068); nkeynes@297: COPYREG(0x06C); nkeynes@297: COPYREG(0x074); nkeynes@297: COPYREG(0x078); nkeynes@297: COPYREG(0x07C); nkeynes@297: COPYREG(0x080); nkeynes@297: COPYREG(0x084); nkeynes@297: COPYREG(0x088); nkeynes@297: COPYREG(0x08C); nkeynes@297: COPYREG(0x098); nkeynes@297: COPYREG(0x0B0); nkeynes@297: COPYREG(0x0B4); nkeynes@297: COPYREG(0x0B8); nkeynes@297: COPYREG(0x0BC); nkeynes@297: COPYREG(0x0C0); nkeynes@297: COPYREG(0x0E4); nkeynes@297: COPYREG(0x0F4); nkeynes@297: COPYREG(0x108); nkeynes@297: COPYREG(0x110); nkeynes@297: COPYREG(0x114); nkeynes@297: COPYREG(0x118); nkeynes@297: fprintf( stdout, "Load complete\n" ); nkeynes@297: fclose(f); nkeynes@297: } nkeynes@297: nkeynes@297: nkeynes@297: void pvr2_render_loaded_scene() nkeynes@297: { nkeynes@297: asic_clear(); nkeynes@297: long_write( (PVR2_BASE+0x14), 0xFFFFFFFF ); nkeynes@297: asic_wait( EVENT_PVR_RENDER_DONE ); nkeynes@297: asic_clear(); nkeynes@297: asic_wait( EVENT_RETRACE ); nkeynes@297: uint32_t addr = long_read( (PVR2_BASE+0x060) ); nkeynes@297: uint32_t mod = long_read( (PVR2_BASE+0x04C) ); nkeynes@297: long_write( (PVR2_BASE+0x050), addr); nkeynes@297: long_write( (PVR2_BASE+0x054), addr + (mod<<3) ); nkeynes@297: } nkeynes@297: nkeynes@297: nkeynes@297: int main() nkeynes@297: { nkeynes@297: pvr_init(); nkeynes@297: pvr2_render_load_scene(stdin); nkeynes@297: pvr2_render_loaded_scene(); nkeynes@297: asic_clear(); nkeynes@297: asic_wait(EVENT_RETRACE); nkeynes@297: asic_clear(); nkeynes@297: asic_wait(EVENT_RETRACE); nkeynes@297: asic_clear(); nkeynes@297: asic_wait(EVENT_RETRACE); nkeynes@297: }