revision 1145:45674791c6ad
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 1145:45674791c6ad |
parent | 1144:00dd49743974 |
child | 1146:76c5d1064262 |
author | nkeynes |
date | Mon Nov 08 14:33:38 2010 +1000 (13 years ago) |
Introduce tile iterators to simplify processing of the tile lists
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/pvr2/glrender.c | view | annotate | diff | log | ||
src/pvr2/pvr2.h | view | annotate | diff | log | ||
src/pvr2/tacore.c | view | annotate | diff | log | ||
src/pvr2/tileiter.h | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Mon Nov 08 14:12:10 2010 +10001.2 +++ b/src/Makefile.am Mon Nov 08 14:33:38 2010 +10001.3 @@ -56,10 +56,9 @@1.4 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armdasm.h aica/armmem.c \1.5 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \1.6 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c pvr2/pvr2mmio.h \1.7 - pvr2/tacore.c pvr2/rendsort.c \1.8 + pvr2/tacore.c pvr2/rendsort.c pvr2/tileiter.h pvr2/shaders.glsl \1.9 pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \1.10 pvr2/gl_sl.c pvr2/shaders.h pvr2/shaders.def pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c \1.11 - pvr2/vertex.glsl pvr2/fragment.glsl \1.12 maple/maple.c maple/maple.h \1.13 maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c maple/vmu.c \1.14 loader.c loader.h elf.h bootstrap.c bootstrap.h util.c gdlist.c gdlist.h \
2.1 --- a/src/Makefile.in Mon Nov 08 14:12:10 2010 +10002.2 +++ b/src/Makefile.in Mon Nov 08 14:33:38 2010 +10002.3 @@ -156,10 +156,10 @@2.4 aica/armcore.h aica/armdasm.c aica/armdasm.h aica/armmem.c \2.5 aica/aica.c aica/aica.h aica/audio.c aica/audio.h pvr2/pvr2.c \2.6 pvr2/pvr2.h pvr2/pvr2mem.c pvr2/pvr2mmio.h pvr2/tacore.c \2.7 - pvr2/rendsort.c pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c \2.8 - pvr2/scene.c pvr2/scene.h pvr2/gl_sl.c pvr2/shaders.h \2.9 - pvr2/shaders.def pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c \2.10 - pvr2/vertex.glsl pvr2/fragment.glsl maple/maple.c \2.11 + pvr2/rendsort.c pvr2/tileiter.h pvr2/shaders.glsl \2.12 + pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c \2.13 + pvr2/scene.h pvr2/gl_sl.c pvr2/shaders.h pvr2/shaders.def \2.14 + pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c maple/maple.c \2.15 maple/maple.h maple/controller.c maple/kbd.c maple/mouse.c \2.16 maple/lightgun.c maple/vmu.c loader.c loader.h elf.h \2.17 bootstrap.c bootstrap.h util.c gdlist.c gdlist.h vmu/vmuvol.c \2.18 @@ -576,14 +576,14 @@2.19 aica/armdasm.h aica/armmem.c aica/aica.c aica/aica.h \2.20 aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \2.21 pvr2/pvr2mem.c pvr2/pvr2mmio.h pvr2/tacore.c pvr2/rendsort.c \2.22 - pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c \2.23 - pvr2/scene.h pvr2/gl_sl.c pvr2/shaders.h pvr2/shaders.def \2.24 - pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c pvr2/vertex.glsl \2.25 - pvr2/fragment.glsl maple/maple.c maple/maple.h \2.26 - maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c \2.27 - maple/vmu.c loader.c loader.h elf.h bootstrap.c bootstrap.h \2.28 - util.c gdlist.c gdlist.h vmu/vmuvol.c vmu/vmuvol.h \2.29 - vmu/vmulist.c vmu/vmulist.h display.c display.h dckeysyms.h \2.30 + pvr2/tileiter.h pvr2/shaders.glsl pvr2/texcache.c pvr2/yuv.c \2.31 + pvr2/rendsave.c pvr2/scene.c pvr2/scene.h pvr2/gl_sl.c \2.32 + pvr2/shaders.h pvr2/shaders.def pvr2/glutil.c pvr2/glutil.h \2.33 + pvr2/glrender.c maple/maple.c maple/maple.h maple/controller.c \2.34 + maple/kbd.c maple/mouse.c maple/lightgun.c maple/vmu.c \2.35 + loader.c loader.h elf.h bootstrap.c bootstrap.h util.c \2.36 + gdlist.c gdlist.h vmu/vmuvol.c vmu/vmuvol.h vmu/vmulist.c \2.37 + vmu/vmulist.h display.c display.h dckeysyms.h \2.38 drivers/audio_null.c drivers/video_null.c drivers/video_gl.c \2.39 drivers/video_gl.h drivers/gl_fbo.c drivers/serial_unix.c \2.40 drivers/cdrom/cdrom.h drivers/cdrom/cdrom.c \
3.1 --- a/src/pvr2/glrender.c Mon Nov 08 14:12:10 2010 +10003.2 +++ b/src/pvr2/glrender.c Mon Nov 08 14:33:38 2010 +10003.3 @@ -21,8 +21,9 @@3.4 #include "display.h"3.5 #include "pvr2/pvr2.h"3.6 #include "pvr2/pvr2mmio.h"3.7 +#include "pvr2/glutil.h"3.8 #include "pvr2/scene.h"3.9 -#include "pvr2/glutil.h"3.10 +#include "pvr2/tileiter.h"3.12 #define IS_EMPTY_TILE_LIST(p) ((*((uint32_t *)(pvr2_main_ram+(p))) >> 28) == 0x0F)3.14 @@ -59,6 +60,16 @@3.15 return tile[0] < tile[1] && tile[2] < tile[3];3.16 }3.18 +static void drawrect2d( uint32_t tile_bounds[], float z )3.19 +{3.20 + glBegin( GL_QUADS );3.21 + glVertex3f( tile_bounds[0], tile_bounds[2], z );3.22 + glVertex3f( tile_bounds[1], tile_bounds[2], z );3.23 + glVertex3f( tile_bounds[1], tile_bounds[3], z );3.24 + glVertex3f( tile_bounds[0], tile_bounds[3], z );3.25 + glEnd();3.26 +}3.27 +3.28 void pvr2_scene_load_textures()3.29 {3.30 int i;3.31 @@ -239,107 +250,8 @@3.32 }3.33 }3.35 -static void gl_render_bkgnd( struct polygon_struct *poly )3.36 -{3.37 - glBindTexture(GL_TEXTURE_2D, poly->tex_id);3.38 - render_set_tsp_context( poly->context[0], poly->context[1] );3.39 - glDisable( GL_DEPTH_TEST );3.40 - glBlendFunc( GL_ONE, GL_ZERO );3.41 - gl_draw_vertexes(poly);3.42 - glEnable( GL_DEPTH_TEST );3.43 -}3.45 -void gl_render_tilelist( pvraddr_t tile_entry, gboolean set_depth )3.46 -{3.47 - uint32_t *tile_list = (uint32_t *)(pvr2_main_ram+tile_entry);3.48 - int strip_count;3.49 - struct polygon_struct *poly;3.50 -3.51 - if( !IS_TILE_PTR(tile_entry) )3.52 - return;3.53 -3.54 - while(1) {3.55 - uint32_t entry = *tile_list++;3.56 - switch( entry >> 28 ) {3.57 - case 0x0F:3.58 - return; // End-of-list3.59 - case 0x0E:3.60 - tile_list = (uint32_t *)(pvr2_main_ram + (entry&0x007FFFFF));3.61 - break;3.62 - case 0x08: case 0x09: case 0x0A: case 0x0B:3.63 - strip_count = ((entry >> 25) & 0x0F)+1;3.64 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];3.65 - while( strip_count > 0 ) {3.66 - assert( poly != NULL );3.67 - gl_render_poly( poly, set_depth );3.68 - poly = poly->next;3.69 - strip_count--;3.70 - }3.71 - break;3.72 - default:3.73 - if( entry & 0x7E000000 ) {3.74 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];3.75 - gl_render_poly( poly, set_depth );3.76 - }3.77 - }3.78 - }3.79 -}3.80 -3.81 -/**3.82 - * Render the tilelist with depthbuffer updates only.3.83 - */3.84 -void gl_render_tilelist_depthonly( pvraddr_t tile_entry )3.85 -{3.86 - uint32_t *tile_list = (uint32_t *)(pvr2_main_ram+tile_entry);3.87 - int strip_count;3.88 - struct polygon_struct *poly;3.89 -3.90 - if( !IS_TILE_PTR(tile_entry) )3.91 - return;3.92 -3.93 - while(1) {3.94 - uint32_t entry = *tile_list++;3.95 - switch( entry >> 28 ) {3.96 - case 0x0F:3.97 - return; // End-of-list3.98 - case 0x0E:3.99 - tile_list = (uint32_t *)(pvr2_main_ram + (entry&0x007FFFFF));3.100 - break;3.101 - case 0x08: case 0x09: case 0x0A: case 0x0B:3.102 - strip_count = ((entry >> 25) & 0x0F)+1;3.103 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];3.104 - while( strip_count > 0 ) {3.105 - if( poly->vertex_count != 0 ) {3.106 - render_set_base_context(poly->context[0],TRUE);3.107 - gl_draw_vertexes(poly);3.108 - }3.109 - poly = poly->next;3.110 - strip_count--;3.111 - }3.112 - break;3.113 - default:3.114 - if( entry & 0x7E000000 ) {3.115 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];3.116 - if( poly->vertex_count != 0 ) {3.117 - render_set_base_context(poly->context[0],TRUE);3.118 - gl_draw_vertexes(poly);3.119 - }3.120 - }3.121 - }3.122 - }3.123 -}3.124 -3.125 -static void drawrect2d( uint32_t tile_bounds[], float z )3.126 -{3.127 - glBegin( GL_QUADS );3.128 - glVertex3f( tile_bounds[0], tile_bounds[2], z );3.129 - glVertex3f( tile_bounds[1], tile_bounds[2], z );3.130 - glVertex3f( tile_bounds[1], tile_bounds[3], z );3.131 - glVertex3f( tile_bounds[0], tile_bounds[3], z );3.132 - glEnd();3.133 -}3.134 -3.135 -void gl_render_modifier_polygon( struct polygon_struct *poly, uint32_t tile_bounds[] )3.136 +static void gl_render_modifier_polygon( struct polygon_struct *poly, uint32_t tile_bounds[] )3.137 {3.138 /* A bit of explanation:3.139 * In theory it works like this: generate a 1-bit stencil for each polygon3.140 @@ -405,55 +317,79 @@3.141 }3.142 }3.144 -void gl_render_modifier_tilelist( pvraddr_t tile_entry, uint32_t tile_bounds[] )3.145 +static void gl_render_bkgnd( struct polygon_struct *poly )3.146 {3.147 - uint32_t *tile_list = (uint32_t *)(pvr2_main_ram+tile_entry);3.148 - int strip_count;3.149 - struct polygon_struct *poly;3.150 + glBindTexture(GL_TEXTURE_2D, poly->tex_id);3.151 + render_set_tsp_context( poly->context[0], poly->context[1] );3.152 + glDisable( GL_DEPTH_TEST );3.153 + glBlendFunc( GL_ONE, GL_ZERO );3.154 + gl_draw_vertexes(poly);3.155 + glEnable( GL_DEPTH_TEST );3.156 +}3.157 +3.158 +void gl_render_tilelist( pvraddr_t tile_entry, gboolean set_depth )3.159 +{3.160 + tileentryiter list;3.161 +3.162 + FOREACH_TILEENTRY(list, tile_entry) {3.163 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[TILEENTRYITER_POLYADDR(list)];3.164 + if( poly != NULL ) {3.165 + do {3.166 + gl_render_poly(poly, set_depth);3.167 + poly = poly->next;3.168 + } while( list.strip_count-- > 0 );3.169 + }3.170 + }3.171 +}3.172 +3.173 +/**3.174 + * Render the tilelist with depthbuffer updates only.3.175 + */3.176 +static void gl_render_tilelist_depthonly( pvraddr_t tile_entry )3.177 +{3.178 + tileentryiter list;3.179 +3.180 + FOREACH_TILEENTRY(list, tile_entry) {3.181 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[TILEENTRYITER_POLYADDR(list)];3.182 + if( poly != NULL ) {3.183 + do {3.184 + render_set_base_context(poly->context[0],TRUE);3.185 + gl_draw_vertexes(poly);3.186 + poly = poly->next;3.187 + } while( list.strip_count-- > 0 );3.188 + }3.189 + }3.190 +}3.191 +3.192 +static void gl_render_modifier_tilelist( pvraddr_t tile_entry, uint32_t tile_bounds[] )3.193 +{3.194 + tileentryiter list;3.196 if( !IS_TILE_PTR(tile_entry) )3.197 return;3.199 glEnable( GL_STENCIL_TEST );3.200 glEnable( GL_DEPTH_TEST );3.201 - glDepthFunc( GL_LEQUAL );3.202 -3.203 glStencilFunc( GL_ALWAYS, 0, 1 );3.204 glStencilOp( GL_KEEP,GL_INVERT, GL_KEEP );3.205 glStencilMask( 0x01 );3.206 + glDepthFunc( GL_LEQUAL );3.207 glDepthMask( GL_FALSE );3.209 - while(1) {3.210 - uint32_t entry = *tile_list++;3.211 - switch( entry >> 28 ) {3.212 - case 0x0F:3.213 - glDepthMask( GL_TRUE );3.214 - glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );3.215 - glDisable( GL_STENCIL_TEST );3.216 - return; // End-of-list3.217 - case 0x0E:3.218 - tile_list = (uint32_t *)(pvr2_main_ram + (entry&0x007FFFFF));3.219 - break;3.220 - case 0x08: case 0x09: case 0x0A: case 0x0B:3.221 - strip_count = ((entry >> 25) & 0x0F)+1;3.222 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];3.223 - while( strip_count > 0 ) {3.224 + FOREACH_TILEENTRY(list, tile_entry ) {3.225 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[TILEENTRYITER_POLYADDR(list)];3.226 + if( poly != NULL ) {3.227 + do {3.228 gl_render_modifier_polygon( poly, tile_bounds );3.229 poly = poly->next;3.230 - strip_count--;3.231 - }3.232 - break;3.233 - default:3.234 - if( entry & 0x7E000000 ) {3.235 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];3.236 - gl_render_modifier_polygon( poly, tile_bounds );3.237 - }3.238 + } while( list.strip_count-- > 0 );3.239 }3.240 }3.241 -3.242 + glDepthMask( GL_TRUE );3.243 + glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );3.244 + glDisable( GL_STENCIL_TEST );3.245 }3.247 -3.248 /**3.249 * Render the currently defined scene in pvr2_scene3.250 */
4.1 --- a/src/pvr2/pvr2.h Mon Nov 08 14:12:10 2010 +10004.2 +++ b/src/pvr2/pvr2.h Mon Nov 08 14:33:38 2010 +10004.3 @@ -21,7 +21,6 @@4.5 #include <stdio.h>4.6 #include "lxdream.h"4.7 -#include "mem.h"4.8 #include "display.h"4.10 #ifdef __cplusplus4.11 @@ -431,6 +430,11 @@4.12 pvraddr_t punchout_ptr;4.13 };4.15 +4.16 +struct tile_bounds {4.17 + int32_t x1, y1, x2, y2;4.18 +};4.19 +4.20 #ifdef __cplusplus4.21 }4.22 #endif
5.1 --- a/src/pvr2/tacore.c Mon Nov 08 14:12:10 2010 +10005.2 +++ b/src/pvr2/tacore.c Mon Nov 08 14:33:38 2010 +10005.3 @@ -126,10 +126,6 @@5.4 uint32_t detail[8]; /* 0-8 detail words */5.5 };5.7 -struct tile_bounds {5.8 - int32_t x1, y1, x2, y2;5.9 -};5.10 -5.11 struct pvr2_ta_status {5.12 int32_t state;5.13 int32_t width, height; /* Tile resolution, ie 20x15 */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00006.2 +++ b/src/pvr2/tileiter.h Mon Nov 08 14:33:38 2010 +10006.3 @@ -0,0 +1,197 @@6.4 +/**6.5 + * $Id$6.6 + *6.7 + * Tile iterator ADT. Defines an iterator that can be used to iterate through6.8 + * a PVR2 tile list a polygon at a time.6.9 + *6.10 + * Note: The iterator functions are defined here to allow the compiler to6.11 + * inline them if it wants to, but it's not always beneficial to do so6.12 + * (hence we don't force them to be inlined)6.13 + *6.14 + * Copyright (c) 2010 Nathan Keynes.6.15 + *6.16 + * This program is free software; you can redistribute it and/or modify6.17 + * it under the terms of the GNU General Public License as published by6.18 + * the Free Software Foundation; either version 2 of the License, or6.19 + * (at your option) any later version.6.20 + *6.21 + * This program is distributed in the hope that it will be useful,6.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of6.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the6.24 + * GNU General Public License for more details.6.25 + */6.26 +6.27 +#ifndef lxdream_tileiter_H6.28 +#define lxdream_tileiter_H 16.29 +6.30 +#include <assert.h>6.31 +#include "pvr2/pvr2.h"6.32 +6.33 +#ifdef __cplusplus6.34 +extern "C" {6.35 +#endif6.36 +6.37 +6.38 +/**6.39 + * tileiter: iterator over individual polygons in a tile list.6.40 + */6.41 +typedef struct tileiter {6.42 + uint32_t *ptr;6.43 + unsigned strip_count;6.44 + unsigned poly_size;6.45 + uint32_t poly_addr;6.46 +} tileiter;6.47 +6.48 +6.49 +#define TILEITER_IS_MODIFIED(it) ((*(it).ptr) & 0x01000000)6.50 +#define TILEITER_IS_TRIANGLE(it) (((*(it).ptr) >> 29) == 4)6.51 +#define TILEITER_IS_QUAD(it) (((*(it).ptr) >> 29) == 5)6.52 +#define TILEITER_IS_POLY(it) (((*(it).ptr) >> 31) == 0)6.53 +6.54 +#define TILEITER_POLYADDR(it) ((it).poly_addr)6.55 +#define TILEITER_STRIPCOUNT(it) ((it).strip_count)6.56 +#define TILEITER_DONE(it) ((it).ptr == 0)6.57 +#define TILEITER_BEGIN(it, tileent) (tileiter_init(&it, tileent))6.58 +#define TILEITER_NEXT(it) (tileiter_next(&it))6.59 +#define FOREACH_TILE(it, seg) for( TILEITER_BEGIN(it, seg); !TILEITER_DONE(it); TILEITER_NEXT(it) )6.60 +6.61 +6.62 +/**6.63 + * tileentryiter: iterator over entries in the tile list, where each entry is6.64 + * a polygon, triangle set, or quad set.6.65 + */6.66 +typedef struct tileentryiter {6.67 + uint32_t *ptr;6.68 + unsigned strip_count;6.69 +} tileentryiter;6.70 +6.71 +#define TILEENTRYITER_POLYADDR(it) ((*((it).ptr)) & 0x001FFFFF)6.72 +#define TILEENTRYITER_STRIPCOUNT(it) ((it).strip_count)6.73 +#define TILEENTRYITER_DONE(it) ((it).ptr == 0)6.74 +#define TILEENTRYITER_BEGIN(it, tileent) (tileentryiter_init(&(it),tileent))6.75 +#define TILEENTRYITER_NEXT(it) (tileentryiter_next(&(it)))6.76 +#define FOREACH_TILEENTRY(it,seg) for( TILEENTRYITER_BEGIN(it,seg); !TILEENTRYITER_DONE(it); TILEENTRYITER_NEXT(it) )6.77 +6.78 +/**************************** tileiter functions ****************************/6.79 +6.80 +/**6.81 + * Read the entry pointed to by it->ptr into the tileiter structure. If the6.82 + * entry if a list pointer or invalid entry, the pointer will first be6.83 + * updated to the next real entry. On end-of-list, sets ptr to NULL6.84 + */6.85 +static void tileiter_read( tileiter *it )6.86 +{6.87 + for(;;){6.88 + uint32_t entry = *it->ptr;6.89 + uint32_t tag = entry >> 29;6.90 + if( tag == 0x07 ) {6.91 + if( tag & 0x10000000 ) {6.92 + it->ptr = NULL;6.93 + return;6.94 + } else {6.95 + it->ptr = (uint32_t *)(pvr2_main_ram + (entry&0x007FFFFF));6.96 + it->poly_addr = -1;6.97 + entry = *it->ptr;6.98 + }6.99 + } else if( tag == 6 ) {6.100 + /* Illegal? Skip */6.101 + it->ptr++;6.102 + } else if( tag & 0x04 ) {6.103 + int vertex_count = tag-1; /* 4 == tri, 5 == quad */6.104 + int vertex_length = (entry >> 21) & 0x07;6.105 + if( (entry & 0x01000000) && (pvr2_scene.shadow_mode == SHADOW_FULL) ) {6.106 + it->poly_size = 5 + (vertex_length<<1) * vertex_count;6.107 + } else {6.108 + it->poly_size = 3 + vertex_length * vertex_count;6.109 + }6.110 + it->strip_count = ((entry >> 25) & 0x0F);6.111 + it->poly_addr = entry & 0x001FFFFF;6.112 + return;6.113 + } else {6.114 + /* Other polygon */6.115 + it->strip_count = 0;6.116 + it->poly_addr = entry & 0x001FFFFF;6.117 + return;6.118 + }6.119 + }6.120 +}6.121 +6.122 +static void tileiter_init( tileiter *it, uint32_t segptr )6.123 +{6.124 + if( IS_TILE_PTR(segptr) ) {6.125 + it->ptr = (uint32_t *)(pvr2_main_ram + (segptr & 0x007FFFFF));6.126 + tileiter_read(it);6.127 + } else {6.128 + it->ptr = 0;6.129 + }6.130 +}6.131 +6.132 +static inline void tileiter_next( tileiter *it )6.133 +{6.134 + assert( it->ptr != NULL );6.135 + if( it->strip_count > 0 ) {6.136 + it->strip_count--;6.137 + it->poly_addr += it->poly_size;6.138 + } else {6.139 + it->ptr++;6.140 + tileiter_read(it);6.141 + }6.142 +}6.143 +6.144 +6.145 +/************************* tileentryiter functions **************************/6.146 +6.147 +/**6.148 + * Read the entry pointed to by it->ptr, updating the pointer to point6.149 + * to the next real element if the current value is not a polygon entry.6.150 + */6.151 +static void tileentryiter_read( tileentryiter *it )6.152 +{6.153 + for(;;){6.154 + uint32_t entry = *it->ptr;6.155 + uint32_t tag = entry >> 28;6.156 + if( tag < 0x0C ) {6.157 + if( tag & 0x08 ) {6.158 + it->strip_count = ((entry >> 25) & 0x0F);6.159 + } else {6.160 + it->strip_count = 0;6.161 + }6.162 + return;6.163 + } else {6.164 + if( tag == 0x0F ) {6.165 + it->ptr = NULL;6.166 + return;6.167 + } else if( tag == 0x0E ) {6.168 + it->ptr = (uint32_t *)(pvr2_main_ram + (entry&0x007FFFFF));6.169 + entry = *it->ptr;6.170 + } else {6.171 + /* Illegal? Skip */6.172 + it->ptr++;6.173 + }6.174 + }6.175 + }6.176 +}6.177 +6.178 +6.179 +static void tileentryiter_init( tileentryiter *it, uint32_t segptr )6.180 +{6.181 + if( IS_TILE_PTR(segptr) ) {6.182 + it->ptr = (uint32_t *)(pvr2_main_ram + (segptr & 0x007FFFFF));6.183 + tileentryiter_read(it);6.184 + } else {6.185 + it->ptr = 0;6.186 + }6.187 +}6.188 +6.189 +static void inline tileentryiter_next( tileentryiter *it )6.190 +{6.191 + it->ptr++;6.192 + tileentryiter_read(it);6.193 +}6.194 +6.195 +6.196 +#ifdef __cplusplus6.197 +}6.198 +#endif6.199 +6.200 +#endif /* !lxdream_tileiter_H */
.