diff --git a/.gitignore b/.gitignore index 206b71c..6e25a20 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ __pycache__ *.gch *.blend1 *.scramble -*.FCStd1 \ No newline at end of file +*.FCStd1 +*.data +*_128.png \ No newline at end of file diff --git a/build_textures.sh b/build_textures.sh new file mode 100644 index 0000000..b667ed8 --- /dev/null +++ b/build_textures.sh @@ -0,0 +1,15 @@ +set -eux + +for i in texture/*.png; do + j=$(echo $i | cut -d. -f1).data + python ~/model_generator/color_convert.py $i rgb565 twiddled non_mipmapped $j + make ${j}.h +done + +rm -f texture/walking/*128.png +for i in texture/walking/*.png; do + j=$(echo $i | cut -d. -f1) + python ~/physics_engine/tools/canvas_size.py $i 128 32 ${j}_128.png + python ~/model_generator/color_convert.py ${j}_128.png argb4444 twiddled non_mipmapped ${j}_128.data + make ${j}_128.data.h +done diff --git a/demo.mk b/demo.mk index f5552c5..615abe3 100644 --- a/demo.mk +++ b/demo.mk @@ -1,6 +1,18 @@ FONT_OBJ = \ font/ter_u12n.data.o +TEXTURE_OBJ = \ + texture/igh25_box_top_32.data.o \ + texture/igh25_box_bottom_32.data.o \ + texture/igh25_box_side_32.data.o \ + texture/walking/frame0000_128.data.o \ + texture/walking/frame0001_128.data.o \ + texture/walking/frame0002_128.data.o \ + texture/walking/frame0003_128.data.o \ + texture/walking/frame0004_128.data.o \ + texture/walking/frame0005_128.data.o \ + texture/walking/frame0006_128.data.o + DEMO_OBJ = \ $(LIB)/holly/core.o \ $(LIB)/holly/region_array.o \ @@ -23,6 +35,8 @@ DEMO_OBJ = \ src/demo/bridge.o \ src/demo/sailboat.o \ src/demo/collision.o \ + src/demo/lizard/main.o \ + src/demo/lizard/world.o \ src/physics/particle.o \ src/physics/particle_link.o \ src/physics/particle_contact.o \ @@ -31,4 +45,16 @@ DEMO_OBJ = \ src/physics/collide.o demo.elf: LDSCRIPT = $(LIB)/main.lds -demo.elf: $(START_OBJ) $(DEMO_OBJ) $(FONT_OBJ) $(LIBGCC) +demo.elf: $(START_OBJ) $(DEMO_OBJ) $(FONT_OBJ) $(TEXTURE_OBJ) $(LIBGCC) + +%_128.png: %.png + python tools/canvas_size.py $< 128 32 $@ + +texture/igh25_box_%.data: texture/igh25_box_%.png + python ../model_generator/color_convert.py $< rgb565 twiddled non_mipmapped $@ + +texture/walking/%.data: texture/walking/%.png + python ../model_generator/color_convert.py $< argb4444 twiddled non_mipmapped $@ + +font/ter_u12n.data: + $(LIB)/tools/ttf_bitmap2 20 7f 128 64 /usr/share/fonts/terminus/ter-u12n.otb $@ > /dev/null diff --git a/font/ter_u12n.data b/font/ter_u12n.data deleted file mode 100644 index 1d01af8..0000000 Binary files a/font/ter_u12n.data and /dev/null differ diff --git a/src/demo/bridge.cpp b/src/demo/bridge.cpp index 6a3f50d..4d40380 100644 --- a/src/demo/bridge.cpp +++ b/src/demo/bridge.cpp @@ -102,7 +102,7 @@ namespace demo { printf("en cables %d\n", en_cables); } - void bridge::analog(float dx) { + void bridge::analog(float dl, float dr, float dx, float dy) { interpolator.interp_add(dx * 0.5f); } diff --git a/src/demo/bridge.hpp b/src/demo/bridge.hpp index ecd03a5..294ddd1 100644 --- a/src/demo/bridge.hpp +++ b/src/demo/bridge.hpp @@ -25,7 +25,7 @@ namespace demo { void draw_weight(ta_parameter_writer& writer, const mat4x4& trans); void draw(ta_parameter_writer& writer, const mat4x4& trans) override; void a() override; - void analog(float dx) override; + void analog(float dl, float dr, float dx, float dy) override; static const inline int particles_length = 12; physics::particle particles[particles_length]; diff --git a/src/demo/lizard/levels.hpp b/src/demo/lizard/levels.hpp new file mode 100644 index 0000000..b94a1b9 --- /dev/null +++ b/src/demo/lizard/levels.hpp @@ -0,0 +1,28 @@ +#include "demo/lizard/world.hpp" + +namespace demo { + + world::platform level1_platforms[] = { + { + .position = vec3( 7.500, 0.000, 7.500), + .scale = vec3( 3.000, 1.000, 3.000), + }, + { + .position = vec3( 12.500, 0.000, 7.500), + .scale = vec3( 3.000, 1.000, 3.000), + }, + { + .position = vec3( 17.500, 0.000, 7.500), + .scale = vec3( 3.000, 1.000, 3.000), + }, + { + .position = vec3( 12.500, 0.000, 12.500), + .scale = vec3( 3.000, 1.000, 3.000), + }, + }; + world::level level1_level = { + .platforms = level1_platforms, + .platforms_length = (sizeof (level1_platforms)) / (sizeof (world::platform)), + }; + +} diff --git a/src/demo/lizard/main.cpp b/src/demo/lizard/main.cpp new file mode 100644 index 0000000..37f74e2 --- /dev/null +++ b/src/demo/lizard/main.cpp @@ -0,0 +1,228 @@ +#include "math/float_types.hpp" +#include "math/transform.hpp" + +#include "platform/graphics_primitive.hpp" +#include "platform/font.hpp" + +#include "demo/lizard/main.hpp" +#include "demo/lizard/levels.hpp" + +#include "texture/igh25_box_top_32.data.h" + +#include "assert.h" + +extern float alpha_mul; + +const int lizard_frames[] = { + texture::offset::walking_frame0000, + texture::offset::walking_frame0001, + texture::offset::walking_frame0002, + texture::offset::walking_frame0003, + texture::offset::walking_frame0004, + texture::offset::walking_frame0005, + texture::offset::walking_frame0006, +}; +const int lizard_frames_count = (sizeof (lizard_frames)) / (sizeof (lizard_frames[0])); +int last_drawn_frame; + +namespace demo { + static inline void print_mat4x4(const mat4x4& mat) + { + for (int i = 0; i < 4; i++) { + printf("%f %f %f %f\n", mat[i][0], mat[i][1], mat[i][2], mat[i][3]); + } + } + + mat4x4 lizard::init() + { + vx = 0; + vy = 0; + + current_level = &demo::level1_level; + + world::table_build(*current_level); + + lizard_position = {7.5, 1, 7.5}; + lizard_velocity = {0, 0, 0}; + + return view_trans; + } + + static float sign(float n) + { + if (n > 0) + return 1; + else + return -1; + } + + void lizard::update() + { + /* + if (!collided) + lizard_velocity.y -= 0.01; + */ + + if (abs(lizard_velocity.x) > 0.05) + lizard_velocity.x = 0.05 * sign(lizard_velocity.x); + if (abs(lizard_velocity.y) > 0.05) + lizard_velocity.y = 0.05 * sign(lizard_velocity.y); + if (abs(lizard_velocity.z) > 0.05) + lizard_velocity.z = 0.05 * sign(lizard_velocity.z); + + lizard_velocity.x *= 0.8; + lizard_velocity.y *= 0.8; + lizard_velocity.z *= 0.8; + + lizard_frame += magnitude(lizard_velocity) * 15; + + lizard_position.x += lizard_velocity.x; + lizard_position.y += lizard_velocity.y; + lizard_position.z += lizard_velocity.z; + + world::platform * p = lizard_collide(); + collided = p != nullptr; + + if (collided) { + lizard_position.y -= -lizard_velocity.y; + } + + view_trans + = translate(vec3(0, 0, 3)) + * rotate_x(vy) + * rotate_y(vx) + * translate(-lizard_position); + } + + void lizard::y() + { + lizard_velocity.y += 0.01; + } + + void lizard::a() + { + lizard_velocity.y -= 0.01; + } + + void lizard::x() + { + lizard_heading -= pi * (1.0f / 160); + } + + void lizard::b() + { + lizard_heading += pi * (1.0f / 160); + } + + void lizard::analog(float dl, float dr, float dx, float dy) + { + //float forward = (dr - dl) * -0.001f; + //alpha_mul += forward; + float forward = (dr - dl) * -0.04f; + + lizard_velocity.x += -cos(lizard_heading) * forward; + lizard_velocity.z += sin(lizard_heading) * forward; + + vy += dy * 0.03f; + vx += dx * 0.03f; + } + + world::platform * lizard::lizard_collide() + { + world::platform * p = world::table_lookup(lizard_position.x, lizard_position.z); + if (p == nullptr) + return nullptr; + + float ym = lizard_position.y - 0.5; + float yp = lizard_position.y + 0.5; + + float pm = p->position.y - p->scale.y * 0.5; + float pp = p->position.y + p->scale.y * 0.5; + + if (ym < pp && yp > pm) + return p; + else + return nullptr; + } + + void lizard::draw_hud(ta_parameter_writer& writer) + { + const int title_length = 8; + const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1; + const int framebuffer_width_2 = framebuffer::framebuffer.px_width >> 1; + const int x = framebuffer_width_2 - title_width_2; + vec3 center_p = vec3(x, 5, 10); + + font::ter_u12n.global(writer); + font::ter_u12n.draw_string(writer, center_p, "platform", 0xffffffff); + + vec3 status_p = vec3(10, 10, 10); + /* + if (collided) + font::ter_u12n.draw_string(writer, status_p, "collide", 0xffffffff); + else + font::ter_u12n.draw_string(writer, status_p, "air", 0xffffffff); + */ + + font::ter_u12n.draw_float(writer, status_p, (float)last_drawn_frame, 0xffffffff, 10); + } + + void lizard::draw_platform(ta_parameter_writer& writer, const mat4x4& trans, const world::platform& p) + { + mat4x4 t + = trans + * translate(p.position) + * scale(p.scale); + + draw_textured_cube(writer, + t, + p.scale, + texture::cube_type_1); + } + + void lizard::draw_lizard(ta_parameter_writer& writer, const mat4x4& trans) + { + mat4x4 t + = trans + * translate(lizard_position) + * rotate_y(lizard_heading); + + /* + draw_icosphere(writer, + t, + vec3(1, 0.5, 0)); + */ + int frame = ((int)lizard_frame) % lizard_frames_count; + if (frame < 0) + frame = lizard_frames_count + frame; + last_drawn_frame = frame; + + draw_textured_voxel(writer, + t, + lizard_frames[frame]); + } + + void lizard::draw(ta_parameter_writer& writer, const mat4x4& _) + { + // punch through + const mat4x4& trans = view_trans; + + draw_hud(writer); + + draw_lizard(writer, trans); + + writer.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + + // opaque + + //draw_axis(writer, trans * translate(lizard_position)); + + for (int i = 0; i < current_level->platforms_length; i++) { + draw_platform(writer, trans, current_level->platforms[i]); + } + + writer.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + } +} diff --git a/src/demo/lizard/main.hpp b/src/demo/lizard/main.hpp new file mode 100644 index 0000000..7f58461 --- /dev/null +++ b/src/demo/lizard/main.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "demo/scene.hpp" +#include "demo/lizard/world.hpp" + +namespace demo { + + struct lizard : scene { + world::level * current_level; + vec3 lizard_position; + vec3 lizard_velocity; + float lizard_heading; + float lizard_frame; + + bool collided; + + mat4x4 view_trans; + + float vx; + float vy; + + mat4x4 init() override; + + void update() override; + + void y() override; + void x() override; + void b() override; + void a() override; + + void analog(float dl, float dr, float dx, float dy) override; + + world::platform * lizard_collide(); + + void draw_hud(ta_parameter_writer& writer); + void draw_platform(ta_parameter_writer& writer, const mat4x4& trans, const world::platform& p); + void draw_lizard(ta_parameter_writer& writer, const mat4x4& trans); + void draw(ta_parameter_writer& writer, const mat4x4& trans) override; + }; +} diff --git a/src/demo/lizard/maps/level1.png b/src/demo/lizard/maps/level1.png new file mode 100644 index 0000000..c45f563 Binary files /dev/null and b/src/demo/lizard/maps/level1.png differ diff --git a/src/demo/lizard/world.cpp b/src/demo/lizard/world.cpp new file mode 100644 index 0000000..30ba1dc --- /dev/null +++ b/src/demo/lizard/world.cpp @@ -0,0 +1,109 @@ +#include + +#include "demo/lizard/world.hpp" +#include "assert.h" + +namespace demo::world { + + struct min_max { + int x_min; + int x_max; + int z_min; + int z_max; + }; + + static platform_lookup lookup; + + static inline void clear_table() + { + for (int i = 0; i < lookup_table_dim * lookup_table_dim; i++) { + lookup.table[i] = nullptr; + } + } + + static inline bool float_equal_int(float f) + { + int i = (int)f; + float fi = (float)i; + return fi == f; + } + + static inline min_max calculate_platforms_area(const level& level) + { + float x_min = std::numeric_limits::max(); + float x_max = std::numeric_limits::min(); + + float z_min = std::numeric_limits::max(); + float z_max = std::numeric_limits::min(); + + for (int i = 0; i < level.platforms_length; i++) { + const vec3& position = level.platforms[i].position; + float scale_x_2 = level.platforms[i].scale.x * 0.5; + float scale_z_2 = level.platforms[i].scale.z * 0.5; + + if (position.x - scale_x_2 < x_min) + x_min = position.x - scale_x_2; + if (position.x + scale_x_2 > x_max) + x_max = position.x + scale_x_2; + if (position.z - scale_z_2 < z_min) + z_min = position.z - scale_z_2; + if (position.z + scale_z_2 > z_max) + z_max = position.z + scale_z_2; + } + + assert(float_equal_int(x_min)); + assert(float_equal_int(x_max)); + assert(float_equal_int(z_min)); + assert(float_equal_int(z_max)); + + return { + (int)x_min, + (int)x_max, + (int)z_min, + (int)z_max, + }; + } + + void table_build(const level& level) + { + clear_table(); + min_max mm = calculate_platforms_area(level); + + lookup.xz_offset = vec2i(mm.x_min, mm.z_min); + lookup.size = vec2i(mm.x_max - mm.x_min, + mm.z_max - mm.z_min); + + for (int i = 0; i < level.platforms_length; i++) { + const vec3& position = level.platforms[i].position; + int scale_x = (int)level.platforms[i].scale.x; + int scale_z = (int)level.platforms[i].scale.z; + float scale_x_2 = level.platforms[i].scale.x * 0.5; + float scale_z_2 = level.platforms[i].scale.z * 0.5; + + for (int xo = 0; xo < scale_x; xo++) { + for (int zo = 0; zo < scale_z; zo++) { + int x = xo + (int)(position.x - scale_x_2) - mm.x_min; + int z = zo + (int)(position.z - scale_z_2) - mm.z_min; + assert(x >= 0); + assert(z >= 0); + assert(x < lookup.size.x); + assert(z < lookup.size.y); + + lookup.table[z * lookup.size.x + x] = &level.platforms[i]; + } + } + } + } + + platform * table_lookup(float x, float z) + { + int xi = ((int)x) - lookup.xz_offset.x; + int zi = ((int)z) - lookup.xz_offset.y; + + if (xi < 0 || zi < 0 || xi >= lookup.size.x || zi >= lookup.size.y) { + return nullptr; + } + + return lookup.table[zi * lookup.size.x + xi]; + } +} diff --git a/src/demo/lizard/world.hpp b/src/demo/lizard/world.hpp new file mode 100644 index 0000000..c661e7a --- /dev/null +++ b/src/demo/lizard/world.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "math/float_types.hpp" + +namespace demo::world { + + using vec2i = vec<2, int>; + + struct platform { + vec3 position; + vec3 scale; + }; + + struct level { + platform * platforms; + int platforms_length; + }; + + constexpr int lookup_table_dim = 128; + + struct platform_lookup { + vec2i xz_offset; + vec2i size; + platform * table[lookup_table_dim * lookup_table_dim]; + }; + + void table_build(const level& level); + platform * table_lookup(float x, float z); +} diff --git a/src/demo/scene.hpp b/src/demo/scene.hpp index 968745a..1e1c53d 100644 --- a/src/demo/scene.hpp +++ b/src/demo/scene.hpp @@ -7,11 +7,15 @@ namespace demo { struct scene { virtual mat4x4 init() = 0; - virtual void analog(float dx) {} + virtual void analog(float dl, float dr, float dx, float dy) {} virtual void a() {} virtual void b() {} virtual void x() {} virtual void y() {} + virtual void ra() {} + virtual void la() {} + virtual void da() {} + virtual void ua() {} virtual void update() = 0; virtual void draw(ta_parameter_writer& writer, const mat4x4& trans) = 0; }; diff --git a/src/platform/font.cpp b/src/platform/font.cpp index 655c19e..c56c57d 100644 --- a/src/platform/font.cpp +++ b/src/platform/font.cpp @@ -83,10 +83,10 @@ namespace font { int32_t whole = num; offset += unparse_base10_unsigned(&s[offset], whole, 0, 0); s[offset++] = '.'; - int32_t fraction = (int32_t)((num - (float)whole) * 1000.0); + int32_t fraction = (int32_t)((num - (float)whole) * 1000000000.0); if (fraction < 0) fraction = -fraction; - offset += unparse_base10_unsigned(&s[offset], fraction, 3, '0'); + offset += unparse_base10_unsigned(&s[offset], fraction, 9, '0'); return offset; } diff --git a/src/platform/graphics.cpp b/src/platform/graphics.cpp index 757413f..92dd19e 100644 --- a/src/platform/graphics.cpp +++ b/src/platform/graphics.cpp @@ -27,6 +27,7 @@ #include "demo/bridge.hpp" #include "demo/sailboat.hpp" #include "demo/collision.hpp" +#include "demo/lizard/main.hpp" #include "maple/maple_bus_bits.hpp" @@ -94,14 +95,19 @@ namespace graphics { } } + /* demo::ballistics _ballistics; demo::bridge _bridge; demo::sailboat _sailboat; demo::collision _collision; - demo::scene * current_scene = &_collision; + */ + demo::lizard _lizard; + demo::scene * current_scene = &_lizard; void draw() { + holly.PT_ALPHA_REF = 15; + current_scene->draw(writer, view_trans * scale(0.05f)); } @@ -172,25 +178,39 @@ namespace graphics { auto& data = data_fields.data; - float dx = static_cast(data.analog_coordinate_axis[2] - 0x80) * 0.001; - float dy = static_cast(data.analog_coordinate_axis[3] - 0x80) * 0.001; + float dl = static_cast(data.analog_coordinate_axis[0]) * (1.f / 255.f); + float dr = static_cast(data.analog_coordinate_axis[1]) * (1.f / 255.f); + float dx = static_cast(data.analog_coordinate_axis[2] - 0x80) * (1.f / 128.f); + float dy = static_cast(data.analog_coordinate_axis[3] - 0x80) * (1.f / 128.f); bool a = ft0::data_transfer::digital_button::a(data.digital_button) == 0; bool b = ft0::data_transfer::digital_button::b(data.digital_button) == 0; bool x = ft0::data_transfer::digital_button::x(data.digital_button) == 0; bool y = ft0::data_transfer::digital_button::y(data.digital_button) == 0; - if (last[port_ix].a == 0 && a) current_scene->a(); - if (last[port_ix].b == 0 && b) current_scene->b(); - if (last[port_ix].x == 0 && x) current_scene->x(); - if (last[port_ix].y == 0 && y) current_scene->y(); + + bool ra = ft0::data_transfer::digital_button::ra(data.digital_button) == 0; + bool la = ft0::data_transfer::digital_button::la(data.digital_button) == 0; + bool da = ft0::data_transfer::digital_button::da(data.digital_button) == 0; + bool ua = ft0::data_transfer::digital_button::ua(data.digital_button) == 0; + + if (a) current_scene->a(); + if (b) current_scene->b(); + if (x) current_scene->x(); + if (y) current_scene->y(); + + if (ra) current_scene->ra(); + if (la) current_scene->la(); + if (da) current_scene->da(); + if (ua) current_scene->ua(); + last[port_ix].a = a; last[port_ix].b = b; last[port_ix].x = x; last[port_ix].y = y; - current_scene->analog(dx); + current_scene->analog(dl, dr, dx, dy); - view_trans = view_trans * rotate_y(dy);// * rotate_x(dx); + //view_trans = rotate_y(dy) * view_trans;// * rotate_x(dx); } } } diff --git a/src/platform/graphics_primitive.cpp b/src/platform/graphics_primitive.cpp index 9777da4..ed95d28 100644 --- a/src/platform/graphics_primitive.cpp +++ b/src/platform/graphics_primitive.cpp @@ -154,7 +154,7 @@ void draw_icosphere(ta_parameter_writer& writer, const vec3& ap = position_cache[tris[i].a]; const vec3& bp = position_cache[tris[i].b]; const vec3& cp = position_cache[tris[i].c]; - const float& intensity = _intensity(trans, normal[tris[i].n]); + const float intensity = _intensity(trans, normal[tris[i].n]); tri_type_2(writer, ap, @@ -261,3 +261,289 @@ void draw_halfspace(ta_parameter_writer& writer, dp, 1.0f); } + +void draw_textured_cube(ta_parameter_writer& writer, + const mat4x4& trans, + const vec3& scale, + const texture::cube_texture_offsets& offsets) +{ + static const vec3 position[] = { + {-0.5, -0.5, 0.5}, + {-0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5}, + {-0.5, 0.5, -0.5}, + { 0.5, -0.5, 0.5}, + { 0.5, 0.5, 0.5}, + { 0.5, -0.5, -0.5}, + { 0.5, 0.5, -0.5}, + }; + static const vec3 normal[] = { + {-1.0, -0.0, -0.0}, + {-0.0, -0.0, -1.0}, + { 1.0, -0.0, -0.0}, + {-0.0, -0.0, 1.0}, + {-0.0, -1.0, -0.0}, + {-0.0, 1.0, -0.0}, + }; + static const vec2 texture[] = { + {0.0, 0.0}, + {1.0, 0.0}, + {1.0, 1.0}, + {0.0, 1.0}, + }; + const int position_length = (sizeof (position)) / (sizeof (position[0])); + + struct quad { + int a, b, c, d; + }; + + static const quad quads[] = { + {0, 1, 3, 2}, // front (z, y) + {2, 3, 7, 6}, // left (x, y) + {6, 7, 5, 4}, // rear (z, y) + {4, 5, 1, 0}, // right (x, y) + {2, 6, 4, 0}, // bottom (x, z) + {7, 3, 1, 5} // top (x, z) + }; + + const vec2 uv_scale[] = { + {scale.z, scale.y}, + {scale.x, scale.y}, + {scale.z, scale.y}, + {scale.x, scale.y}, + {scale.z, scale.x}, + {scale.z, scale.x}, + }; + + const int quads_length = (sizeof (quads)) / (sizeof (quads[0])); + + vec3 position_cache[position_length]; + for (int i = 0; i < position_length; i++) { + position_cache[i] = trans * position[i]; + } + + int texture_uv_size + = tsp_instruction_word::texture_shading_instruction::decal + | tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::texture_u_size::from_int(32) + | tsp_instruction_word::texture_v_size::from_int(32); + + int pixel_format + = texture_control_word::pixel_format::_565; + + const vec4 color = {0, 0, 0, 0}; + + global_polygon_textured_intensity(writer, + color, + para_control::list_type::opaque, + offsets.side, + texture_uv_size, + pixel_format); + + for (int i = 0; i < quads_length; i++) { + if (i == 4) + global_polygon_textured_intensity(writer, + color, + para_control::list_type::opaque, + offsets.bottom, + texture_uv_size, + pixel_format); + if (i == 5) + global_polygon_textured_intensity(writer, + color, + para_control::list_type::opaque, + offsets.top, + texture_uv_size, + pixel_format); + + const vec3& ap = position_cache[quads[i].a]; + const vec3& bp = position_cache[quads[i].b]; + const vec3& cp = position_cache[quads[i].c]; + const vec3& dp = position_cache[quads[i].d]; + + const vec2& at = texture[3] * uv_scale[i]; + const vec2& bt = texture[0] * uv_scale[i]; + const vec2& ct = texture[1] * uv_scale[i]; + const vec2& dt = texture[2] * uv_scale[i]; + + const float base_intensity = _intensity(trans, normal[i]); + + quad_type_7_maybe_clip(writer, + ap, at, + bp, bt, + cp, ct, + dp, dt, + base_intensity); + } +} + +constexpr inline float pow(float x, int n) +{ + for (int i = 0; i < n; i++) + x *= x; + + return x; +} + +float alpha_mul = 0.9; + +void draw_textured_voxel(ta_parameter_writer& writer, + const mat4x4& trans, + int texture_offset) +{ + static const vec3 position[] = { + {-0.5, 0.5, 0.0}, + { 0.5, 0.5, 0.0}, + { 0.5, -0.5, 0.0}, + {-0.5, -0.5, 0.0}, + }; + static const vec2 texture[] = { + {0.0, 0.0}, + {1.0, 0.0}, + {1.0, 1.0}, + {0.0, 1.0}, + }; + const int position_length = (sizeof (position)) / (sizeof (position[0])); + + const vec3 pos_scale = {96 / 32, 1.0f, 1.0f}; + const vec2 uv_scale = {96.0f / 128.0f, 1.0}; + + vec3 position_cache[position_length]; + for (int i = 0; i < position_length; i++) { + position_cache[i] = trans * (position[i] * pos_scale); + } + + int texture_uv_size + = tsp_instruction_word::texture_shading_instruction::modulate_alpha + | tsp_instruction_word::src_alpha_instr::src_alpha + | tsp_instruction_word::dst_alpha_instr::inverse_src_alpha + | tsp_instruction_word::texture_u_size::from_int(128) + | tsp_instruction_word::texture_v_size::from_int(32) + | tsp_instruction_word::use_alpha; + + int pixel_format + = texture_control_word::pixel_format::_4444; + + const float table[] = { + 0.063, + 0.063, + 0.063, + 0.074, + 0.077, // after purple + 0.077, // after purple + 0.077, // after purple + 0.077, // after purple + 0.077, // after purple + 0.084, // purple + 0.084, // purple + 0.084, // purple + 0.084, // purple + 0.084, // purple + 0.090, + 0.090, + 0.090, + 0.100, + 0.100, + 0.100, + 0.111, + 0.111, + 0.111, + 0.129, + 0.129, + 0.129, + 0.148, + 0.148, + 0.148, + 0.180, + 0.180, + 0.180, + 0.440, // green + 0.440, // green + 0.440, // green + 0.881, // yellow + 1.0, + 1.0, + 1.0, + 0.881, // yellow + 0.440, // green + 0.440, // green + 0.440, // green + 0.180, + 0.180, + 0.180, + 0.148, + 0.148, + 0.148, + 0.129, + 0.129, + 0.129, + 0.111, + 0.111, + 0.111, + 0.100, + 0.100, + 0.100, + 0.090, + 0.090, + 0.090, + 0.084, // purple + 0.084, // purple + 0.084, // purple + 0.084, // purple + 0.084, // purple + 0.077, // after purple + 0.077, // after purple + 0.077, // after purple + 0.077, // after purple + 0.077, // after purple + 0.074, + 0.063, + 0.063, + 0.063, + }; + const int table_length = (sizeof (table)) / (sizeof (table[0])); + + constexpr int num_quads = table_length; + constexpr int half_quads = (num_quads - 1) / 2; + constexpr float inverse_half_quads = 1.0f / (float)half_quads; + + + for (int i = 0; i < num_quads; i++) { + float z = (float)(i - half_quads) * inverse_half_quads; + float s = sin(z * pi * 0.5f + pi * 0.5f); + //printf("%f\n", s); + //float a = pow(s, 5); + float a = table[i]; + //float a = alpha_mul; + vec4 color = {1, 1, 1, a}; + + global_polygon_textured_intensity(writer, + color, + para_control::list_type::punch_through, + texture_offset, + texture_uv_size, + pixel_format); + + vec3 z_trans = {0, 0, z * 0.35f}; + const vec3& ap = trans * (position[0] * pos_scale + z_trans); + const vec3& bp = trans * (position[1] * pos_scale + z_trans); + const vec3& cp = trans * (position[2] * pos_scale + z_trans); + const vec3& dp = trans * (position[3] * pos_scale + z_trans); + + const vec2& at = texture[0] * uv_scale; + const vec2& bt = texture[1] * uv_scale; + const vec2& ct = texture[2] * uv_scale; + const vec2& dt = texture[3] * uv_scale; + + //const float base_intensity = _intensity(trans, normal[i]); + const float base_intensity = 1.0f; + + quad_type_7_maybe_clip(writer, + ap, at, + bp, bt, + cp, ct, + dp, dt, + base_intensity); + } +} diff --git a/src/platform/graphics_primitive.hpp b/src/platform/graphics_primitive.hpp index 7946d35..c315080 100644 --- a/src/platform/graphics_primitive.hpp +++ b/src/platform/graphics_primitive.hpp @@ -1,10 +1,9 @@ #include "math/math.hpp" -#include "holly/framebuffer.hpp" #include "platform/ta_parameter_presets.hpp" +#include "platform/texture.hpp" #define _fsrra(n) (1.0f / (sqrt(n))) - static inline void draw_line(ta_parameter_writer& writer, const vec3& p1, const vec3& p2) @@ -28,17 +27,7 @@ static inline void draw_line(ta_parameter_writer& writer, dp, intensity); } - -static inline vec3 screen_transform(const vec3& v) -{ - float tx = framebuffer::framebuffer.px_width / 2.f; - float ty = framebuffer::framebuffer.px_height / 2.f; - float s = framebuffer::framebuffer.px_height / 2.f; - - float z = _fsrra(v.z); - float z2 = z * z; - return {(v.x) * s * z2 + tx , (v.y) * s * z2 + ty , z2}; -} +#undef _fsrra static inline void draw_grid(ta_parameter_writer& writer, const mat4x4& trans) @@ -91,6 +80,11 @@ void draw_cube(ta_parameter_writer& writer, const mat4x4& trans, const vec3& color); +void draw_textured_cube(ta_parameter_writer& writer, + const mat4x4& trans, + const vec3& scale, + const texture::cube_texture_offsets& offsets); + void draw_icosphere(ta_parameter_writer& writer, const mat4x4& trans, const vec3& color); @@ -106,3 +100,7 @@ void draw_halfspace(ta_parameter_writer& writer, const vec3& n, const mat4x4& trans, const vec3& color); + +void draw_textured_voxel(ta_parameter_writer& writer, + const mat4x4& trans, + int texture_offset); diff --git a/src/platform/ta_parameter_presets.hpp b/src/platform/ta_parameter_presets.hpp index 6ce92c4..d42d3d6 100644 --- a/src/platform/ta_parameter_presets.hpp +++ b/src/platform/ta_parameter_presets.hpp @@ -5,7 +5,9 @@ #include "holly/ta_global_parameter.hpp" #include "holly/isp_tsp.hpp" #include "holly/texture_memory_alloc9.hpp" +#include "holly/framebuffer.hpp" +#include "math/geometry.hpp" #include "math/float_types.hpp" static inline void global_polygon_intensity(ta_parameter_writer& writer, @@ -35,6 +37,38 @@ static inline void global_polygon_intensity(ta_parameter_writer& writer, 1.0f, color.x, color.y, color.z); } +static inline void global_polygon_textured_intensity(ta_parameter_writer& writer, + const vec4& color, + int list_type, + int texture_offset, + int texture_uv_size, + int pixel_format) +{ + const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume + | list_type + | obj_control::col_type::intensity_mode_1 + | obj_control::texture + ; + + const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater_or_equal + | isp_tsp_instruction_word::culling_mode::no_culling;//cull_if_positive; + + const uint32_t tsp_instruction_word = tsp_instruction_word::fog_control::no_fog + | texture_uv_size; + + const uint32_t texture_address = texture_memory_alloc.texture.start + texture_offset; + const uint32_t texture_control_word = pixel_format + | texture_control_word::scan_order::twiddled + | texture_control_word::texture_address(texture_address / 8); + + writer.append() = + ta_global_parameter::polygon_type_1(parameter_control_word, + isp_tsp_instruction_word, + tsp_instruction_word, + texture_control_word, + color.w, color.x, color.y, color.z); +} + static inline void global_polygon_textured(ta_parameter_writer& writer, uint32_t list_type, uint32_t texture_offset, @@ -151,3 +185,156 @@ static inline void quad_type_3(ta_parameter_writer& writer, ct.x, ct.y, base_color, 0); } + +static inline void quad_type_7(ta_parameter_writer& writer, + const vec3& ap, const vec2& at, + const vec3& bp, const vec2& bt, + const vec3& cp, const vec2& ct, + const vec3& dp, const vec2& dt, + float base_intensity) +{ + writer.append() = + ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false), + ap.x, ap.y, ap.z, + at.x, at.y, + base_intensity, 0); + + writer.append() = + ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false), + bp.x, bp.y, bp.z, + bt.x, bt.y, + base_intensity, 0); + + writer.append() = + ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false), + dp.x, dp.y, dp.z, + dt.x, dt.y, + base_intensity, 0); + + writer.append() = + ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(true), + cp.x, cp.y, cp.z, + ct.x, ct.y, + base_intensity, 0); +} + +static inline void tri_type_7(ta_parameter_writer& writer, + const vec3& ap, const vec2& at, + const vec3& bp, const vec2& bt, + const vec3& cp, const vec2& ct, + float base_intensity) +{ + writer.append() = + ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false), + ap.x, ap.y, ap.z, + at.x, at.y, + base_intensity, 0); + + writer.append() = + ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false), + bp.x, bp.y, bp.z, + bt.x, bt.y, + base_intensity, 0); + + writer.append() = + ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(true), + cp.x, cp.y, cp.z, + ct.x, ct.y, + base_intensity, 0); +} + +#define _fsrra(n) (1.0f / (sqrt(n))) +static inline vec3 screen_transform(const vec3& v) +{ + float tx = framebuffer::framebuffer.px_width / 2.f; + float ty = framebuffer::framebuffer.px_height / 2.f; + float s = framebuffer::framebuffer.px_height / 2.f; + + float z = _fsrra(v.z); + float z2 = z * z; + return {(-v.x) * s * z2 + tx , (-v.y) * s * z2 + ty , z2}; +} +#undef _fsrra + +static inline void tri_type_7_clip(ta_parameter_writer& writer, + const vec3& ap, const vec2& at, + const vec3& bp, const vec2& bt, + const vec3& cp, const vec2& ct, + float base_intensity) +{ + const vec3 plane_point = {0.f, 0.f, 0.5f}; + const vec3 plane_normal = {0.f, 0.f, 1.f}; + + vec3 preclip_position[] = {ap, bp, cp}; + vec2 preclip_texture[] = {at, bt, ct}; + + vec3 clip_position[4]; + vec2 clip_texture[4]; + + int output_length = geometry::clip_polygon_2<3>(clip_position, + clip_texture , + plane_point, + plane_normal, + preclip_position, + preclip_texture); + + { + vec3 ap = screen_transform(clip_position[0]); + vec3 bp = screen_transform(clip_position[1]); + vec3 cp = screen_transform(clip_position[2]); + + const vec2& at = clip_texture[0]; + const vec2& bt = clip_texture[1]; + const vec2& ct = clip_texture[2]; + + if (output_length >= 4) { + vec3 dp = screen_transform(clip_position[3]); + const vec2& dt = clip_texture[3]; + quad_type_7(writer, + ap, at, + bp, bt, + cp, ct, + dp, dt, + base_intensity); + } else { + tri_type_7(writer, + ap, at, + bp, bt, + cp, ct, + base_intensity); + } + } +} + +static inline void quad_type_7_maybe_clip(ta_parameter_writer& writer, + const vec3& ap, const vec2& at, + const vec3& bp, const vec2& bt, + const vec3& cp, const vec2& ct, + const vec3& dp, const vec2& dt, + float base_intensity) +{ + if (ap.z < 0 && bp.z < 0 && cp.z < 0 && dp.z < 0) { + return; + } + + if (ap.z < 0 || bp.z < 0 || cp.z < 0 || dp.z < 0) { + tri_type_7_clip(writer, + ap, at, + bp, bt, + cp, ct, + base_intensity); + + tri_type_7_clip(writer, + ap, at, + cp, ct, + dp, dt, + base_intensity); + } else { + quad_type_7(writer, + screen_transform(ap), at, + screen_transform(bp), bt, + screen_transform(cp), ct, + screen_transform(dp), dt, + base_intensity); + } +} diff --git a/src/platform/texture.cpp b/src/platform/texture.cpp index 200f7af..0dd91d8 100644 --- a/src/platform/texture.cpp +++ b/src/platform/texture.cpp @@ -8,6 +8,16 @@ #include "holly/ta_fifo_texture_memory_transfer.hpp" #include "font/ter_u12n.data.h" +#include "texture/igh25_box_top_32.data.h" +#include "texture/igh25_box_bottom_32.data.h" +#include "texture/igh25_box_side_32.data.h" +#include "texture/walking/frame0000_128.data.h" +#include "texture/walking/frame0001_128.data.h" +#include "texture/walking/frame0002_128.data.h" +#include "texture/walking/frame0003_128.data.h" +#include "texture/walking/frame0004_128.data.h" +#include "texture/walking/frame0005_128.data.h" +#include "texture/walking/frame0006_128.data.h" namespace texture { struct entry { @@ -22,6 +32,56 @@ namespace texture { .size = reinterpret_cast(&_binary_font_ter_u12n_data_size), .offset = offset::ter_u12n, }, + { + .start = reinterpret_cast(&_binary_texture_igh25_box_top_32_data_start), + .size = reinterpret_cast(&_binary_texture_igh25_box_top_32_data_size), + .offset = offset::igh25_box_top_32, + }, + { + .start = reinterpret_cast(&_binary_texture_igh25_box_bottom_32_data_start), + .size = reinterpret_cast(&_binary_texture_igh25_box_bottom_32_data_size), + .offset = offset::igh25_box_bottom_32, + }, + { + .start = reinterpret_cast(&_binary_texture_igh25_box_side_32_data_start), + .size = reinterpret_cast(&_binary_texture_igh25_box_side_32_data_size), + .offset = offset::igh25_box_side_32, + }, + { + .start = reinterpret_cast(&_binary_texture_walking_frame0000_128_data_start), + .size = reinterpret_cast(&_binary_texture_walking_frame0000_128_data_size), + .offset = offset::walking_frame0000, + }, + { + .start = reinterpret_cast(&_binary_texture_walking_frame0001_128_data_start), + .size = reinterpret_cast(&_binary_texture_walking_frame0001_128_data_size), + .offset = offset::walking_frame0001, + }, + { + .start = reinterpret_cast(&_binary_texture_walking_frame0002_128_data_start), + .size = reinterpret_cast(&_binary_texture_walking_frame0002_128_data_size), + .offset = offset::walking_frame0002, + }, + { + .start = reinterpret_cast(&_binary_texture_walking_frame0003_128_data_start), + .size = reinterpret_cast(&_binary_texture_walking_frame0003_128_data_size), + .offset = offset::walking_frame0003, + }, + { + .start = reinterpret_cast(&_binary_texture_walking_frame0004_128_data_start), + .size = reinterpret_cast(&_binary_texture_walking_frame0004_128_data_size), + .offset = offset::walking_frame0004, + }, + { + .start = reinterpret_cast(&_binary_texture_walking_frame0005_128_data_start), + .size = reinterpret_cast(&_binary_texture_walking_frame0005_128_data_size), + .offset = offset::walking_frame0005, + }, + { + .start = reinterpret_cast(&_binary_texture_walking_frame0006_128_data_start), + .size = reinterpret_cast(&_binary_texture_walking_frame0006_128_data_size), + .offset = offset::walking_frame0006, + }, }; const int textures_length = (sizeof (textures)) / (sizeof (textures[0])); diff --git a/src/platform/texture.hpp b/src/platform/texture.hpp index b250367..c6576c5 100644 --- a/src/platform/texture.hpp +++ b/src/platform/texture.hpp @@ -1,7 +1,31 @@ +#pragma once + namespace texture { namespace offset { constexpr int ter_u12n = 0; + constexpr int igh25_box_top_32 = ter_u12n + 4096; + constexpr int igh25_box_bottom_32 = igh25_box_top_32 + 2048; + constexpr int igh25_box_side_32 = igh25_box_bottom_32 + 2048; + constexpr int walking_frame0000 = igh25_box_side_32 + 2048; + constexpr int walking_frame0001 = walking_frame0000 + 8192; + constexpr int walking_frame0002 = walking_frame0001 + 8192; + constexpr int walking_frame0003 = walking_frame0002 + 8192; + constexpr int walking_frame0004 = walking_frame0003 + 8192; + constexpr int walking_frame0005 = walking_frame0004 + 8192; + constexpr int walking_frame0006 = walking_frame0005 + 8192; } + struct cube_texture_offsets { + const int top; + const int bottom; + const int side; + }; + + constexpr cube_texture_offsets cube_type_1 = { + offset::igh25_box_top_32, + offset::igh25_box_bottom_32, + offset::igh25_box_side_32, + }; + void init(); } diff --git a/texture/igh25_box_bottom_32.data.h b/texture/igh25_box_bottom_32.data.h new file mode 100644 index 0000000..929d6af --- /dev/null +++ b/texture/igh25_box_bottom_32.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_igh25_box_bottom_32_data_start __asm("_binary_texture_igh25_box_bottom_32_data_start"); +extern uint32_t _binary_texture_igh25_box_bottom_32_data_end __asm("_binary_texture_igh25_box_bottom_32_data_end"); +extern uint32_t _binary_texture_igh25_box_bottom_32_data_size __asm("_binary_texture_igh25_box_bottom_32_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/igh25_box_bottom_32.png b/texture/igh25_box_bottom_32.png new file mode 100644 index 0000000..65739fc Binary files /dev/null and b/texture/igh25_box_bottom_32.png differ diff --git a/texture/igh25_box_side_32.data.h b/texture/igh25_box_side_32.data.h new file mode 100644 index 0000000..7271191 --- /dev/null +++ b/texture/igh25_box_side_32.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_igh25_box_side_32_data_start __asm("_binary_texture_igh25_box_side_32_data_start"); +extern uint32_t _binary_texture_igh25_box_side_32_data_end __asm("_binary_texture_igh25_box_side_32_data_end"); +extern uint32_t _binary_texture_igh25_box_side_32_data_size __asm("_binary_texture_igh25_box_side_32_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/igh25_box_side_32.png b/texture/igh25_box_side_32.png new file mode 100644 index 0000000..25ac194 Binary files /dev/null and b/texture/igh25_box_side_32.png differ diff --git a/texture/igh25_box_top_32.data.h b/texture/igh25_box_top_32.data.h new file mode 100644 index 0000000..3445e26 --- /dev/null +++ b/texture/igh25_box_top_32.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_igh25_box_top_32_data_start __asm("_binary_texture_igh25_box_top_32_data_start"); +extern uint32_t _binary_texture_igh25_box_top_32_data_end __asm("_binary_texture_igh25_box_top_32_data_end"); +extern uint32_t _binary_texture_igh25_box_top_32_data_size __asm("_binary_texture_igh25_box_top_32_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/igh25_box_top_32.png b/texture/igh25_box_top_32.png new file mode 100644 index 0000000..d4767fb Binary files /dev/null and b/texture/igh25_box_top_32.png differ diff --git a/texture/walking/frame0000.png b/texture/walking/frame0000.png new file mode 100755 index 0000000..906109d Binary files /dev/null and b/texture/walking/frame0000.png differ diff --git a/texture/walking/frame0000_128.data.h b/texture/walking/frame0000_128.data.h new file mode 100644 index 0000000..4616d78 --- /dev/null +++ b/texture/walking/frame0000_128.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_walking_frame0000_128_data_start __asm("_binary_texture_walking_frame0000_128_data_start"); +extern uint32_t _binary_texture_walking_frame0000_128_data_end __asm("_binary_texture_walking_frame0000_128_data_end"); +extern uint32_t _binary_texture_walking_frame0000_128_data_size __asm("_binary_texture_walking_frame0000_128_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/walking/frame0001.png b/texture/walking/frame0001.png new file mode 100755 index 0000000..9120587 Binary files /dev/null and b/texture/walking/frame0001.png differ diff --git a/texture/walking/frame0001_128.data.h b/texture/walking/frame0001_128.data.h new file mode 100644 index 0000000..40cc7e5 --- /dev/null +++ b/texture/walking/frame0001_128.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_walking_frame0001_128_data_start __asm("_binary_texture_walking_frame0001_128_data_start"); +extern uint32_t _binary_texture_walking_frame0001_128_data_end __asm("_binary_texture_walking_frame0001_128_data_end"); +extern uint32_t _binary_texture_walking_frame0001_128_data_size __asm("_binary_texture_walking_frame0001_128_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/walking/frame0002.png b/texture/walking/frame0002.png new file mode 100755 index 0000000..55e7891 Binary files /dev/null and b/texture/walking/frame0002.png differ diff --git a/texture/walking/frame0002_128.data.h b/texture/walking/frame0002_128.data.h new file mode 100644 index 0000000..d05e4c6 --- /dev/null +++ b/texture/walking/frame0002_128.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_walking_frame0002_128_data_start __asm("_binary_texture_walking_frame0002_128_data_start"); +extern uint32_t _binary_texture_walking_frame0002_128_data_end __asm("_binary_texture_walking_frame0002_128_data_end"); +extern uint32_t _binary_texture_walking_frame0002_128_data_size __asm("_binary_texture_walking_frame0002_128_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/walking/frame0003.png b/texture/walking/frame0003.png new file mode 100755 index 0000000..521b0c0 Binary files /dev/null and b/texture/walking/frame0003.png differ diff --git a/texture/walking/frame0003_128.data.h b/texture/walking/frame0003_128.data.h new file mode 100644 index 0000000..b293fc0 --- /dev/null +++ b/texture/walking/frame0003_128.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_walking_frame0003_128_data_start __asm("_binary_texture_walking_frame0003_128_data_start"); +extern uint32_t _binary_texture_walking_frame0003_128_data_end __asm("_binary_texture_walking_frame0003_128_data_end"); +extern uint32_t _binary_texture_walking_frame0003_128_data_size __asm("_binary_texture_walking_frame0003_128_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/walking/frame0004.png b/texture/walking/frame0004.png new file mode 100755 index 0000000..ffe405a Binary files /dev/null and b/texture/walking/frame0004.png differ diff --git a/texture/walking/frame0004_128.data.h b/texture/walking/frame0004_128.data.h new file mode 100644 index 0000000..dc6e3b3 --- /dev/null +++ b/texture/walking/frame0004_128.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_walking_frame0004_128_data_start __asm("_binary_texture_walking_frame0004_128_data_start"); +extern uint32_t _binary_texture_walking_frame0004_128_data_end __asm("_binary_texture_walking_frame0004_128_data_end"); +extern uint32_t _binary_texture_walking_frame0004_128_data_size __asm("_binary_texture_walking_frame0004_128_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/walking/frame0005.png b/texture/walking/frame0005.png new file mode 100755 index 0000000..c00b67f Binary files /dev/null and b/texture/walking/frame0005.png differ diff --git a/texture/walking/frame0005_128.data.h b/texture/walking/frame0005_128.data.h new file mode 100644 index 0000000..a7fa81b --- /dev/null +++ b/texture/walking/frame0005_128.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_walking_frame0005_128_data_start __asm("_binary_texture_walking_frame0005_128_data_start"); +extern uint32_t _binary_texture_walking_frame0005_128_data_end __asm("_binary_texture_walking_frame0005_128_data_end"); +extern uint32_t _binary_texture_walking_frame0005_128_data_size __asm("_binary_texture_walking_frame0005_128_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/texture/walking/frame0006.png b/texture/walking/frame0006.png new file mode 100755 index 0000000..ff79111 Binary files /dev/null and b/texture/walking/frame0006.png differ diff --git a/texture/walking/frame0006_128.data.h b/texture/walking/frame0006_128.data.h new file mode 100644 index 0000000..7e0a819 --- /dev/null +++ b/texture/walking/frame0006_128.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_texture_walking_frame0006_128_data_start __asm("_binary_texture_walking_frame0006_128_data_start"); +extern uint32_t _binary_texture_walking_frame0006_128_data_end __asm("_binary_texture_walking_frame0006_128_data_end"); +extern uint32_t _binary_texture_walking_frame0006_128_data_size __asm("_binary_texture_walking_frame0006_128_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/tools/canvas_size.py b/tools/canvas_size.py new file mode 100644 index 0000000..08cce9a --- /dev/null +++ b/tools/canvas_size.py @@ -0,0 +1,17 @@ +from PIL import Image +import sys + +def main(): + in_file = sys.argv[1] + new_width = int(sys.argv[2]) + new_height = int(sys.argv[3]) + dst_file = sys.argv[4] + with Image.open(in_file) as im: + dst = Image.new(im.mode, (new_width, new_height)) + for y in range(im.height): + for x in range(im.width): + dst.putpixel((x, y), im.getpixel((x, y))) + dst.save(dst_file) + +if __name__ == "__main__": + main() diff --git a/tools/generate.py b/tools/generate.py new file mode 100644 index 0000000..d5805e9 --- /dev/null +++ b/tools/generate.py @@ -0,0 +1,42 @@ +import io + +def should_autonewline(line): + return ( + "static_assert" not in line + and "extern" not in line + and (len(line.split()) < 2 or line.split()[1] != '=') # hacky; meh + ) + +def _render(out, lines): + indent = " " + level = 0 + namespace = 0 + for l in lines: + if l and (l[0] == "}" or l[0] == ")"): + level -= 2 + if level < 0: + assert namespace >= 0 + namespace -= 1 + level = 0 + + if len(l) == 0: + out.write("\n") + else: + out.write(indent * level + l + "\n") + + if l and (l[-1] == "{" or l[-1] == "("): + #if l.startswith("namespace"): + # namespace += 1 + #else: + level += 2 + + if level == 0 and l and l[-1] == ";": + if should_autonewline(l): + out.write("\n") + return out + +def renderer(): + out = io.StringIO() + def render(lines): + return _render(out, lines) + return render, out diff --git a/tools/parse_map.py b/tools/parse_map.py new file mode 100644 index 0000000..02d1f01 --- /dev/null +++ b/tools/parse_map.py @@ -0,0 +1,151 @@ +from PIL import Image +import sys +from dataclasses import dataclass +from generate import renderer +from os import path + +visited = set() + +@dataclass +class vec3: + x: float + y: float + z: float + +@dataclass +class Platform: + scale: vec3 + position: vec3 + +def parse_width(x, y, get_pixel): + width = 0 + while True: + px = get_pixel(x, y) + if px[0] != 0: + width += 1 + x += 1 + else: + break + return width + +def parse_height(x, y, get_pixel): + height = 0 + while True: + px = get_pixel(x, y) + if px[0] != 0: + height += 1 + y += 1 + else: + break + return height + +def round_to_one(n): + if n == 0: + return 1 + else: + return n + +def visit_pixels(x, y, width, height): + for yi in range(round_to_one(height)): + for xi in range(round_to_one(width)): + xx = x + xi + yy = y + yi + location = (xx, yy) + assert location not in visited + visited.add(location) + +def parse_platform(x, y, get_pixel): + width = parse_width(x, y, get_pixel) + height = parse_height(x, y, get_pixel) + + visit_pixels(x, y, width, height) + + if width != 0 and height != 0: + px = get_pixel(x, y) + position = vec3( + x + (width / 2), + (px[0] - 128), + y + (height / 2), + ) + scale = vec3( + width, + 1, + height, + ) + + return Platform( + position=position, + scale=scale, + ) + else: + return None + +def find_platforms(im): + width, height = im.size + pixels = im.convert("RGB").getdata() + + def get_pixel(x, y): + return pixels[y * width + x] + + platforms = [] + + for y in range(height): + for x in range(width): + if (x, y) not in visited: + platform = parse_platform(x, y, get_pixel) + if platform is not None: + platforms.append(platform) + + return platforms + +def format_vec3(v): + return ", ".join(( + f"{n: 8.03f}" + for n in [v.x, v.y, v.z] + )) + +def generate_platform(platform): + yield "{" + yield f".position = vec3({format_vec3(platform.position)})," + yield f".scale = vec3({format_vec3(platform.scale)})," + yield "}," + +def generate_level(name, platforms): + yield f"world::platform {name}_platforms[] = {{" + for platform in platforms: + yield from generate_platform(platform) + yield "};" + + yield f"world::level {name}_level = {{" + yield f".platforms = {name}_platforms," + yield f".platforms_length = (sizeof ({name}_platforms)) / (sizeof (world::platform))," + yield "};" + +def generate_file(name_platforms_list): + yield '#include "demo/platform/world.hpp"' + yield "" + yield f"namespace demo::map {{" + yield "" + for name, platforms in name_platforms_list: + yield from generate_level(name, platforms) + + yield "" + yield '}' + +def level_name(p): + _, fn = path.split(p) + name, _ = path.splitext(fn) + return name + +def find_all_platforms(maps): + for filename in maps: + with Image.open(filename) as im: + name = level_name(filename) + platforms = find_platforms(im) + yield (name, platforms) + +maps = sys.argv[1:] + +render, out = renderer() +render(generate_file(find_all_platforms(maps))) +sys.stdout.write(out.getvalue())