add pipelined rendering examples

This adds a new texture memory allocation header,
texture_memory_alloc2.hpp, with two of each memory area.

This also adds two new examples, "cube_textured" and "cube_vq" that
demonstrate using the new texture_memory_alloc2 to perform CORE
rendering, geometry transformation, and tile acceleration
concurrently.
This commit is contained in:
Zack Buhman 2024-09-09 04:20:40 -05:00
parent 4aa665b13a
commit 8cead9614f
29 changed files with 1054 additions and 47 deletions

View File

@ -11,6 +11,18 @@ geometry/%.hpp: geometry/%.obj
PYTHONPATH=regs/gen python tools/obj_to_cpp.py $< > $@.tmp PYTHONPATH=regs/gen python tools/obj_to_cpp.py $< > $@.tmp
mv $@.tmp $@ mv $@.tmp $@
%.data.h:
$(BUILD_BINARY_H)
%.data.pal.h:
$(BUILD_BINARY_H)
%.vq.h: %.vq
$(BUILD_BINARY_H)
%.vq.o: %.vq
$(BUILD_BINARY_O)
build-fonts: build-fonts:
./tools/ttf_outline 20 7f 20 0 little /usr/share/fonts/dejavu/DejaVuSans.ttf dejavusansmono.data ./tools/ttf_outline 20 7f 20 0 little /usr/share/fonts/dejavu/DejaVuSans.ttf dejavusansmono.data
./tools/ttf_outline 20 7f 20 1 little /usr/share/fonts/dejavu/DejaVuSans.ttf dejavusansmono_mono.data ./tools/ttf_outline 20 7f 20 1 little /usr/share/fonts/dejavu/DejaVuSans.ttf dejavusansmono_mono.data
@ -19,7 +31,5 @@ build-fonts:
include example/example.mk include example/example.mk
include chess/chess.mk include chess/chess.mk
include text_editor/text_editor.mk include text_editor/text_editor.mk
include snake/snake.mk
include pokemon/pokemon.mk
.PHONY: phony .PHONY: phony

12
base.mk
View File

@ -33,15 +33,17 @@ define BUILD_BINARY_O
$< $@ $< $@
endef endef
as_obj_binary = _binary_$(subst .,_,$(subst /,_,$(1))) makefile_path := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
makefile_relative = $(shell realpath --relative-to $(makefile_path) $(1))
as_obj_binary = _binary_$(subst .,_,$(subst /,_,$(subst .h,,$(call makefile_relative,$(1)))))
define BUILD_BINARY_H define BUILD_BINARY_H
@echo gen $@ @echo gen $(call makefile_relative,$@)
@echo '#pragma once' > $@ @echo '#pragma once' > $@
@echo '#include <cstdint>' >> $@ @echo '#include <cstdint>' >> $@
@echo 'extern uint32_t $(call as_obj_binary,$<)_start __asm("$(call as_obj_binary,$<)_start");' >> $@ @echo 'extern uint32_t $(call as_obj_binary,$@)_start __asm("$(call as_obj_binary,$@)_start");' >> $@
@echo 'extern uint32_t $(call as_obj_binary,$<)_end __asm("$(call as_obj_binary,$<)_end");' >> $@ @echo 'extern uint32_t $(call as_obj_binary,$@)_end __asm("$(call as_obj_binary,$@)_end");' >> $@
@echo 'extern uint32_t $(call as_obj_binary,$<)_size __asm("$(call as_obj_binary,$<)_size");' >> $@ @echo 'extern uint32_t $(call as_obj_binary,$@)_size __asm("$(call as_obj_binary,$@)_size");' >> $@
endef endef
%.bin.o: %.bin %.bin.o: %.bin

View File

@ -4,8 +4,8 @@ import sys
import time import time
#dest = 0xac21_0000 #dest = 0xac21_0000
#dest = 0xac02_0000 dest = 0xac02_0000
dest = 0xac01_0000 #dest = 0xac01_0000
ret = [] ret = []
@ -34,7 +34,7 @@ def symmetric(ser, b):
l = [] l = []
mem = memoryview(b) mem = memoryview(b)
i = 0 i = 0
chunk_size = 384 chunk_size = 8
while i < len(b): while i < len(b):
if i % 1024 == 0: if i % 1024 == 0:
@ -73,6 +73,8 @@ def start_data(ser, b):
ret = sync(ser, b'DATA' + args) ret = sync(ser, b'DATA' + args)
if ret != b'data\n': if ret != b'data\n':
print(".", end=' ') print(".", end=' ')
print(ret)
time.sleep(1)
sys.stdout.flush() sys.stdout.flush()
sync(ser, b'prime', wait=0) sync(ser, b'prime', wait=0)
start_data(ser, b) start_data(ser, b)
@ -89,7 +91,8 @@ def do(ser, b):
duration = end - start duration = end - start
print("\n\nduration:", duration, "\n\n") print("\n\nduration:", duration, "\n\n")
print(ret[-5:]) print(ret[-5:])
if ret[:-5] != b: print(len(b), len(ret))
if ret[:-5] != b and False:
print("ret != b; dumped to asdf.bin") print("ret != b; dumped to asdf.bin")
with open('asdf.bin', 'wb') as f: with open('asdf.bin', 'wb') as f:
f.write(ret[:-5]) f.write(ret[:-5])
@ -97,7 +100,8 @@ def do(ser, b):
return return
args = struct.pack("<I", dest) args = struct.pack("<I", dest)
ret = sync(ser, b'JUMP' + args, wait=0) print("JUMP")
ret = sync(ser, b'JUMP' + args, wait=1)
print() print()
console(ser) console(ser)
@ -176,8 +180,8 @@ def change_rate(old_rate, new_rate):
ret = sync(ser, b'RATE' + args, wait=1) ret = sync(ser, b'RATE' + args, wait=1)
print(ret) print(ret)
old_rate = 1 old_rate = 4
new_rate = 1 new_rate = 4
if old_rate != new_rate: if old_rate != new_rate:
change_rate(old_rate, new_rate) change_rate(old_rate, new_rate)
@ -188,8 +192,8 @@ with serial.Serial(port='/dev/ttyUSB0',
stopbits=serial.STOPBITS_ONE, stopbits=serial.STOPBITS_ONE,
timeout=1, timeout=1,
xonxoff=False, xonxoff=False,
#rtscts=False, rtscts=False,
rtscts=True, #rtscts=True,
) as ser: ) as ser:
#console(ser) #console(ser)
print("waiting: ", end=' ') print("waiting: ", end=' ')

34
color_format.hpp Normal file
View File

@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
namespace color_format {
uint16_t argb4444(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
{
int a4 = (a >> 4) & 15;
int r4 = (r >> 4) & 15;
int g4 = (g >> 4) & 15;
int b4 = (b >> 4) & 15;
return (a4 << 12) | (r4 << 8) | (g4 << 4) | (b4 << 0);
}
uint16_t argb1555(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
{
int a1 = (a >> 7) & 1;
int r5 = (r >> 3) & 31;
int g5 = (g >> 3) & 31;
int b5 = (b >> 3) & 31;
return (a1 << 15) | (r5 << 10) | (g5 << 5) | (b5 << 0);
}
uint16_t rgb565(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
{
int r5 = (r >> 3) & 31;
int g6 = (g >> 2) & 63;
int b5 = (b >> 3) & 31;
return (r5 << 11) | (g6 << 5) | (b5 << 0);
}
}

View File

@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
DIR := $(dir $(MAKEFILE_PATH)) DIR := $(dir $(MAKEFILE_PATH))
LIB ?= . LIB ?= .
OPT ?= -O3 OPT ?= -O0
GENERATED ?= GENERATED ?=
AARCH = --isa=sh4 --little AARCH = --isa=sh4 --little

239
example/cube_textured.cpp Normal file
View File

@ -0,0 +1,239 @@
#include <cstdint>
#include "holly/isp_tsp.hpp"
#include "holly/ta_parameter.hpp"
#include "holly/ta_global_parameter.hpp"
#include "holly/ta_vertex_parameter.hpp"
#include "holly/ta_bits.hpp"
#include "holly/ta_fifo_polygon_converter.hpp"
#include "holly/holly.hpp"
#include "holly/core_bits.hpp"
#include "holly/core.hpp"
#include "holly/region_array.hpp"
#include "holly/background.hpp"
#include "holly/video_output.hpp"
#include "holly/texture_memory_alloc2.hpp"
#include "sh7091/store_queue.hpp"
#include "sh7091/serial.hpp"
#include "twiddle.hpp"
#include "math/vec2.hpp"
#include "texture/cube/wn.data.h"
#include "texture/cube/wn.data.pal.h"
#include "model/cube_material.h"
#include "model/cube.h"
void transfer_scene(float theta)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::translucent
| obj_control::col_type::intensity_mode_1
| obj_control::texture
| obj_control::gouraud;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::src_alpha
| tsp_instruction_word::dst_alpha_instr::inverse_src_alpha
| tsp_instruction_word::fog_control::no_fog
| tsp_instruction_word::use_alpha
| tsp_instruction_word::texture_shading_instruction::modulate_alpha
| tsp_instruction_word::texture_u_size::from_int(128)
| tsp_instruction_word::texture_v_size::from_int(128);
const uint32_t texture_address = texture_memory_alloc::texture.start;
const uint32_t texture_control_word = texture_control_word::pixel_format::_8bpp_palette
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address / 8);
for (int j = 0; j < cube_model.object_count; j++) {
*reinterpret_cast<ta_global_parameter::polygon_type_1 *>(store_queue) =
ta_global_parameter::polygon_type_1(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word, // texture_control_word
0.5, // face color alpha
1.0, // face color r
1.0, // face color g
1.0 // face color b
);
sq_transfer_32byte(ta_fifo_polygon_converter);
struct object * object = cube_model.object[j];
for (int i = 0; i < object->triangle_count; i++) {
for (int k = 0; k < 3; k++) {
int position_ix = object->triangle[i].v[k].position;
float x0 = cube_model.position[position_ix].x;
float y0 = cube_model.position[position_ix].y;
float z0 = cube_model.position[position_ix].z;
float x1 = x0 * cos(theta) - z0 * sin(theta);
float y1 = y0;
float z1 = x0 * sin(theta) + z0 * cos(theta);
float x = x1;
float y = y1 * cos(theta) - z1 * sin(theta);
float z = y1 * sin(theta) + z1 * cos(theta);
z += 3;
x /= z;
y /= z;
// do rotation
x = x * 240 + 320;
y = y * 240 + 240;
z = 1/z;
bool end_of_strip = k == 2;
int texture_ix = object->triangle[i].v[k].texture;
float u = cube_model.texture[texture_ix].u;
float v = cube_model.texture[texture_ix].v;
*reinterpret_cast<ta_vertex_parameter::polygon_type_7 *>(store_queue) =
ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(end_of_strip),
x, y, z,
u, v,
1.0, // base intensity
1.0 // offset intensity
);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
}
}
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
void texture_init()
{
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::argb1555;
int material_count = (sizeof (material)) / (sizeof (material[0]));
for (int i = 0; i < material_count; i++) {
uint32_t offset = texture_memory_alloc::texture.start + material[i].pixel.vram_offset;
/*
twiddle::texture3<8, 8>(&texture_memory64[offset / 4],
(uint32_t *)material[i].pixel.start,
material[i].pixel.width,
material[i].pixel.size);
*/
twiddle::texture((uint8_t *)&texture_memory64[offset / 4],
(uint8_t *)material[i].pixel.start,
material[i].pixel.width,
material[i].pixel.height);
};
for (int i = 0; i < material[0].palette.size / 2; i++) {
holly.PALETTE_RAM[i] = ((uint16_t*)material[0].palette.start)[i];
}
}
void main()
{
serial::init(0);
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::_16x4byte
| ta_alloc_ctrl::om_opb::no_list
| ta_alloc_ctrl::o_opb::no_list;
constexpr int render_passes = 1;
constexpr struct opb_size opb_size[render_passes] = {
{
.opaque = 0,
.opaque_modifier = 0,
.translucent = 16 * 4,
.translucent_modifier = 0,
.punch_through = 0
}
};
holly.SOFTRESET = softreset::pipeline_soft_reset
| softreset::ta_soft_reset;
holly.SOFTRESET = 0;
core_init();
video_output::set_mode_vga();
constexpr int framebuffer_width = 640;
constexpr int framebuffer_height = 480;
constexpr int tile_width = framebuffer_width / 32;
constexpr int tile_height = framebuffer_height / 32;
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[0].start,
texture_memory_alloc::object_list[0].start);
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[1].start,
texture_memory_alloc::object_list[1].start);
background_parameter2(texture_memory_alloc::background[0].start,
0xff220033);
background_parameter2(texture_memory_alloc::background[1].start,
0xff220033);
texture_init();
const float degree = 0.017453292519943295;
float theta = 0;
int ta = -1;
int core = -2;
while (1) {
if (core >= 0) {
// core = 0 ; core = 1
// ta = 1 ; ta = 0
core_wait_end_of_render_video();
while (!spg_status::vsync(holly.SPG_STATUS));
holly.FB_R_SOF1 = texture_memory_alloc::framebuffer[core].start;
while (spg_status::vsync(holly.SPG_STATUS));
}
// core = -2 ; core = 1 ; core = 0
// ta = -1 ; ta = 0 ; ta = 1
core += 1;
ta += 1;
if (core > 1) core = 0;
if (ta > 1) ta = 0;
if (core >= 0) {
// core = 1 ; core = 0
// ta = 0 ; ta = 1
ta_wait_translucent_list();
core_start_render2(texture_memory_alloc::region_array[core].start,
texture_memory_alloc::isp_tsp_parameters[core].start,
texture_memory_alloc::background[core].start,
texture_memory_alloc::framebuffer[core].start,
framebuffer_width);
}
// core = -1 ; core = 1 ; core = 0
// ta = 0 ; ta = 0 ; ta = 1
ta_polygon_converter_init2(texture_memory_alloc::isp_tsp_parameters[ta].start,
texture_memory_alloc::isp_tsp_parameters[ta].end,
texture_memory_alloc::object_list[ta].start,
texture_memory_alloc::object_list[ta].end,
opb_size[1].total(),
ta_alloc,
tile_width,
tile_height);
transfer_scene(theta);
theta += degree;
}
}

236
example/cube_vq.cpp Normal file
View File

@ -0,0 +1,236 @@
#include <cstdint>
#include "holly/isp_tsp.hpp"
#include "holly/ta_parameter.hpp"
#include "holly/ta_global_parameter.hpp"
#include "holly/ta_vertex_parameter.hpp"
#include "holly/ta_bits.hpp"
#include "holly/ta_fifo_polygon_converter.hpp"
#include "holly/holly.hpp"
#include "holly/core_bits.hpp"
#include "holly/core.hpp"
#include "holly/region_array.hpp"
#include "holly/background.hpp"
#include "holly/video_output.hpp"
#include "holly/texture_memory_alloc2.hpp"
#include "sh7091/store_queue.hpp"
#include "sh7091/serial.hpp"
#include "twiddle.hpp"
#include "math/vec2.hpp"
#include "texture/panda/panda.vq.h"
enum material {
wn,
};
#include "model/cube.h"
void transfer_scene(float theta)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::translucent
| obj_control::col_type::intensity_mode_1
| obj_control::texture
| obj_control::gouraud;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
| tsp_instruction_word::fog_control::no_fog
| tsp_instruction_word::texture_shading_instruction::modulate
| tsp_instruction_word::flip_uv::u
| tsp_instruction_word::texture_u_size::from_int(512)
| tsp_instruction_word::texture_v_size::from_int(512);
const uint32_t texture_address = texture_memory_alloc::texture.start;
const uint32_t texture_control_word = texture_control_word::vq_compressed
| texture_control_word::pixel_format::_565
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address / 8);
for (int j = 0; j < cube_model.object_count; j++) {
*reinterpret_cast<ta_global_parameter::polygon_type_1 *>(store_queue) =
ta_global_parameter::polygon_type_1(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word, // texture_control_word
1.0, // face color alpha
1.0, // face color r
1.0, // face color g
1.0 // face color b
);
sq_transfer_32byte(ta_fifo_polygon_converter);
struct object * object = cube_model.object[j];
for (int i = 0; i < object->triangle_count; i++) {
for (int k = 0; k < 3; k++) {
int position_ix = object->triangle[i].v[k].position;
float x0 = cube_model.position[position_ix].x;
float y0 = cube_model.position[position_ix].y;
float z0 = cube_model.position[position_ix].z;
float x1 = x0 * cos(theta) - z0 * sin(theta);
float y1 = y0;
float z1 = x0 * sin(theta) + z0 * cos(theta);
float x = x1;
float y = y1 * cos(theta) - z1 * sin(theta);
float z = y1 * sin(theta) + z1 * cos(theta);
z += 2.4;
x /= z;
y /= z;
// do rotation
x = x * 240 + 320;
y = y * 240 + 240;
z = 1/z;
bool end_of_strip = k == 2;
int texture_ix = object->triangle[i].v[k].texture;
float u = cube_model.texture[texture_ix].u;
float v = cube_model.texture[texture_ix].v;
*reinterpret_cast<ta_vertex_parameter::polygon_type_7 *>(store_queue) =
ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(end_of_strip),
x, y, z,
u, v,
1.0, // base intensity
1.0 // offset intensity
);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
}
}
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
template <typename T>
inline void copy(T * dst, const T * src, const int32_t n) noexcept
{
int32_t n_t = n / (sizeof (T));
while (n_t > 0) {
*dst++ = *src++;
n_t--;
}
}
void texture_init()
{
uint32_t offset = texture_memory_alloc::texture.start;
copy<volatile uint32_t>(&texture_memory64[offset / 4],
reinterpret_cast<uint32_t *>(&_binary_texture_panda_panda_vq_start),
reinterpret_cast<int>(&_binary_texture_panda_panda_vq_size));
}
void main()
{
serial::init(0);
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::_16x4byte
| ta_alloc_ctrl::om_opb::no_list
| ta_alloc_ctrl::o_opb::no_list;
constexpr int render_passes = 1;
constexpr struct opb_size opb_size[render_passes] = {
{
.opaque = 0,
.opaque_modifier = 0,
.translucent = 16 * 4,
.translucent_modifier = 0,
.punch_through = 0
}
};
holly.SOFTRESET = softreset::pipeline_soft_reset
| softreset::ta_soft_reset;
holly.SOFTRESET = 0;
core_init();
video_output::set_mode_vga();
constexpr int framebuffer_width = 640;
constexpr int framebuffer_height = 480;
constexpr int tile_width = framebuffer_width / 32;
constexpr int tile_height = framebuffer_height / 32;
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[0].start,
texture_memory_alloc::object_list[0].start);
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[1].start,
texture_memory_alloc::object_list[1].start);
background_parameter2(texture_memory_alloc::background[0].start,
0xff220033);
background_parameter2(texture_memory_alloc::background[1].start,
0xff220033);
texture_init();
const float degree = 0.017453292519943295;
float theta = 0;
int ta = -1;
int core = -2;
while (1) {
if (core >= 0) {
// core = 0 ; core = 1
// ta = 1 ; ta = 0
core_wait_end_of_render_video();
while (!spg_status::vsync(holly.SPG_STATUS));
holly.FB_R_SOF1 = texture_memory_alloc::framebuffer[core].start;
while (spg_status::vsync(holly.SPG_STATUS));
}
// core = -2 ; core = 1 ; core = 0
// ta = -1 ; ta = 0 ; ta = 1
core += 1;
ta += 1;
if (core > 1) core = 0;
if (ta > 1) ta = 0;
if (core >= 0) {
// core = 1 ; core = 0
// ta = 0 ; ta = 1
ta_wait_translucent_list();
core_start_render2(texture_memory_alloc::region_array[core].start,
texture_memory_alloc::isp_tsp_parameters[core].start,
texture_memory_alloc::background[core].start,
texture_memory_alloc::framebuffer[core].start,
framebuffer_width);
}
// core = -1 ; core = 1 ; core = 0
// ta = 0 ; ta = 0 ; ta = 1
ta_polygon_converter_init2(texture_memory_alloc::isp_tsp_parameters[ta].start,
texture_memory_alloc::isp_tsp_parameters[ta].end,
texture_memory_alloc::object_list[ta].start,
texture_memory_alloc::object_list[ta].end,
opb_size[1].total(),
ta_alloc,
tile_width,
tile_height);
transfer_scene(theta);
//theta += degree;
}
}

View File

@ -538,7 +538,8 @@ SIERPINSKI_OBJ = \
wolf2.data.o \ wolf2.data.o \
wolf2.data.pal.o \ wolf2.data.pal.o \
strawberry.data.o \ strawberry.data.o \
strawberry.data.pal.o strawberry.data.pal.o \
$(LIBGCC)
example/sierpinski.elf: LDSCRIPT = $(LIB)/main.lds example/sierpinski.elf: LDSCRIPT = $(LIB)/main.lds
example/sierpinski.elf: $(START_OBJ) $(SIERPINSKI_OBJ) example/sierpinski.elf: $(START_OBJ) $(SIERPINSKI_OBJ)
@ -553,3 +554,30 @@ TETRAHEDRON_OBJ = \
example/tetrahedron.elf: LDSCRIPT = $(LIB)/main.lds example/tetrahedron.elf: LDSCRIPT = $(LIB)/main.lds
example/tetrahedron.elf: $(START_OBJ) $(TETRAHEDRON_OBJ) example/tetrahedron.elf: $(START_OBJ) $(TETRAHEDRON_OBJ)
CUBE_TEXTURED_OBJ = \
example/cube_textured.o \
holly/core.o \
holly/region_array.o \
holly/background.o \
holly/ta_fifo_polygon_converter.o \
holly/video_output.o \
sh7091/serial.o \
texture/cube/wn.data.o \
texture/cube/wn.data.pal.o
example/cube_textured.elf: LDSCRIPT = $(LIB)/main.lds
example/cube_textured.elf: $(START_OBJ) $(CUBE_TEXTURED_OBJ)
CUBE_VQ_OBJ = \
example/cube_vq.o \
holly/core.o \
holly/region_array.o \
holly/background.o \
holly/ta_fifo_polygon_converter.o \
holly/video_output.o \
sh7091/serial.o \
texture/panda/panda.vq.o
example/cube_vq.elf: LDSCRIPT = $(LIB)/alt.lds
example/cube_vq.elf: $(START_OBJ) $(CUBE_VQ_OBJ)

View File

@ -20,10 +20,11 @@ struct isp_tsp_parameter {
static_assert((sizeof (isp_tsp_parameter)) == (4 * 3 + 3) * 4); static_assert((sizeof (isp_tsp_parameter)) == (4 * 3 + 3) * 4);
void background_parameter(const uint32_t color) void background_parameter2(const uint32_t background_start,
const uint32_t color)
{ {
auto parameter = reinterpret_cast<volatile isp_tsp_parameter *> auto parameter = reinterpret_cast<volatile isp_tsp_parameter *>
(&texture_memory32[texture_memory_alloc::background.start / 4]); (&texture_memory32[background_start / 4]);
parameter->isp_tsp_instruction_word parameter->isp_tsp_instruction_word
= isp_tsp_instruction_word::depth_compare_mode::always = isp_tsp_instruction_word::depth_compare_mode::always
@ -52,3 +53,10 @@ void background_parameter(const uint32_t color)
parameter->vertex[2].z = 1.f/100000; parameter->vertex[2].z = 1.f/100000;
parameter->vertex[2].base_color = color; parameter->vertex[2].base_color = color;
} }
void background_parameter(const uint32_t color)
{
background_parameter2(texture_memory_alloc::background.start,
color);
}

View File

@ -2,4 +2,6 @@
#include <cstdint> #include <cstdint>
void background_parameter2(const uint32_t background_start,
const uint32_t color);
void background_parameter(const uint32_t color); void background_parameter(const uint32_t color);

View File

@ -74,8 +74,6 @@ void core_start_render(uint32_t frame_address,
holly.STARTRENDER = 1; holly.STARTRENDER = 1;
} }
constexpr uint32_t framebuffer_frame_size = 0x00096000 * 2;
void core_start_render(uint32_t frame_ix) void core_start_render(uint32_t frame_ix)
{ {
core_start_render(texture_memory_alloc::framebuffer[frame_ix].start, core_start_render(texture_memory_alloc::framebuffer[frame_ix].start,
@ -83,6 +81,31 @@ void core_start_render(uint32_t frame_ix)
); );
} }
void core_start_render2(uint32_t region_array_start,
uint32_t isp_tsp_parameters_start,
uint32_t background_start,
uint32_t frame_address,
uint32_t frame_width // in pixels
)
{
holly.REGION_BASE = region_array_start;
holly.PARAM_BASE = isp_tsp_parameters_start;
uint32_t background_offset = background_start - isp_tsp_parameters_start;
holly.ISP_BACKGND_T = isp_backgnd_t::tag_address(background_offset / 4)
| isp_backgnd_t::tag_offset(0)
| isp_backgnd_t::skip(1);
holly.ISP_BACKGND_D = _i(1.f/100000.f);
holly.FB_W_CTRL = fb_w_ctrl::fb_dither | fb_w_ctrl::fb_packmode::_565_rgb_16bit;
constexpr uint32_t bytes_per_pixel = 2;
holly.FB_W_LINESTRIDE = (frame_width * bytes_per_pixel) / 8;
holly.FB_W_SOF1 = frame_address;
holly.STARTRENDER = 1;
}
void core_wait_end_of_render_video() void core_wait_end_of_render_video()
{ {
/* /*

View File

@ -7,5 +7,12 @@ void core_start_render(uint32_t frame_address,
void core_start_render(uint32_t frame_ix); void core_start_render(uint32_t frame_ix);
void core_start_render2(uint32_t region_array_start,
uint32_t isp_tsp_parameters_start,
uint32_t background_start,
uint32_t frame_address,
uint32_t frame_width // in pixels
);
void core_wait_end_of_render_video(); void core_wait_end_of_render_video();
void core_flip(uint32_t frame_ix); void core_flip(uint32_t frame_ix);

View File

@ -4,27 +4,6 @@
#include "texture_memory_alloc.hpp" #include "texture_memory_alloc.hpp"
#include "memorymap.hpp" #include "memorymap.hpp"
#define REGION_ARRAY__LAST_REGION (1 << 31)
#define REGION_ARRAY__Z_CLEAR (1 << 30)
#define REGION_ARRAY__PRE_SORT (1 << 29)
#define REGION_ARRAY__FLUSH_ACCUMULATE (1 << 28)
#define REGION_ARRAY__TILE_Y_POSITION(n) (((n) & 0x3f) << 8)
#define REGION_ARRAY__TILE_X_POSITION(n) (((n) & 0x3f) << 2)
#define REGION_ARRAY__LIST_POINTER__EMPTY (1 << 31)
#define REGION_ARRAY__LIST_POINTER(n) ((n) & 0xfffffc)
// this is for a "type 2" region array.
// region header type is specified in FPU_PARAM_CFG
struct region_array_entry {
uint32_t tile; /* 3.7.7 page 216 */
uint32_t opaque_list_pointer;
uint32_t opaque_modifier_volume_list_pointer;
uint32_t translucent_list_pointer;
uint32_t translucent_modifier_volume_list_pointer;
uint32_t punch_through_list_pointer;
};
// opaque list pointer offset: OPB size * tile index * 4 // opaque list pointer offset: OPB size * tile index * 4
void region_array(const uint32_t width, // in tile units (1 tile unit = 32 pixels) void region_array(const uint32_t width, // in tile units (1 tile unit = 32 pixels)
@ -141,15 +120,17 @@ void region_array2(const uint32_t width, // in tile units (1 tile unit = 32 pix
void region_array_multipass(const uint32_t width, // in tile units (1 tile unit = 32 pixels) void region_array_multipass(const uint32_t width, // in tile units (1 tile unit = 32 pixels)
const uint32_t height, // in tile units (1 tile unit = 32 pixels) const uint32_t height, // in tile units (1 tile unit = 32 pixels)
const struct opb_size * opb_size, const struct opb_size * opb_size,
const uint32_t num_render_passes) const uint32_t num_render_passes,
const uint32_t region_array_start,
const uint32_t object_list_start)
{ {
auto region_array = reinterpret_cast<volatile region_array_entry *> auto region_array = reinterpret_cast<volatile region_array_entry *>
(&texture_memory32[texture_memory_alloc::region_array.start / 4]); (&texture_memory32[region_array_start / 4]);
const uint32_t num_tiles = width * height; const uint32_t num_tiles = width * height;
uint32_t ol_base[num_render_passes]; uint32_t ol_base[num_render_passes];
ol_base[0] = texture_memory_alloc::object_list.start; ol_base[0] = object_list_start;
for (uint32_t pass = 1; pass < num_render_passes; pass++) { for (uint32_t pass = 1; pass < num_render_passes; pass++) {
ol_base[pass] = ol_base[pass - 1] + num_tiles * opb_size[pass - 1].total(); ol_base[pass] = ol_base[pass - 1] + num_tiles * opb_size[pass - 1].total();
} }

View File

@ -2,6 +2,27 @@
#include <cstdint> #include <cstdint>
#define REGION_ARRAY__LAST_REGION (1 << 31)
#define REGION_ARRAY__Z_CLEAR (1 << 30)
#define REGION_ARRAY__PRE_SORT (1 << 29)
#define REGION_ARRAY__FLUSH_ACCUMULATE (1 << 28)
#define REGION_ARRAY__TILE_Y_POSITION(n) (((n) & 0x3f) << 8)
#define REGION_ARRAY__TILE_X_POSITION(n) (((n) & 0x3f) << 2)
#define REGION_ARRAY__LIST_POINTER__EMPTY (1 << 31)
#define REGION_ARRAY__LIST_POINTER(n) ((n) & 0xfffffc)
// this is for a "type 2" region array.
// region header type is specified in FPU_PARAM_CFG
struct region_array_entry {
uint32_t tile; /* 3.7.7 page 216 */
uint32_t opaque_list_pointer;
uint32_t opaque_modifier_volume_list_pointer;
uint32_t translucent_list_pointer;
uint32_t translucent_modifier_volume_list_pointer;
uint32_t punch_through_list_pointer;
};
struct opb_size { struct opb_size {
uint32_t opaque; uint32_t opaque;
uint32_t opaque_modifier; uint32_t opaque_modifier;
@ -29,4 +50,6 @@ void region_array2(const uint32_t width, // in tile units (1 tile unit = 32 pix
void region_array_multipass(const uint32_t width, // in tile units (1 tile unit = 32 pixels) void region_array_multipass(const uint32_t width, // in tile units (1 tile unit = 32 pixels)
const uint32_t height, // in tile units (1 tile unit = 32 pixels) const uint32_t height, // in tile units (1 tile unit = 32 pixels)
const struct opb_size * opb_size, const struct opb_size * opb_size,
const uint32_t num_render_passes); const uint32_t num_render_passes,
const uint32_t region_array_start,
const uint32_t object_list_start);

View File

@ -41,6 +41,39 @@ void ta_polygon_converter_init(uint32_t opb_total_size, // for one tile, for all
(void)_dummy_read; (void)_dummy_read;
} }
void ta_polygon_converter_init2(uint32_t isp_tsp_parameters_start,
uint32_t isp_tsp_parameters_end,
uint32_t object_list_start,
uint32_t object_list_end,
uint32_t opb_total_size, // for one tile, for all render passes
uint32_t ta_alloc,
uint32_t tile_width, // in tile units (e.g: (640 / 32))
uint32_t tile_height) // in tile units (e.g: (480 / 32))
{
// opb_size is the total size of all OPBs for all passes
const uint32_t ta_next_opb_offset = opb_total_size * tile_width * tile_height;
holly.SOFTRESET = softreset::ta_soft_reset;
holly.SOFTRESET = 0;
holly.TA_GLOB_TILE_CLIP = ta_glob_tile_clip::tile_y_num(tile_height - 1)
| ta_glob_tile_clip::tile_x_num(tile_width - 1);
holly.TA_ALLOC_CTRL = ta_alloc_ctrl::opb_mode::increasing_addresses
| ta_alloc;
holly.TA_ISP_BASE = isp_tsp_parameters_start;
holly.TA_ISP_LIMIT = isp_tsp_parameters_end; // the end of isp_tsp_parameters
holly.TA_OL_BASE = object_list_start;
holly.TA_OL_LIMIT = object_list_end; // the end of the object_list
holly.TA_NEXT_OPB_INIT = object_list_start + ta_next_opb_offset;
holly.TA_LIST_INIT = ta_list_init::list_init;
uint32_t _dummy_read = holly.TA_LIST_INIT;
(void)_dummy_read;
}
void ta_polygon_converter_cont(uint32_t ol_base_offset, void ta_polygon_converter_cont(uint32_t ol_base_offset,
uint32_t ta_alloc) uint32_t ta_alloc)
{ {

View File

@ -6,6 +6,15 @@ void ta_polygon_converter_init(uint32_t opb_total_size, // for one tile, for all
uint32_t ta_alloc, uint32_t ta_alloc,
uint32_t tile_width, // in tile units (e.g: (640 / 32)) uint32_t tile_width, // in tile units (e.g: (640 / 32))
uint32_t tile_height); // in tile units (e.g: (480 / 32)) uint32_t tile_height); // in tile units (e.g: (480 / 32))
void ta_polygon_converter_init2(uint32_t isp_tsp_parameters_start,
uint32_t isp_tsp_parameters_end,
uint32_t object_list_start,
uint32_t object_list_end,
uint32_t opb_total_size, // for one tile, for all render passes
uint32_t ta_alloc,
uint32_t tile_width, // in tile units (e.g: (640 / 32))
uint32_t tile_height); // in tile units (e.g: (480 / 32))
void ta_polygon_converter_cont(uint32_t ol_base_offset, void ta_polygon_converter_cont(uint32_t ol_base_offset,
uint32_t ta_alloc); uint32_t ta_alloc);
void ta_polygon_converter_transfer(volatile uint32_t const * const buf, uint32_t size); void ta_polygon_converter_transfer(volatile uint32_t const * const buf, uint32_t size);

View File

@ -0,0 +1,86 @@
#pragma once
#include <cstdint>
#include <cstddef>
/*
* A 0x10000-byte region array is sufficient for 9 render passes:
*
* ((640 / 32) * (480 / 32) * 6 * 4) * 9 == 0xfd20
*/
namespace texture_memory_alloc {
constexpr uint32_t address_64to32(uint32_t addr)
{
uint32_t value = ((addr & 0xfffffff8) >> 1) + (addr & 0x3);
if ((addr & 0x4) != 0)
value += 0x400000;
if (addr >= 0x800000)
value += 0x400000;
return value;
}
struct start_end {
uint32_t start;
uint32_t end;
};
constexpr start_end isp_tsp_parameters[2] = {
{ // bus A
.start = 0x00'0000,
.end = 0x0f'ffc0,
},
{ // bus B
.start = 0x40'0000,
.end = 0x4f'ffc0,
},
};
constexpr start_end background[2] = {
{
.start = 0x0f'ffc0,
.end = 0x10'0000,
},
{
.start = 0x4f'ffc0,
.end = 0x50'0000,
},
};
constexpr start_end object_list[2] = {
{ // bus A
.start = 0x10'0000,
.end = 0x20'0000 - 0x10,
},
{ // bus B
.start = 0x50'0000,
.end = 0x60'0000 - 0x10,
}
};
constexpr start_end framebuffer[2] = {
{ // bus A
.start = 0x20'0000,
.end = 0x29'6000,
},
{ // bus B
.start = 0x60'0000,
.end = 0x69'6000,
}
};
constexpr start_end region_array[2] = {
{ // bus A
.start = 0x29'6000,
.end = 0x2a'6000,
},
{ // bus B
.start = 0x69'6000,
.end = 0x6a'6000,
},
};
// 64-bit transfer
constexpr start_end texture = {
.start = 0x54'c000,
.end = 0x80'0000,
};
}

119
model/cube.h Normal file
View File

@ -0,0 +1,119 @@
#include <stddef.h>
#include "model.h"
// floating-point
vertex_position cube_position[] = {
{1.0, 1.0, -1.0},
{1.0, -1.0, -1.0},
{1.0, 1.0, 1.0},
{1.0, -1.0, 1.0},
{-1.0, 1.0, -1.0},
{-1.0, -1.0, -1.0},
{-1.0, 1.0, 1.0},
{-1.0, -1.0, 1.0},
};
// floating-point
vertex_texture cube_texture[] = {
{1.0, 0.0},
{0.0, 1.0},
{0.0, 0.0},
{1.0, 1.0},
{0.0, 0.0},
{1.0, 0.0},
};
// floating-point
vertex_normal cube_normal[] = {
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0},
{-1.0, 0.0, 0.0},
{0.0, -1.0, 0.0},
{1.0, 0.0, 0.0},
{0.0, 0.0, -1.0},
};
union triangle cube_knight_triangle[] = {
{ .v = {
{4, 0, 0},
{2, 1, 0},
{0, 2, 0},
}},
{ .v = {
{2, 3, 1},
{7, 4, 1},
{3, 5, 1},
}},
{ .v = {
{6, 3, 2},
{5, 4, 2},
{7, 5, 2},
}},
{ .v = {
{1, 0, 3},
{7, 1, 3},
{5, 2, 3},
}},
{ .v = {
{0, 3, 4},
{3, 4, 4},
{1, 5, 4},
}},
{ .v = {
{4, 3, 5},
{1, 4, 5},
{5, 5, 5},
}},
{ .v = {
{4, 0, 0},
{6, 3, 0},
{2, 1, 0},
}},
{ .v = {
{2, 3, 1},
{6, 1, 1},
{7, 4, 1},
}},
{ .v = {
{6, 3, 2},
{4, 1, 2},
{5, 4, 2},
}},
{ .v = {
{1, 0, 3},
{3, 3, 3},
{7, 1, 3},
}},
{ .v = {
{0, 3, 4},
{2, 1, 4},
{3, 4, 4},
}},
{ .v = {
{4, 3, 5},
{0, 1, 5},
{1, 4, 5},
}},
};
struct object cube_knight = {
.triangle = &cube_knight_triangle[0],
.quadrilateral = NULL,
.triangle_count = 12,
.quadrilateral_count = 0,
.material = wn,
};
struct object * cube_object_list[] = {
&cube_knight,
};
struct model cube_model = {
.position = &cube_position[0],
.texture = &cube_texture[0],
.normal = &cube_normal[0],
.object = &cube_object_list[0],
.object_count = 1,
};

28
model/cube_material.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
#include <stdint.h>
#include "model/material.h"
enum material {
wn,
};
struct material_descriptor material[] = {
[wn] = {
.pixel = {
.start = (uint8_t *)&_binary_texture_cube_wn_data_start,
.size = (int)&_binary_texture_cube_wn_data_size,
.vram_offset = 0,
.width = 128,
.height = 128,
},
.palette = {
.start = (uint8_t *)&_binary_texture_cube_wn_data_pal_start,
.size = (int)&_binary_texture_cube_wn_data_pal_size,
.vram_offset = 0,
.palette_size = 256,
},
},
};

25
model/material.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <stdint.h>
struct pixel_descriptor {
uint8_t * start;
int32_t size;
int32_t vram_offset; // offset into vram texture address space
int16_t width;
int16_t height;
};
struct palette_descriptor {
uint8_t * start;
int32_t size;
int32_t vram_offset; // offset into vram palette address space
int32_t palette_size;
};
struct material_descriptor {
struct pixel_descriptor pixel;
struct palette_descriptor palette;
};

53
model/model.h Normal file
View File

@ -0,0 +1,53 @@
#pragma once
#include <stdint.h>
#include "math/vec3.hpp"
#include "math/vec2.hpp"
struct index_ptn {
uint16_t position;
uint16_t texture;
uint16_t normal;
};
union triangle {
struct {
struct index_ptn a;
struct index_ptn b;
struct index_ptn c;
};
struct index_ptn v[3];
};
union quadrilateral {
struct {
struct index_ptn a;
struct index_ptn b;
struct index_ptn c;
struct index_ptn d;
};
struct index_ptn v[4];
};
using vertex_position = vec<3, float>;
using vertex_normal = vec<3, float>;
using vertex_texture = vec<2, float>;
struct object {
union triangle * triangle;
union quadrilateral * quadrilateral;
int triangle_count;
int quadrilateral_count;
int material;
};
struct model {
vertex_position * position;
vertex_texture * texture;
vertex_normal * normal;
struct object ** object;
int object_count;
};

Binary file not shown.

42
texture/cube/wn.data Normal file
View File

@ -0,0 +1,42 @@
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹T繉圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�\儋賷圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�+藤种賷圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹W僦儋腺�圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�{僦儋晕賵圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!≠踪僮形賵圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!)荣儋僮佑钨�圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�  ?儋儋僮佑游賵圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�_僦儋僮佑佑钨�!!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� 斮踪儋钟佑佑钨�  圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!
;儋儋儋杂佑佑游賸;1$  !圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹
氋踪儋儆佑佑佑有僭始�`D/ 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�k僮儋儋钟佑佑佑佑杏宰儋偎硴jD) 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�K儋儋儋子佑佑佑佑佑有行行灾蕴簹qF)
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 H儋儋儋子佑佑佑佑佑佑佑佑有杏佑丝瓡d5 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 X儋踪儋杂佑佑佑佑佑佑佑佑佑佑有釉允腑�; 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� n儋踪僮佑佑佑佑佑佑佑佑佑佑佑佑佑有栽什─p4
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!囐儋儋钟佑佑佑佑佑佑佑佑佑佑佑佑佑佑有栽抹àe) 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 嬞仲儋钟佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉谐‖擝 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 j僦儋僭佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑有又隆ぉk! 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�
;儋儋僦佑佑佑行挝杏佑佑佑佑佑佑佑佑佑佑佑佑佑性失毉�4 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹溬仲僮佑佑佑性儋僮杏佑佑佑佑佑佑佑佑佑佑佑佑佑性苇毃烡 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 >儋儋僭佑佑有傥杦吔傩佑佑佑佑佑佑佑佑佑佑佑佑佑有杂畾かW
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�冑仲僭佑佑游佗6
!w傩佑佑佑佑佑佑佑佑佑佑佑佑佑有孕瑸~] 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�(馁儋儆佑佑钨�
y傩佑佑佑佑佑佑佑佑佑佑佑佑佑有晕�‖^ 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹U僮儋杂佑有卓, )恐杏佑佑佑佑佑佑佑佑佑佑佑佑佑性龋 琜
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�! 栙刭儆佑佑钨^捹杏佑佑佑佑佑佑佑佑佑佑佑佑佑有挚煛~S 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� .速儋钟佑有俚!氋杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉盁 �>
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹Z僮儋杂佑游賚!F钟佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉衰 �,圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹! 樫踪儆佑佑佑9  K手杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑兄綗�﹦圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹1匈儋钟佑有佾 2XaZKDZ椯孕佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑药 灜\ 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�f僦儋杂佑有賵o匈儋僦儋行佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑姓罒 。8 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�ㄙ踪儆佑佑釉速招涡杏行佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑熄 煥�圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� ?儋儋子佑佑佑孕杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑有崭煟�玃
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�
撡刭僭佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉佑佑佑佑佑佑佑佑佑佑釉省 ˉ�'圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�
=儋儋儆佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑蕴卧佑佑佑佑佑佑佑佑佑佑营煛�琕 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 捹仲僦佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑有Э中佑佑佑佑佑佑佑佑佑兄粸!ˉ�'圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�! @儋儋儆佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑有志毜杂佑佑佑佑佑佑佑佑佑釉啤 �琕
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�踪僭佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑酝��佑佑佑佑佑佑佑佑佑佑孕Α ˉ�!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹m僦儋杂佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑有缘煛�佑佑佑佑佑佑佑佑佑佑诱瓱 �〦 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 >儋儋钟佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑郧 々杏佑佑佑佑佑佑佑佑佑有侄灒 煩|圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!官踪子佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑瑹!ㄐ佑佑佑佑佑佑佑佑佑佑兄緷! �/圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�僦儋佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑有志煟 ㄐ佑佑佑佑佑佑佑佑佑佑以谩  煬T 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�O儇儋杂佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑刑ァ 煭佑佑佑佑佑佑佑佑佑佑佑匀  �﹡!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹",瀑踪杂佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑匈碁!�吃佑佑佑佑佑佑佑佑佑佑釉剩  。�- 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 欃仲钟佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑匈摍ぁ。灱中佑佑佑佑佑佑佑佑佑佑蕴ぁ  煫I 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�d僦僮佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑游贁 Z瑹 ∑杂佑佑佑佑佑佑佑佑佑佑孕ぁ  煭i 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� :踪儋佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑游佴啫 ね杂佑佑佑佑佑佑佑佑佑佑孕ぁ  ¨�圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�踪杂佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑游俑.  ?�煭沼佑佑佑佑佑佑佑佑佑佑釉肖   �.圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹僦僭佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑钨�2 啫毢中佑佑佑佑佑佑佑佑佑佑釉亭   ¨@ 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹D儋僦佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑钨�3  P瑸旁佑佑佑佑佑佑佑佑佑佑佑运!  �璚圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�"*临刈佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑钨�3  2煥姓佑佑佑佑佑佑佑佑佑佑佑陨   �琸圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 撡仲佑佑佑佑佑佑佑佑釉杂佑佑佑佑佑佑唾�0 圹!!徆杂佑佑佑佑佑佑佑佑佑佑右悦    ▇圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹_儇僭佑佑佑佑佑佑佑釉优试杂佑佑佑佑行贉) 圹�~稍杏佑佑佑佑佑佑佑佑佑佑兄緹!  ˉ�!!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� 4淤僭佑佑佑佑佑佑佑诱协潱�栽杏佑有钨賩圹圹!勛杏佑佑佑佑佑佑佑佑佑佑有指灒   �+圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!
撡种佑佑佑佑佑佑佑佑远殻�〉卧有形再笻 圹圹圹!椯杏佑佑佑佑佑佑佑佑佑佑佑员煟   !3 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹*速钟佑佑佑佑佑佑佑釉剩  煔ダ灾儋苢& !圹圹圹�&甲杏佑佑佑佑佑佑佑佑佑佑佑惜    ˉ>
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�
?儋佑佑佑佑佑佑佑佑姓笧�(�é�漛,圹圹圹� H傩佑佑佑佑佑佑佑佑佑佑佑釉伞    〃A 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�J儆杏佑佑佑佑佑佑佑友�々�_MD@;+!圹圹圹圹
愘杏佑佑佑佑佑佑佑佑佑佑有志潱   �獽 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�
>杂佑佑佑佑佑佑佑佑云。﹐0 
圹圹圹圹�
;杂佑佑佑佑佑佑佑佑佑佑佑佑辕煟   �璔圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!!阶杏佑佑佑佑佑佑有猿煠M !圹圹圹圹圹
撡杏佑佑佑佑佑佑佑佑佑佑佑酝ァ    灜U圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 n偎佑佑佑佑佑佑佑酝)K圹圹圹圹圹圹圹Q傩佑佑佑佑佑佑佑佑佑佑佑有志煟    灟V圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!�托佑佑佑佑佑有侄ゝ
圹圹圹圹圹圹圹圹圹 1磷杏佑佑佑佑佑佑佑佑佑佑佑佑獰    �疺圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!+欃傥杏佑佑佑佑允珝圹圹圹圹圹圹圹圹圹!�杏佑佑佑佑佑佑佑佑佑佑佑釉啤     灜T圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹Y官傩涡佑佑有猿�>
!圹圹圹圹圹圹圹圹圹 溬斡佑佑佑佑佑佑佑佑佑佑佑佑园煟    �獽 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!\χ儋游涡性铆e 圹圹圹圹圹圹圹圹� )澷斡佑佑佑佑佑佑佑佑佑佑佑佑郧      〃C 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹>r�儋字谐�!圹圹圹圹圹圹圹圹�!/操斡佑佑佑佑佑佑佑佑佑佑佑佑釉睙!     �8 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� =c尫朔�,!圹圹圹圹圹圹圹圹?抠斡佑佑佑佑佑佑佑佑佑佑佑佑性谩      �*圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� 
 !,3%圹圹圹圹圹圹圹圹 U匈斡佑佑佑佑佑佑佑佑佑佑佑佑佑蝎煛     ¨�!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� ! 圹圹圹圹圹圹圹�r僭杏佑佑佑佑佑佑佑佑佑佑佑佑有愿煟     �﹛!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!!!!圹圹圹圹圹圹圹� !曎行佑佑佑佑佑佑佑佑佑佑佑佑佑釉剩      �璦 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�0�斡佑佑佑佑佑佑佑佑佑佑佑佑佑佑原煟      煩G 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹#>抠斡佑佑佑佑佑佑佑佑佑佑佑佑佑有曰煟       �3 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!E姓斡佑佑佑佑佑佑佑佑佑佑佑佑佑有陨        �圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�K又杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑孕�       煫q!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹N自杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑性禐!      �璚 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�I自杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑姓隆        ˉ< 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 E性杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉抬        ·�$圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� 7俗杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑援潱       �﹛!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹#)蒂斡佑佑佑佑佑佑佑佑佑佑佑佑佑佑有掷煟        煭T 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� 栙斡佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑酝ァ         �9 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� g傥佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑园煟        ˉ�!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�
9性杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑匀         �琻圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹氋斡佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉瓱         煫K 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 R傩佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑有阅煛         �/ 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!�杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉療!        〃�!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹R傩佑佑佑佑行行行行行形挝挝挝挝挝挝信煙         煭] 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹澷涡形涡杏栽灾踪儋儋儋儋儋儋儋儋儋儋篓�èДぃ �灍煛  �=
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�  =赵踪儋儋僦兴饶涵牅棐媼亐亇vvvvu~個€坰px}儔悧殲·ì��В。�$圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹u偾弧弢i]OD;1*$!
!'.4<BKYdp~憵》v !圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹?A,! 

*8T9 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹  
!!$)--2555<>>>>>65550.)$!!   圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹
 )9DTfs儜洤�了涡性栽再儋匮僭栽杂形颓汲珰拠zl_N?2'  圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹! .Gh厺晃踪儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋允稙協D* 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� >vㄎ儋儋儋儋字种肿鬃儋儋儋儋儋儋儋儇儋儋儋儋儋僮鬃种肿儋儋儋儋偻焗2
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� C氋儋儋种踪儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋字仲儋僭�9 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� $堎儋肿儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋僮仲儋g
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!*操鬃儋儋儋儋僮字衷栽栽栽杂佑佑佑佑佑佑佑佑佑佑佑佑栽栽栽栽灾肿踪儋儋儋僦儋� 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹①再儋字栽杂佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑栽栽鬃儋踪l 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�h僭衷佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑釉宰�9
圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹)馁杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑唾� !圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹W傥佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑性�,圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹� 娰斡佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑匈S圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!�杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑钨u圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!*稍杏佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑匈�!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�!
9性佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑匈�圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 @杂佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑匈�!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 G仔佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑凶�!!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹M傩佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑兄�$!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹L傩佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑兄�$!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹L傩佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑佑兄�$!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹K滞挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝挝陀�$!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹R儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋儋�&!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹 7ytvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvtwo!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹!圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹�圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹

5
texture/cube/wn.data.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <cstdint>
extern uint32_t _binary_texture_cube_wn_data_start __asm("_binary_texture_cube_wn_data_start");
extern uint32_t _binary_texture_cube_wn_data_end __asm("_binary_texture_cube_wn_data_end");
extern uint32_t _binary_texture_cube_wn_data_size __asm("_binary_texture_cube_wn_data_size");

BIN
texture/cube/wn.data.pal Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
#pragma once
#include <cstdint>
extern uint32_t _binary_texture_cube_wn_data_pal_start __asm("_binary_texture_cube_wn_data_pal_start");
extern uint32_t _binary_texture_cube_wn_data_pal_end __asm("_binary_texture_cube_wn_data_pal_end");
extern uint32_t _binary_texture_cube_wn_data_pal_size __asm("_binary_texture_cube_wn_data_pal_size");

BIN
texture/cube/wn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
texture/panda/panda.vq Normal file

Binary file not shown.

5
texture/panda/panda.vq.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <cstdint>
extern uint32_t _binary_texture_panda_panda_vq_start __asm("_binary_texture_panda_panda_vq_start");
extern uint32_t _binary_texture_panda_panda_vq_end __asm("_binary_texture_panda_panda_vq_end");
extern uint32_t _binary_texture_panda_panda_vq_size __asm("_binary_texture_panda_panda_vq_size");