example/: add vq and sierpinski

This commit is contained in:
Zack Buhman 2024-05-25 20:42:59 -05:00
parent 40b7c9d800
commit dd5969dc1f
18 changed files with 5067 additions and 4 deletions

View File

@ -8,6 +8,7 @@ CFLAGS += -Wno-array-bounds
#CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds=
CFLAGS += -Wno-error=maybe-uninitialized
CFLAGS += -Wno-error=unused-but-set-variable
CFLAGS += -Wno-error=unused-variable
CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics
@ -52,6 +53,9 @@ endef
%.data.o: %.data
$(BUILD_BINARY_O)
%.data.pal.o: %.data.pal
$(BUILD_BINARY_O)
%.o: %.s
$(AS) $(AARCH) $(AFLAGS) $(DEBUG) $< -o $@

View File

@ -516,3 +516,29 @@ TA_TRANSFER_PROFILE_OBJ = \
example/ta_transfer_profile.elf: LDSCRIPT = $(LIB)/main.lds
example/ta_transfer_profile.elf: $(START_OBJ) $(TA_TRANSFER_PROFILE_OBJ)
VQ_OBJ = \
example/vq.o \
holly/core.o \
holly/region_array.o \
holly/background.o \
holly/ta_fifo_polygon_converter.o \
holly/video_output.o
example/vq.elf: LDSCRIPT = $(LIB)/main.lds
example/vq.elf: $(START_OBJ) $(VQ_OBJ)
SIERPINSKI_OBJ = \
example/sierpinski.o \
holly/core.o \
holly/region_array.o \
holly/background.o \
holly/ta_fifo_polygon_converter.o \
holly/video_output.o \
wolf2.data.o \
wolf2.data.pal.o \
strawberry.data.o \
strawberry.data.pal.o
example/sierpinski.elf: LDSCRIPT = $(LIB)/main.lds
example/sierpinski.elf: $(START_OBJ) $(SIERPINSKI_OBJ)

363
example/sierpinski.cpp Normal file
View File

@ -0,0 +1,363 @@
#include "holly/texture_memory_alloc.hpp"
#include "holly/holly.hpp"
#include "holly/core.hpp"
#include "holly/core_bits.hpp"
#include "holly/ta_fifo_polygon_converter.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/isp_tsp.hpp"
#include "holly/region_array.hpp"
#include "holly/background.hpp"
#include "holly/video_output.hpp"
#include "memorymap.hpp"
#include "twiddle.hpp"
#include "sh7091/store_queue.hpp"
#include "math/vec2.hpp"
#include "wolf2.hpp"
#include "strawberry.hpp"
/*
a
s q
c r b
saq
qbr
rcs
*/
using vec2 = vec<2, float>;
uint32_t tris;
uint32_t max_tris;
void triangle(vec2 a, vec2 b, vec2 c, const uint32_t base_color)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque
| obj_control::col_type::packed_color
| obj_control::shadow
| obj_control::volume::polygon::with_two_volumes
| obj_control::texture;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
| 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_u_size::from_int(1024)
| tsp_instruction_word::texture_v_size::from_int(1024);
const uint32_t texture_address_0 = texture_memory_alloc::texture.start + 1024 * 1024 * 0;
const uint32_t texture_control_word_0 = texture_control_word::pixel_format::_8bpp_palette
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address_0 / 8)
| texture_control_word::palette_selector8(0);
const uint32_t texture_address_1 = texture_memory_alloc::texture.start + 1024 * 1024 * 1;
const uint32_t texture_control_word_1 = texture_control_word::pixel_format::_8bpp_palette
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address_1 / 8)
| texture_control_word::palette_selector8(1);
*reinterpret_cast<ta_global_parameter::polygon_type_3 *>(store_queue) =
ta_global_parameter::polygon_type_3(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word, // tsp_instruction_word_0
texture_control_word_0, // texture_control_word_0
tsp_instruction_word, // tsp_instruction_word_1
texture_control_word_1, // texture_control_word_1
0, // data_size_for_sort_dma
0 // next_address_for_sort_dma
);
sq_transfer_32byte(ta_fifo_polygon_converter);
*reinterpret_cast<ta_vertex_parameter::polygon_type_11 *>(store_queue) =
ta_vertex_parameter::polygon_type_11(polygon_vertex_parameter_control_word(false),
a.x, a.y, 2.0f, // x, y, z
0.5f, 1.0f, // u, v
base_color, 0,
0.5f, 1.0f, // u, v
base_color, 0);
sq_transfer_64byte(ta_fifo_polygon_converter);
*reinterpret_cast<ta_vertex_parameter::polygon_type_11 *>(store_queue) =
ta_vertex_parameter::polygon_type_11(polygon_vertex_parameter_control_word(false),
b.x, b.y, 2.0f, // x, y, z
0.0f, 0.11111975f, // u, v
base_color, 0,
0.0f, 0.11111975f, // u, v
base_color, 0);
sq_transfer_64byte(ta_fifo_polygon_converter);
*reinterpret_cast<ta_vertex_parameter::polygon_type_11 *>(store_queue) =
ta_vertex_parameter::polygon_type_11(polygon_vertex_parameter_control_word(true), // end_of_strip
c.x, c.y, 2.0f, // x, y, z
1.0f, 0.11111975f, // u, v
base_color, 0,
1.0f, 0.11111975f, // u, v
base_color, 0);
sq_transfer_64byte(ta_fifo_polygon_converter);
}
vec2 midpoint(vec2 a, vec2 b)
{
return {(a.x + b.x) / 2.f, (a.y + b.y) / 2.f};
}
constexpr uint32_t yellow = 0xfff0f000;
constexpr uint32_t blue = 0xff0000ff;
constexpr uint32_t green = 0xff00ff00;
void shadow_volume(vec2 a, vec2 b, vec2 c)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque_modifier_volume;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::volume_instruction::normal_polygon
| isp_tsp_instruction_word::culling_mode::no_culling;
*reinterpret_cast<ta_global_parameter::modifier_volume *>(store_queue) =
ta_global_parameter::modifier_volume(parameter_control_word,
isp_tsp_instruction_word
);
sq_transfer_32byte(ta_fifo_polygon_converter);
// top
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
a.x, a.y, 1.0f,
b.x, b.y, 1.0f,
c.x, c.y, 1.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
// at--ab
// \/_\ .
// ct bt bb
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
a.x, a.y, 1.0f,
a.x, a.y, 3.0f,
b.x, b.y, 1.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
a.x, a.y, 3.0f,
b.x, b.y, 3.0f,
b.x, b.y, 1.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
// ab--at
// | / |
// cb--ct bt
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
a.x, a.y, 1.0f,
c.x, c.y, 3.0f,
a.x, a.y, 3.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
a.x, a.y, 1.0f,
c.x, c.y, 1.0f,
c.x, c.y, 3.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
// at
//
// ct--bt
// | \ |
// cb--bb
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
c.x, c.y, 1.0f,
b.x, b.y, 1.0f,
b.x, b.y, 3.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
c.x, c.y, 1.0f,
b.x, b.y, 3.0f,
c.x, c.y, 3.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
const uint32_t last_parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque_modifier_volume
| obj_control::volume::modifier_volume::last_in_volume;
const uint32_t last_isp_tsp_instruction_word = isp_tsp_instruction_word::volume_instruction::inside_last_polygon
| isp_tsp_instruction_word::culling_mode::no_culling;
*reinterpret_cast<ta_global_parameter::modifier_volume *>(store_queue) =
ta_global_parameter::modifier_volume(last_parameter_control_word,
last_isp_tsp_instruction_word
);
sq_transfer_32byte(ta_fifo_polygon_converter);
// bottom
*reinterpret_cast<ta_vertex_parameter::modifier_volume *>(store_queue) =
ta_vertex_parameter::modifier_volume(modifier_volume_vertex_parameter_control_word(),
a.x, a.y, 3.0f,
b.x, b.y, 3.0f,
c.x, c.y, 3.0f);
sq_transfer_64byte(ta_fifo_polygon_converter);
}
void subdivide(vec2 a, vec2 b, vec2 c, int depth)
{
vec2 q = midpoint(a, b);
vec2 r = midpoint(b, c);
vec2 s = midpoint(c, a);
//triangle(s, a, q, green);
//triangle(q, b, r, green);
//triangle(r, c, s, green);
if (depth <= 0)
return;
subdivide(s, a, q, depth - 1);
subdivide(q, b, r, depth - 1);
subdivide(r, c, s, depth - 1);
if (tris++ > max_tris)
return;
shadow_volume(q, r, s);
}
vec2 transform(vec2 v, float theta)
{
v.x -= 320.f;
v.y -= 240.f;
float x = v.x * __builtin_cosf(theta) - v.y * __builtin_sinf(theta);
float y = v.x * __builtin_sinf(theta) + v.y * __builtin_cosf(theta);
return {x + 320.f, y + 240.f};
}
void copy_texture(const uint8_t * src, volatile uint32_t * texture)
{
constexpr uint32_t size = 1024 * 1024 / 4;
uint32_t temp[size];
twiddle::texture(reinterpret_cast<uint8_t *>(temp), src, 1024, 1024);
for (uint32_t i = 0; i < size; i++) {
texture[i] = temp[i];
}
}
void copy_palette(const uint8_t * src, const uint32_t palette)
{
for (uint32_t i = 0; i < 256; i++) {
uint8_t a = 255;
uint8_t r = src[i * 3 + 0];
uint8_t g = src[i * 3 + 1];
uint8_t b = src[i * 3 + 2];
holly.PALETTE_RAM[palette * 256 + i] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
}
}
void copy_textures_palettes()
{
auto texture = reinterpret_cast<volatile uint32_t *>(&texture_memory64[texture_memory_alloc::texture.start / 4]);
auto wolf_src = reinterpret_cast<const uint8_t *>(&_binary_wolf2_data_start);
auto wolf_pal_src = reinterpret_cast<const uint8_t *>(&_binary_wolf2_data_pal_start);
auto wolf_texture = &texture[1024 * 1024 / 4 * 1];
copy_texture(wolf_src, wolf_texture);
copy_palette(wolf_pal_src, 1);
auto strawberry_src = reinterpret_cast<const uint8_t *>(&_binary_strawberry_data_start);
auto strawberry_pal_src = reinterpret_cast<const uint8_t *>(&_binary_strawberry_data_pal_start);
auto strawberry_texture = &texture[1024 * 1024 / 4 * 0];
copy_texture(strawberry_src, strawberry_texture);
copy_palette(strawberry_pal_src, 0);
}
void main()
{
video_output::set_mode_vga();
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::no_list
| ta_alloc_ctrl::om_opb::_16x4byte
| ta_alloc_ctrl::o_opb::_16x4byte;
constexpr struct opb_size opb_size = { .opaque = 16 * 4
, .opaque_modifier = 16 * 4
, .translucent = 0
, .translucent_modifier = 0
, .punch_through = 0
};
holly.SOFTRESET = softreset::pipeline_soft_reset
| softreset::ta_soft_reset;
holly.SOFTRESET = 0;
core_init();
region_array2(640 / 32, 480 / 32, opb_size);
background_parameter(0xff0000ff);
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::argb8888;
holly.FPU_SHAD_SCALE = fpu_shad_scale::simple_shadow_enable::parameter_selection_volume_mode;
copy_textures_palettes();
uint32_t frame_ix = 0;
float theta = 0;
constexpr float half_degree = 0.01745329f / 2.f;
constexpr uint32_t reset_tris = 364 + 1;
max_tris = 0;
uint32_t frame = 0;
while (true) {
tris = 0;
vec2 a = transform({320.000f, 5.f}, theta);
vec2 b = transform({519.186f, 355.f}, theta);
vec2 c = transform({120.814f, 355.f}, theta);
if ((frame++ % 10) == 0) {
if (max_tris > reset_tris) {
max_tris = 0;
}
max_tris += 1;
}
theta += half_degree / 4;
ta_polygon_converter_init(opb_size.total(),
ta_alloc,
640 / 32,
480 / 32);
triangle(a, b, c, yellow);
// end of opaque list
*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);
subdivide(a, b, c, 6);
// end of opaque modifier list
*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);
ta_wait_opaque_modifier_volume_list();
core_start_render(frame_ix);
core_wait_end_of_render_video();
while (!spg_status::vsync(holly.SPG_STATUS));
core_flip(frame_ix);
while (spg_status::vsync(holly.SPG_STATUS));
frame_ix = (frame_ix + 1) & 1;
}
}

181
example/vq.cpp Normal file
View File

@ -0,0 +1,181 @@
#include <cstdint>
#include "align.hpp"
#include "holly/texture_memory_alloc.hpp"
#include "holly/holly.hpp"
#include "holly/core.hpp"
#include "holly/core_bits.hpp"
#include "holly/ta_fifo_polygon_converter.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/isp_tsp.hpp"
#include "holly/region_array.hpp"
#include "holly/background.hpp"
#include "holly/video_output.hpp"
#include "memorymap.hpp"
#include "twiddle.hpp"
#include "vq.hpp"
struct vertex {
float x;
float y;
float u;
float v;
};
const struct vertex strip_vertices[4] = {
// [ position ] [ uv ]
{ 0.5f, -0.5f, 0.f, 0.f},
{ 0.5f, 0.5f, 1.f, 0.f},
{ -0.5f, -0.5f, 0.f, 1.f},
{ -0.5f, 0.5f, 1.f, 1.f},
};
constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex));
uint32_t transform(uint32_t * ta_parameter_buf,
const vertex * strip_vertices,
const uint32_t strip_length)
{
auto parameter = ta_parameter_writer(ta_parameter_buf);
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque
| obj_control::col_type::packed_color
| obj_control::texture;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
| 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_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::vq_compressed
| texture_control_word::pixel_format::_565
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address / 8);
parameter.append<ta_global_parameter::polygon_type_0>() =
ta_global_parameter::polygon_type_0(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word,
0, // data_size_for_sort_dma
0 // next_address_for_sort_dma
);
for (uint32_t i = 0; i < strip_length; i++) {
float x = strip_vertices[i].x;
float y = -strip_vertices[i].y;
float z = 0.1f;
x *= 256.f;
y *= 256.f;
x += 320.f;
y += 240.f;
bool end_of_strip = i == strip_length - 1;
parameter.append<ta_vertex_parameter::polygon_type_3>() =
ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(end_of_strip),
x, y, z,
strip_vertices[i].u,
strip_vertices[i].v,
0,
0 // offset_color
);
}
parameter.append<ta_global_parameter::end_of_list>() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
return parameter.offset;
}
void init_texture_memory(const struct opb_size& opb_size)
{
region_array2(640 / 32, // width
480 / 32, // height
opb_size
);
background_parameter(0xff00ff00);
}
void copy_vq_texture()
{
uint32_t buf[(256 * 4 * 2 + (64 * 64)) / 4];
//auto texture16 = reinterpret_cast<volatile uint16_t *>(&texture_memory64[texture_memory_alloc::texture.start / 4]);
auto texture16 = reinterpret_cast<volatile uint16_t *>(buf);
uint16_t * _codes = &codes[0][0];
for (int i = 0; i < 256 * 4; i++) {
texture16[i] = _codes[i];
}
//auto texture8 = reinterpret_cast<volatile uint8_t *>(&texture16[256 * 4]);
auto texture8 = reinterpret_cast<volatile uint8_t *>(&buf[256 * 4 * 2 / 4]);
twiddle::texture(texture8, indexes, 64, 64);
volatile uint32_t * tex = &texture_memory64[texture_memory_alloc::texture.start / 4];
for (uint32_t i = 0; i < (sizeof (buf)) / 4; i++) {
tex[i] = buf[i];
}
}
uint32_t _ta_parameter_buf[((32 * (strip_length + 2)) + 32) / 4];
void main()
{
video_output::set_mode_vga();
copy_vq_texture();
// The address of `ta_parameter_buf` must be a multiple of 32 bytes.
// This is mandatory for ch2-dma to the ta fifo polygon converter.
uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf);
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::no_list
| ta_alloc_ctrl::om_opb::no_list
| ta_alloc_ctrl::o_opb::_8x4byte;
constexpr struct opb_size opb_size = { .opaque = 8 * 4
, .opaque_modifier = 0
, .translucent = 0
, .translucent_modifier = 0
, .punch_through = 0
};
holly.SOFTRESET = softreset::pipeline_soft_reset
| softreset::ta_soft_reset;
holly.SOFTRESET = 0;
core_init();
init_texture_memory(opb_size);
uint32_t frame_ix = 0;
while (true) {
ta_polygon_converter_init(opb_size.total(),
ta_alloc,
640 / 32,
480 / 32);
uint32_t ta_parameter_size = transform(ta_parameter_buf, strip_vertices, strip_length);
ta_polygon_converter_transfer(ta_parameter_buf, ta_parameter_size);
ta_wait_opaque_list();
core_start_render(frame_ix);
core_wait_end_of_render_video();
while (!spg_status::vsync(holly.SPG_STATUS));
core_flip(frame_ix);
while (spg_status::vsync(holly.SPG_STATUS));
frame_ix = (frame_ix + 1) & 1;
}
}

View File

@ -185,10 +185,14 @@ namespace texture_control_word {
constexpr uint32_t non_twiddled = 1 << 26;
}
constexpr uint32_t palette_selector(uint32_t a) {
constexpr uint32_t palette_selector4(uint32_t a) {
return (a & 0x3f) << 21;
}
constexpr uint32_t palette_selector8(uint32_t a) {
return (a & 0x3) << 25;
}
constexpr uint32_t stride_select = 1 << 25;
// in 8-byte units

104
math/mat2x2.hpp Normal file
View File

@ -0,0 +1,104 @@
#pragma once
#include <utility>
template <int R, int C, typename T>
struct mat;
//
// mat4x4
//
template <typename T>
struct mat<2, 2, T>
{
typedef vec<2, T> row_type;
typedef vec<2, T> col_type;
private:
row_type value[2];
public:
inline constexpr mat();
inline constexpr mat
(
T const& a00, T const& a01,
T const& a10, T const& a11
);
inline static constexpr int length() { return 4; }
inline constexpr typename mat<2, 2, T>::row_type const &
operator[](int i) const;
void operator=(const mat<2, 2, T>&) = delete;
};
template<typename T>
inline constexpr mat<2, 2, T>::mat()
: value{std::move(row_type(1, 0)),
std::move(row_type(0, 1))}
{ }
template<typename T>
inline constexpr mat<2, 2, T>::mat
(
T const& a00, T const& a01,
T const& a10, T const& a11
)
: value{std::move(row_type(a00, a01)),
std::move(row_type(a10, a11))}
{ }
template <typename T>
inline constexpr typename mat<2, 2, T>::row_type const &
mat<2, 2, T>::operator[](int i) const
{
switch (i)
{
default: [[fallthrough]];
case 0:
return value[0];
case 1:
return value[1];
}
}
template<typename T>
inline constexpr mat<2, 2, T> operator*(mat<2, 2, T> const& m1, mat<2, 2, T> const& m2)
{
#define c(i, j) ( \
m1[i][0] * m2[0][j] \
+ m1[i][1] * m2[1][j])
return mat<2, 2, T>(c(0,0), c(0,1),
c(1,0), c(1,1));
#undef c
}
template<typename T>
inline constexpr typename mat<2, 2, T>::row_type operator*
(
mat<2, 2, T> const& m,
typename mat<2, 2, T>::col_type const& v
)
{
#define c(i) ( \
m[i][0] * v[0] \
+ m[i][1] * v[1])
return typename mat<2, 2, T>::row_type(c(0), c(1));
#undef c
}
template<typename T>
inline constexpr mat<2, 2, T> transpose(mat<2, 2, T> const& m)
{
return mat<2, 2, T>(
m[0][0], m[1][0],
m[0][1], m[1][1]
);
}

View File

@ -133,6 +133,12 @@ inline constexpr T dot(vec<2, T> const& v1, vec<2, T> const& v2)
return tmp.x + tmp.y;
}
template <typename T>
inline constexpr T cross(vec<2, T> const& v1, vec<2, T> const& v2)
{
return v1.x * v2.y - v2.x * v1.y;
}
template <typename T>
inline constexpr vec<2, T> functor1(T (&func) (T const& x), vec<2, T> const& v)
{
@ -146,7 +152,7 @@ inline constexpr vec<2, U> functor1(U (&func) (T const& x), vec<2, T> const& v)
}
template <typename T>
inline constexpr T length(vec<2, T> const& v)
inline constexpr T magnitude(vec<2, T> const& v)
{
return sqrt(dot(v, v));
}

View File

@ -160,7 +160,7 @@ inline constexpr vec<3, U> functor1(U (&func) (T const& x), vec<3, T> const& v)
}
template <typename T>
inline constexpr T length(vec<3, T> const& v)
inline constexpr T magnitude(vec<3, T> const& v)
{
return sqrt(dot(v, v));
}

View File

@ -164,7 +164,7 @@ inline constexpr vec<4, U> functor1(U (&func) (T const& x), vec<4, T> const& v)
}
template <typename T>
inline constexpr T length(vec<4, T> const& v)
inline constexpr T magnitude(vec<4, T> const& v)
{
return sqrt(dot(v, v));
}

BIN
strawberry.data Normal file

Binary file not shown.

BIN
strawberry.data.pal Normal file

Binary file not shown.

9
strawberry.hpp Normal file
View File

@ -0,0 +1,9 @@
#include <cstdint>
extern uint32_t _binary_strawberry_data_start __asm("_binary_strawberry_data_start");
extern uint32_t _binary_strawberry_data_end __asm("_binary_strawberry_data_end");
extern uint32_t _binary_strawberry_data_size __asm("_binary_strawberry_data_size");
extern uint32_t _binary_strawberry_data_pal_start __asm("_binary_strawberry_data_pal_start");
extern uint32_t _binary_strawberry_data_pal_end __asm("_binary_strawberry_data_pal_end");
extern uint32_t _binary_strawberry_data_pal_size __asm("_binary_strawberry_data_pal_size");

BIN
strawberry.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

4357
vq.hpp Normal file

File diff suppressed because it is too large Load Diff

BIN
wolf2.data Normal file

Binary file not shown.

BIN
wolf2.data.pal Normal file

Binary file not shown.

9
wolf2.hpp Normal file
View File

@ -0,0 +1,9 @@
#include <cstdint>
extern uint32_t _binary_wolf2_data_start __asm("_binary_wolf2_data_start");
extern uint32_t _binary_wolf2_data_end __asm("_binary_wolf2_data_end");
extern uint32_t _binary_wolf2_data_size __asm("_binary_wolf2_data_size");
extern uint32_t _binary_wolf2_data_pal_start __asm("_binary_wolf2_data_pal_start");
extern uint32_t _binary_wolf2_data_pal_end __asm("_binary_wolf2_data_pal_end");
extern uint32_t _binary_wolf2_data_pal_size __asm("_binary_wolf2_data_pal_size");

BIN
wolf2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB