jvm/sega/dreamcast/holly/RegionArray.java
2024-12-27 17:15:38 -06:00

138 lines
6.3 KiB
Java

package sega.dreamcast.holly;
import sega.dreamcast.MemoryMap;
import java.misc.Memory;
// this is for a "type 2" region array.
// region header type is specified in FPU_PARAM_CFG
public class RegionArray {
private RegionArray() {
}
public static final int TILE = 0 * 4;
public static final int OPAQUE_LIST_POINTER = 1 * 4;
public static final int OPAQUE_MODIFIER_VOLUME_LIST_POINTER = 2 * 4;
public static final int TRANSLUCENT_LIST_POINTER = 3 * 4;
public static final int TRANSLUCENT_MODIFIER_VOLUME_LIST_POINTER = 4 * 4;
public static final int PUNCH_THROUGH_LIST_POINTER = 5 * 4;
public static final int ENTRY_SIZE = 6 * 4;
public static final int TILE__LAST_REGION = (1 << 31);
public static final int TILE__Z_CLEAR = (1 << 30);
public static final int TILE__PRE_SORT = (1 << 29);
public static final int TILE__FLUSH_ACCUMULATE = (1 << 28);
public static int TILE__Y_POSITION(int n) {
return ((n) & 0X3F) << 8;
}
public static int TILE__X_POSITION(int n) {
return ((n) & 0X3F) << 2;
}
public static final int LIST_POINTER__EMPTY = (1 << 31);
public static class OPBSize {
int opaque;
int opaque_modifier_volume;
int translucent;
int translucent_modifier_volume;
int punch_through;
public OPBSize(int opaque,
int opaque_modifier_volume,
int translucent,
int translucent_modifier_volume,
int punch_through)
{
this.opaque = opaque;
this.opaque_modifier_volume = opaque_modifier_volume;
this.translucent = translucent;
this.translucent_modifier_volume = translucent_modifier_volume;
this.punch_through = punch_through;
}
public int total()
{
return opaque
+ opaque_modifier_volume
+ translucent
+ translucent_modifier_volume
+ punch_through;
}
}
public static void region_array(int width, // in tile units (1 tile unit = 32 pixels)
int height, // in tile units (1 tile unit = 32 pixels)
OPBSize[] opb_size,
int num_render_passes,
int region_array_start,
int object_list_start) {
int region_array = MemoryMap.texture_memory32 + region_array_start;
int num_tiles = width * height;
int[] ol_base = new int[num_render_passes];
ol_base[0] = object_list_start;
for (int pass = 1; pass < num_render_passes; pass++) {
ol_base[pass] = ol_base[pass - 1] + num_tiles * opb_size[pass - 1].total();
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int pass = 0; pass < num_render_passes; pass++) {
int tile_value = TILE__Y_POSITION(y)
| TILE__X_POSITION(x);
if (pass == (num_render_passes - 1) && y == (height - 1) && x == (width - 1))
tile_value |= TILE__LAST_REGION;
if (pass != (num_render_passes - 1))
tile_value |= TILE__FLUSH_ACCUMULATE;
if (pass > 0)
tile_value |= TILE__Z_CLEAR;
int tile_index = y * width + x;
int opaque_list_pointer_value =
(opb_size[pass].opaque == 0) ? LIST_POINTER__EMPTY :
(ol_base[pass] + num_tiles * ( 0 )
+ (opb_size[pass].opaque * tile_index));
int opaque_modifier_volume_list_pointer_value =
(opb_size[pass].opaque_modifier_volume == 0) ? LIST_POINTER__EMPTY :
(ol_base[pass] + num_tiles * ( opb_size[pass].opaque )
+ (opb_size[pass].opaque_modifier_volume * tile_index));
int translucent_list_pointer_value =
(opb_size[pass].translucent == 0) ? LIST_POINTER__EMPTY :
(ol_base[pass] + num_tiles * ( opb_size[pass].opaque
+ opb_size[pass].opaque_modifier_volume )
+ (opb_size[pass].translucent * tile_index));
int translucent_modifier_volume_list_pointer_value =
(opb_size[pass].translucent_modifier_volume == 0) ? LIST_POINTER__EMPTY :
(ol_base[pass] + num_tiles * ( opb_size[pass].opaque
+ opb_size[pass].opaque_modifier_volume
+ opb_size[pass].translucent )
+ (opb_size[pass].translucent_modifier_volume * tile_index));
int punch_through_list_pointer_value =
(opb_size[pass].punch_through == 0) ? LIST_POINTER__EMPTY :
(ol_base[pass] + num_tiles * ( opb_size[pass].opaque
+ opb_size[pass].opaque_modifier_volume
+ opb_size[pass].translucent
+ opb_size[pass].translucent_modifier_volume )
+ (opb_size[pass].punch_through * tile_index));
Memory.putU4(region_array + TILE, tile_value);
Memory.putU4(region_array + OPAQUE_LIST_POINTER, opaque_list_pointer_value);
Memory.putU4(region_array + OPAQUE_MODIFIER_VOLUME_LIST_POINTER, opaque_modifier_volume_list_pointer_value);
Memory.putU4(region_array + TRANSLUCENT_LIST_POINTER, translucent_list_pointer_value);
Memory.putU4(region_array + TRANSLUCENT_MODIFIER_VOLUME_LIST_POINTER, translucent_modifier_volume_list_pointer_value);
Memory.putU4(region_array + PUNCH_THROUGH_LIST_POINTER, punch_through_list_pointer_value);
region_array += ENTRY_SIZE;
}
}
}
}
}