nkeynes@297 | 1 | /**
|
nkeynes@561 | 2 | * $Id$
|
nkeynes@297 | 3 | *
|
nkeynes@297 | 4 | * Scene-save loader support. This is the other side of rendsave.c
|
nkeynes@297 | 5 | *
|
nkeynes@297 | 6 | * Copyright (c) 2005 Nathan Keynes.
|
nkeynes@297 | 7 | *
|
nkeynes@297 | 8 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@297 | 9 | * it under the terms of the GNU General Public License as published by
|
nkeynes@297 | 10 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@297 | 11 | * (at your option) any later version.
|
nkeynes@297 | 12 | *
|
nkeynes@297 | 13 | * This program is distributed in the hope that it will be useful,
|
nkeynes@297 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@297 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@297 | 16 | * GNU General Public License for more details.
|
nkeynes@297 | 17 | */
|
nkeynes@297 | 18 |
|
nkeynes@297 | 19 | #include <stdio.h>
|
nkeynes@297 | 20 | #include <errno.h>
|
nkeynes@297 | 21 | #include "lib.h"
|
nkeynes@297 | 22 | #include "asic.h"
|
nkeynes@297 | 23 | #include "pvr.h"
|
nkeynes@297 | 24 |
|
nkeynes@297 | 25 | char *scene_magic = "%!-lxDream!Scene";
|
nkeynes@297 | 26 |
|
nkeynes@297 | 27 | #define PVR2_BASE 0xA05F8000
|
nkeynes@297 | 28 |
|
nkeynes@297 | 29 | #define COPYREG(x) long_write( (PVR2_BASE+x), scene_header.pvr2_regs[(x>>2)] )
|
nkeynes@297 | 30 |
|
nkeynes@297 | 31 | int pvr2_render_load_scene( FILE *f )
|
nkeynes@297 | 32 | {
|
nkeynes@297 | 33 | struct {
|
nkeynes@297 | 34 | char magic[16];
|
nkeynes@297 | 35 | uint32_t version;
|
nkeynes@297 | 36 | uint32_t timestamp;
|
nkeynes@297 | 37 | uint32_t frame_count;
|
nkeynes@297 | 38 | uint32_t pvr2_regs[0x400];
|
nkeynes@297 | 39 | uint32_t palette[0x400];
|
nkeynes@297 | 40 | } scene_header;
|
nkeynes@297 | 41 | uint32_t start = 0xFFFFFFFF, length;
|
nkeynes@297 | 42 |
|
nkeynes@297 | 43 | if( fread( &scene_header, sizeof(scene_header), 1, f ) != 1 ) {
|
nkeynes@297 | 44 | fprintf( stderr, "Failed to read scene header (%s)\n", strerror(errno) );
|
nkeynes@297 | 45 | return -1;
|
nkeynes@297 | 46 | }
|
nkeynes@297 | 47 | if( memcmp( scene_magic, scene_header.magic, 16 ) != 0 ) {
|
nkeynes@297 | 48 | fprintf( stderr, "Failed to load scene data: Header not found\n" );
|
nkeynes@297 | 49 | fclose(f);
|
nkeynes@297 | 50 | return -1;
|
nkeynes@297 | 51 | }
|
nkeynes@297 | 52 |
|
nkeynes@297 | 53 | fprintf( stdout, "Loaded header\n" );
|
nkeynes@297 | 54 | /* Load the VRAM sections */
|
nkeynes@297 | 55 | while(1) {
|
nkeynes@297 | 56 | fread( &start, sizeof(uint32_t), 1, f );
|
nkeynes@297 | 57 | if( start == 0xFFFFFFFF ) { /* EOF */
|
nkeynes@297 | 58 | break;
|
nkeynes@297 | 59 | }
|
nkeynes@297 | 60 | fread( &length, sizeof(uint32_t), 1, f );
|
nkeynes@297 | 61 | int read = fread( (char *)(0xA5000000 + start), 1, length, f );
|
nkeynes@297 | 62 | if( read != length ) {
|
nkeynes@297 | 63 | fprintf( stderr, "Failed to load %d bytes at %08X (Got %d - %s)\n",
|
nkeynes@297 | 64 | length, start, read, strerror(errno) );
|
nkeynes@297 | 65 | fclose(f);
|
nkeynes@297 | 66 | return -2;
|
nkeynes@297 | 67 | } else {
|
nkeynes@297 | 68 | fprintf( stdout, "Loaded %d bytes at %08X\n", length, start );
|
nkeynes@297 | 69 | }
|
nkeynes@297 | 70 | }
|
nkeynes@297 | 71 |
|
nkeynes@297 | 72 | /* Copy the fog table */
|
nkeynes@297 | 73 | memcpy( (char *)0xA05F8200, ((char *)scene_header.pvr2_regs) + 0x200, 0x200 );
|
nkeynes@297 | 74 | /* Copy the palette data */
|
nkeynes@297 | 75 | memcpy( (char *)0xA05F9000, scene_header.palette, 4096 );
|
nkeynes@297 | 76 | /* And now the other registers */
|
nkeynes@297 | 77 | COPYREG(0x018);
|
nkeynes@297 | 78 | COPYREG(0x020);
|
nkeynes@297 | 79 | COPYREG(0x02C);
|
nkeynes@297 | 80 | COPYREG(0x030);
|
nkeynes@297 | 81 | COPYREG(0x044);
|
nkeynes@297 | 82 | COPYREG(0x048);
|
nkeynes@297 | 83 | COPYREG(0x04C);
|
nkeynes@297 | 84 | COPYREG(0x05C);
|
nkeynes@297 | 85 | COPYREG(0x060);
|
nkeynes@297 | 86 | COPYREG(0x064);
|
nkeynes@297 | 87 | COPYREG(0x068);
|
nkeynes@297 | 88 | COPYREG(0x06C);
|
nkeynes@297 | 89 | COPYREG(0x074);
|
nkeynes@297 | 90 | COPYREG(0x078);
|
nkeynes@297 | 91 | COPYREG(0x07C);
|
nkeynes@297 | 92 | COPYREG(0x080);
|
nkeynes@297 | 93 | COPYREG(0x084);
|
nkeynes@297 | 94 | COPYREG(0x088);
|
nkeynes@297 | 95 | COPYREG(0x08C);
|
nkeynes@297 | 96 | COPYREG(0x098);
|
nkeynes@297 | 97 | COPYREG(0x0B0);
|
nkeynes@297 | 98 | COPYREG(0x0B4);
|
nkeynes@297 | 99 | COPYREG(0x0B8);
|
nkeynes@297 | 100 | COPYREG(0x0BC);
|
nkeynes@297 | 101 | COPYREG(0x0C0);
|
nkeynes@297 | 102 | COPYREG(0x0E4);
|
nkeynes@297 | 103 | COPYREG(0x0F4);
|
nkeynes@297 | 104 | COPYREG(0x108);
|
nkeynes@297 | 105 | COPYREG(0x110);
|
nkeynes@297 | 106 | COPYREG(0x114);
|
nkeynes@297 | 107 | COPYREG(0x118);
|
nkeynes@297 | 108 | fprintf( stdout, "Load complete\n" );
|
nkeynes@297 | 109 | fclose(f);
|
nkeynes@297 | 110 | }
|
nkeynes@297 | 111 |
|
nkeynes@297 | 112 |
|
nkeynes@297 | 113 | void pvr2_render_loaded_scene()
|
nkeynes@297 | 114 | {
|
nkeynes@297 | 115 | asic_clear();
|
nkeynes@297 | 116 | long_write( (PVR2_BASE+0x14), 0xFFFFFFFF );
|
nkeynes@297 | 117 | asic_wait( EVENT_PVR_RENDER_DONE );
|
nkeynes@297 | 118 | asic_clear();
|
nkeynes@297 | 119 | asic_wait( EVENT_RETRACE );
|
nkeynes@297 | 120 | uint32_t addr = long_read( (PVR2_BASE+0x060) );
|
nkeynes@297 | 121 | uint32_t mod = long_read( (PVR2_BASE+0x04C) );
|
nkeynes@297 | 122 | long_write( (PVR2_BASE+0x050), addr);
|
nkeynes@297 | 123 | long_write( (PVR2_BASE+0x054), addr + (mod<<3) );
|
nkeynes@297 | 124 | }
|
nkeynes@297 | 125 |
|
nkeynes@297 | 126 |
|
nkeynes@297 | 127 | int main()
|
nkeynes@297 | 128 | {
|
nkeynes@297 | 129 | pvr_init();
|
nkeynes@297 | 130 | pvr2_render_load_scene(stdin);
|
nkeynes@297 | 131 | pvr2_render_loaded_scene();
|
nkeynes@297 | 132 | asic_clear();
|
nkeynes@297 | 133 | asic_wait(EVENT_RETRACE);
|
nkeynes@297 | 134 | asic_clear();
|
nkeynes@297 | 135 | asic_wait(EVENT_RETRACE);
|
nkeynes@297 | 136 | asic_clear();
|
nkeynes@297 | 137 | asic_wait(EVENT_RETRACE);
|
nkeynes@297 | 138 | }
|