Compare commits
12 Commits
25f4cc50f7
...
4d51b47046
Author | SHA1 | Date | |
---|---|---|---|
4d51b47046 | |||
55c38ebf5f | |||
4503b3542e | |||
6e28a7d147 | |||
9f758e75f0 | |||
e9ef21865c | |||
4301bbd4b7 | |||
447602ef41 | |||
b994669ad9 | |||
35effc6f86 | |||
3c9abcc88c | |||
1cce7752c0 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -11,9 +11,12 @@
|
|||||||
*.pcm
|
*.pcm
|
||||||
*.su
|
*.su
|
||||||
*.ss
|
*.ss
|
||||||
|
*.dsp
|
||||||
|
*.exe
|
||||||
res/mai.data
|
res/mai.data
|
||||||
tools/ttf-convert
|
tools/ttf-convert
|
||||||
tools/ttf-bitmap
|
tools/ttf-bitmap
|
||||||
|
tools/ttf_bitmap2
|
||||||
common/keyboard.cpp
|
common/keyboard.cpp
|
||||||
common/keyboard.hpp
|
common/keyboard.hpp
|
||||||
wordle/word_list.hpp
|
wordle/word_list.hpp
|
33
Makefile
33
Makefile
@ -1,5 +1,5 @@
|
|||||||
CFLAGS = -Isaturn
|
CFLAGS = -Isaturn -I. -D__saturn__
|
||||||
OPT ?= -Og
|
OPT ?= -O2
|
||||||
LIB = ./saturn
|
LIB = ./saturn
|
||||||
|
|
||||||
ALL =
|
ALL =
|
||||||
@ -28,6 +28,9 @@ include $(LIB)/common.mk
|
|||||||
%.data.o: %.data
|
%.data.o: %.data
|
||||||
$(BUILD_BINARY_O)
|
$(BUILD_BINARY_O)
|
||||||
|
|
||||||
|
%.data.h: %.data
|
||||||
|
$(BUILD_BINARY_H)
|
||||||
|
|
||||||
%.pattern.o: %.pattern
|
%.pattern.o: %.pattern
|
||||||
$(BUILD_BINARY_O)
|
$(BUILD_BINARY_O)
|
||||||
|
|
||||||
@ -37,6 +40,15 @@ include $(LIB)/common.mk
|
|||||||
%.bin.o: %.bin
|
%.bin.o: %.bin
|
||||||
$(BUILD_BINARY_O)
|
$(BUILD_BINARY_O)
|
||||||
|
|
||||||
|
%.bin.h: %.bin
|
||||||
|
$(BUILD_BINARY_H)
|
||||||
|
|
||||||
|
%.dsp.o: %.dsp
|
||||||
|
$(BUILD_BINARY_O)
|
||||||
|
|
||||||
|
%.dsp.h: %.dsp
|
||||||
|
$(BUILD_BINARY_H)
|
||||||
|
|
||||||
%.pcm.o: %.pcm
|
%.pcm.o: %.pcm
|
||||||
$(BUILD_BINARY_O)
|
$(BUILD_BINARY_O)
|
||||||
|
|
||||||
@ -52,11 +64,19 @@ vdp2/nbg0.elf: vdp2/nbg0.o res/butterfly.data.o res/butterfly.data.pal.o
|
|||||||
|
|
||||||
vdp2/nbg0_16color.elf: vdp2/nbg0_16color.o res/kirby.data.o res/kirby.data.pal.o
|
vdp2/nbg0_16color.elf: vdp2/nbg0_16color.o res/kirby.data.o res/kirby.data.pal.o
|
||||||
|
|
||||||
|
vdp2/nbg0_font.elf: vdp2/nbg0_font.o saturn/start.o font/hp_100lx_4bit.data.o
|
||||||
|
|
||||||
|
vdp2/rbg0_font.elf: vdp2/rbg0_font.o saturn/start.o font/hp_100lx_4bit.data.o
|
||||||
|
|
||||||
vdp2/color_calculation_ratio.elf: vdp2/color_calculation_ratio.o res/mai00.data.o res/mai.data.pal.o res/haohmaru.data.o res/haohmaru.data.pal.o res/forest.data.pal.o res/forest.pattern.o res/forest.tile.o
|
vdp2/color_calculation_ratio.elf: vdp2/color_calculation_ratio.o res/mai00.data.o res/mai.data.pal.o res/haohmaru.data.o res/haohmaru.data.pal.o res/forest.data.pal.o res/forest.pattern.o res/forest.tile.o
|
||||||
|
|
||||||
|
vdp2/line_color_screen.elf: vdp2/line_color_screen.o $(LIBGCC)
|
||||||
|
|
||||||
vdp1/polygon.elf: vdp1/polygon.o
|
vdp1/polygon.elf: vdp1/polygon.o
|
||||||
vdp1/cube.elf: vdp1/cube.o $(LIBGCC)
|
vdp1/cube.elf: vdp1/cube.o $(LIBGCC)
|
||||||
vdp1/cube2.elf: vdp1/cube2.o
|
vdp1/cube2.elf: vdp1/cube2.o
|
||||||
|
vdp1/bear.elf: CFLAGS += -DUSE_SH2_DVSR
|
||||||
|
vdp1/bear.elf: vdp1/bear.o $(LIBGCC)
|
||||||
vdp1/normal_sprite.elf: vdp1/normal_sprite.o res/mai00.data.o res/mai.data.pal.o
|
vdp1/normal_sprite.elf: vdp1/normal_sprite.o res/mai00.data.o res/mai.data.pal.o
|
||||||
|
|
||||||
vdp1/normal_sprite_color_bank.elf: vdp1/normal_sprite_color_bank.o res/mai00.data.o res/mai.data.pal.o
|
vdp1/normal_sprite_color_bank.elf: vdp1/normal_sprite_color_bank.o res/mai00.data.o res/mai.data.pal.o
|
||||||
@ -153,6 +173,15 @@ editor/main_saturn.elf: editor/main_saturn.o res/nec.bitmap.bin.o res/nec_bold.b
|
|||||||
|
|
||||||
cdc/cdc.elf: cdc/cdc.o saturn/start.o memcpy.o cdc/serial.o
|
cdc/cdc.elf: cdc/cdc.o saturn/start.o memcpy.o cdc/serial.o
|
||||||
|
|
||||||
|
scu-dsp/add.elf: scu-dsp/add.o saturn/start.o cdc/serial.o scu-dsp/input.bin.o
|
||||||
|
|
||||||
|
scu-dsp/div10.elf: scu-dsp/div10.o saturn/start.o cdc/serial.o scu-dsp/div10.dsp.o
|
||||||
|
|
||||||
|
scu-dsp/div10_vdp2.elf: scu-dsp/div10_vdp2.o saturn/start.o cdc/serial.o scu-dsp/div10_vdp2.dsp.o font/hp_100lx_4bit_flip.data.o
|
||||||
|
|
||||||
|
%.dsp: %.asm
|
||||||
|
~/scu-dsp-asm/scu-dsp-asm $< $@
|
||||||
|
|
||||||
# clean
|
# clean
|
||||||
clean: clean-sh
|
clean: clean-sh
|
||||||
clean-sh:
|
clean-sh:
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
void serial_char(const char c)
|
void serial_char(const char c)
|
||||||
{
|
{
|
||||||
while ((sh2.reg.SSR & SSR__TDRE) == 0); // wait for transmit data empty
|
//while ((sh2.reg.SSR & SSR__TDRE) == 0); // wait for transmit data empty
|
||||||
sh2.reg.TDR = c;
|
sh2.reg.TDR = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_string(const char * s)
|
void serial_string(const char * s)
|
||||||
{
|
{
|
||||||
while (*s) {
|
while (*s) {
|
||||||
while ((sh2.reg.SSR & SSR__TDRE) == 0); // wait for transmit data empty
|
//while ((sh2.reg.SSR & SSR__TDRE) == 0); // wait for transmit data empty
|
||||||
sh2.reg.TDR = *s++;
|
sh2.reg.TDR = *s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ void serial_string(const char * s)
|
|||||||
void serial_bytes(const char * s, uint32_t length)
|
void serial_bytes(const char * s, uint32_t length)
|
||||||
{
|
{
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
while ((sh2.reg.SSR & SSR__TDRE) == 0); // wait for transmit data empty
|
//while ((sh2.reg.SSR & SSR__TDRE) == 0); // wait for transmit data empty
|
||||||
sh2.reg.TDR = *s++;
|
sh2.reg.TDR = *s++;
|
||||||
length -= 1;
|
length -= 1;
|
||||||
}
|
}
|
||||||
|
BIN
font/Bm437_HP_100LX_8x8.otb
Normal file
BIN
font/Bm437_HP_100LX_8x8.otb
Normal file
Binary file not shown.
BIN
font/hp_100lx_4bit.data
Normal file
BIN
font/hp_100lx_4bit.data
Normal file
Binary file not shown.
5
font/hp_100lx_4bit.data.h
Normal file
5
font/hp_100lx_4bit.data.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
extern uint32_t _binary_font_hp_100lx_4bit_data_start __asm("_binary_font_hp_100lx_4bit_data_start");
|
||||||
|
extern uint32_t _binary_font_hp_100lx_4bit_data_end __asm("_binary_font_hp_100lx_4bit_data_end");
|
||||||
|
extern uint32_t _binary_font_hp_100lx_4bit_data_size __asm("_binary_font_hp_100lx_4bit_data_size");
|
BIN
font/hp_100lx_4bit_flip.data
Normal file
BIN
font/hp_100lx_4bit_flip.data
Normal file
Binary file not shown.
5
font/hp_100lx_4bit_flip.data.h
Normal file
5
font/hp_100lx_4bit_flip.data.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
extern uint32_t _binary_font_hp_100lx_4bit_flip_data_start __asm("_binary_font_hp_100lx_4bit_flip_data_start");
|
||||||
|
extern uint32_t _binary_font_hp_100lx_4bit_flip_data_end __asm("_binary_font_hp_100lx_4bit_flip_data_end");
|
||||||
|
extern uint32_t _binary_font_hp_100lx_4bit_flip_data_size __asm("_binary_font_hp_100lx_4bit_flip_data_size");
|
105
math/mat2x2.hpp
Normal file
105
math/mat2x2.hpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include "vec2.hpp"
|
||||||
|
|
||||||
|
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]
|
||||||
|
);
|
||||||
|
}
|
@ -74,6 +74,17 @@ mat<3, 3, T>::operator[](int i) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr mat<3, 3, T> operator+(mat<3, 3, T> const& m1, mat<3, 3, T> const& m2)
|
||||||
|
{
|
||||||
|
#define c(i, j) ( m1[i][j] + m2[i][j] )
|
||||||
|
|
||||||
|
return mat<3, 3, T>(c(0,0), c(0,1), c(0,2),
|
||||||
|
c(1,0), c(1,1), c(1,2),
|
||||||
|
c(2,0), c(2,1), c(2,2));
|
||||||
|
#undef c
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr mat<3, 3, T> operator*(mat<3, 3, T> const& m1, mat<3, 3, T> const& m2)
|
inline constexpr mat<3, 3, T> operator*(mat<3, 3, T> const& m1, mat<3, 3, T> const& m2)
|
||||||
{
|
{
|
||||||
@ -88,6 +99,17 @@ inline constexpr mat<3, 3, T> operator*(mat<3, 3, T> const& m1, mat<3, 3, T> con
|
|||||||
#undef c
|
#undef c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr mat<3, 3, T> operator*(mat<3, 3, T> const& m1, float s)
|
||||||
|
{
|
||||||
|
#define c(i, j) ( m1[i][j] * s )
|
||||||
|
|
||||||
|
return mat<3, 3, T>(c(0,0), c(0,1), c(0,2),
|
||||||
|
c(1,0), c(1,1), c(1,2),
|
||||||
|
c(2,0), c(2,1), c(2,2));
|
||||||
|
#undef c
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr typename mat<3, 3, T>::row_type operator*
|
inline constexpr typename mat<3, 3, T>::row_type operator*
|
||||||
(
|
(
|
||||||
|
@ -35,7 +35,7 @@ public:
|
|||||||
inline constexpr typename mat<4, 4, T>::row_type const &
|
inline constexpr typename mat<4, 4, T>::row_type const &
|
||||||
operator[](int i) const;
|
operator[](int i) const;
|
||||||
|
|
||||||
void operator=(const mat<4, 4, T>&) = delete;
|
//void operator=(const mat<4, 4, T>&) = delete;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,6 +80,18 @@ mat<4, 4, T>::operator[](int i) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr mat<4, 4, T> operator+(mat<4, 4, T> const& m1, mat<4, 4, T> const& m2)
|
||||||
|
{
|
||||||
|
#define c(i, j) ( m1[i][j] + m2[i][j] )
|
||||||
|
|
||||||
|
return mat<4, 4, T>(c(0,0), c(0,1), c(0,2), c(0,3),
|
||||||
|
c(1,0), c(1,1), c(1,2), c(1,3),
|
||||||
|
c(2,0), c(2,1), c(2,2), c(2,3),
|
||||||
|
c(3,0), c(3,1), c(3,2), c(3,3));
|
||||||
|
#undef c
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, mat<4, 4, T> const& m2)
|
inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, mat<4, 4, T> const& m2)
|
||||||
{
|
{
|
||||||
@ -96,6 +108,18 @@ inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, mat<4, 4, T> con
|
|||||||
#undef c
|
#undef c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, float s)
|
||||||
|
{
|
||||||
|
#define c(i, j) ( m1[i][j] * s )
|
||||||
|
|
||||||
|
return mat<4, 4, T>(c(0,0), c(0,1), c(0,2), c(0,3),
|
||||||
|
c(1,0), c(1,1), c(1,2), c(1,3),
|
||||||
|
c(2,0), c(2,1), c(2,2), c(2,3),
|
||||||
|
c(3,0), c(3,1), c(3,2), c(3,3));
|
||||||
|
#undef c
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr typename mat<4, 4, T>::row_type operator*
|
inline constexpr typename mat<4, 4, T>::row_type operator*
|
||||||
(
|
(
|
||||||
@ -113,6 +137,23 @@ inline constexpr typename mat<4, 4, T>::row_type operator*
|
|||||||
#undef c
|
#undef c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr vec<3, T> operator*
|
||||||
|
(
|
||||||
|
mat<4, 4, T> const& m,
|
||||||
|
vec<3, T> const& v
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#define c(i) ( \
|
||||||
|
m[i][0] * v[0] \
|
||||||
|
+ m[i][1] * v[1] \
|
||||||
|
+ m[i][2] * v[2] \
|
||||||
|
+ m[i][3] )
|
||||||
|
|
||||||
|
return vec<3, T>(c(0), c(1), c(2));
|
||||||
|
#undef c
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr mat<4, 4, T> transpose(mat<4, 4, T> const& m)
|
inline constexpr mat<4, 4, T> transpose(mat<4, 4, T> const& m)
|
||||||
{
|
{
|
||||||
|
158
math/vec2.hpp
Normal file
158
math/vec2.hpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "math.hpp"
|
||||||
|
#include "vec.hpp"
|
||||||
|
|
||||||
|
//
|
||||||
|
// vec3
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct vec<2, T>
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct { T x, y; };
|
||||||
|
struct { T u, v; };
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr vec();
|
||||||
|
inline constexpr vec(T scalar);
|
||||||
|
inline constexpr vec(T _x, T _y);
|
||||||
|
|
||||||
|
constexpr inline vec<2, T> operator-() const;
|
||||||
|
inline constexpr T const& operator[](int i) const;
|
||||||
|
inline constexpr vec<2, T>& operator=(vec<2, T> const& v);
|
||||||
|
inline constexpr vec<2, T>& operator+=(vec<2, T> const& v);
|
||||||
|
inline constexpr vec<2, T>& operator-=(vec<2, T> const& v);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T>::vec()
|
||||||
|
: x(0), y(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T>::vec(T scalar)
|
||||||
|
: x(scalar), y(scalar)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T>::vec(T _x, T _y)
|
||||||
|
: x(_x), y(_y)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr inline vec<2, T> vec<2, T>::operator-() const
|
||||||
|
{
|
||||||
|
return vec<2, T>(-x, -y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T const& vec<2, T>::operator[](int i) const
|
||||||
|
{
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
default: [[fallthrough]];
|
||||||
|
case 0: return x;
|
||||||
|
case 1: return y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T>& vec<2, T>::operator=(vec<2, T> const& v)
|
||||||
|
{
|
||||||
|
this->x = static_cast<T>(v.x);
|
||||||
|
this->y = static_cast<T>(v.y);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T>& vec<2, T>::operator+=(vec<2, T> const& v)
|
||||||
|
{
|
||||||
|
*this = *this + vec<2, T>(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T>& vec<2, T>::operator-=(vec<2, T> const& v)
|
||||||
|
{
|
||||||
|
*this = *this - vec<2, T>(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T> operator+(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<2, T>(v1.x + v2.x,
|
||||||
|
v1.y + v2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T> operator-(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<2, T>(v1.x - v2.x,
|
||||||
|
v1.y - v2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T> operator*(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<2, T>(v1.x * v2.x,
|
||||||
|
v1.y * v2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T> operator*(vec<2, T> const& v1, T const& scalar)
|
||||||
|
{
|
||||||
|
return v1 * vec<2, T>(scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T> operator*(T const& scalar, vec<2, T> const& v1)
|
||||||
|
{
|
||||||
|
return vec<2, T>(scalar) * v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T> operator/(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<2, T>(v1.x / v2.x,
|
||||||
|
v1.y / v2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<2, T> operator/(vec<2, T> const& v1, T const& scalar)
|
||||||
|
{
|
||||||
|
return v1 / vec<2, T>(scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T dot(vec<2, T> const& v1, vec<2, T> const& v2)
|
||||||
|
{
|
||||||
|
vec<2, T> tmp(v1 * 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)
|
||||||
|
{
|
||||||
|
return vec<2, T>(func(v.x), func(v.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline constexpr vec<2, U> functor1(U (&func) (T const& x), vec<2, T> const& v)
|
||||||
|
{
|
||||||
|
return vec<2, U>(func(v.x), func(v.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T magnitude(vec<2, T> const& v)
|
||||||
|
{
|
||||||
|
return sqrt(dot(v, v));
|
||||||
|
}
|
@ -10,7 +10,10 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct vec<3, T>
|
struct vec<3, T>
|
||||||
{
|
{
|
||||||
T x, y, z;
|
union {
|
||||||
|
struct { T x, y, z; };
|
||||||
|
struct { T r, g, b; };
|
||||||
|
};
|
||||||
|
|
||||||
inline constexpr vec();
|
inline constexpr vec();
|
||||||
inline constexpr vec(T scalar);
|
inline constexpr vec(T scalar);
|
||||||
@ -109,6 +112,12 @@ inline constexpr vec<3, T> operator*(vec<3, T> const& v1, T const& scalar)
|
|||||||
return v1 * vec<3, T>(scalar);
|
return v1 * vec<3, T>(scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<3, T> operator*(T const& scalar, vec<3, T> const& v1)
|
||||||
|
{
|
||||||
|
return vec<3, T>(scalar) * v1;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr vec<3, T> operator/(vec<3, T> const& v1, vec<3, T> const& v2)
|
inline constexpr vec<3, T> operator/(vec<3, T> const& v1, vec<3, T> const& v2)
|
||||||
{
|
{
|
||||||
@ -130,6 +139,14 @@ inline constexpr T dot(vec<3, T> const& v1, vec<3, T> const& v2)
|
|||||||
return tmp.x + tmp.y + tmp.z;
|
return tmp.x + tmp.y + tmp.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<3, T> cross(vec<3, T> const& v1, vec<3, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<3, T>(v1.y * v2.z - v2.y * v1.z,
|
||||||
|
v1.z * v2.x - v2.z * v1.x,
|
||||||
|
v1.x * v2.y - v2.x * v1.y);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr vec<3, T> functor1(T (&func) (T const& x), vec<3, T> const& v)
|
inline constexpr vec<3, T> functor1(T (&func) (T const& x), vec<3, T> const& v)
|
||||||
{
|
{
|
||||||
@ -143,15 +160,7 @@ inline constexpr vec<3, U> functor1(U (&func) (T const& x), vec<3, T> const& v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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));
|
return sqrt(dot(v, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline constexpr vec<3, T> cross(vec<3, T> const& x, vec<3, T> const& y)
|
|
||||||
{
|
|
||||||
return vec<3, T>(x.y * y.z - y.y * x.z,
|
|
||||||
x.z * y.x - y.z * x.x,
|
|
||||||
x.x * y.y - y.x * x.y);
|
|
||||||
}
|
|
||||||
|
BIN
model/bear/bear.data
Normal file
BIN
model/bear/bear.data
Normal file
Binary file not shown.
15
model/bear/bear.data.h
Normal file
15
model/bear/bear.data.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern uint32_t _binary_model_bear_bear_data_start __asm("_binary_model_bear_bear_data_start");
|
||||||
|
extern uint32_t _binary_model_bear_bear_data_end __asm("_binary_model_bear_bear_data_end");
|
||||||
|
extern uint32_t _binary_model_bear_bear_data_size __asm("_binary_model_bear_bear_data_size");
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
22
model/bear/bear.mtl
Normal file
22
model/bear/bear.mtl
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Blender 4.3.2 MTL File: 'bear.blend'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl matBear
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 0.800000 0.800000 0.800000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.000000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
|
||||||
|
newmtl matOutline
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 0.000000 0.000000 0.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.000000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
3407
model/bear/bear0000.obj
Normal file
3407
model/bear/bear0000.obj
Normal file
File diff suppressed because it is too large
Load Diff
3407
model/bear/bear0005.obj
Normal file
3407
model/bear/bear0005.obj
Normal file
File diff suppressed because it is too large
Load Diff
3407
model/bear/bear0010.obj
Normal file
3407
model/bear/bear0010.obj
Normal file
File diff suppressed because it is too large
Load Diff
3407
model/bear/bear0015.obj
Normal file
3407
model/bear/bear0015.obj
Normal file
File diff suppressed because it is too large
Load Diff
3407
model/bear/bear0020.obj
Normal file
3407
model/bear/bear0020.obj
Normal file
File diff suppressed because it is too large
Load Diff
13
model/bear/material.h
Normal file
13
model/bear/material.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "model/material.h"
|
||||||
|
|
||||||
|
enum material {
|
||||||
|
bear_matBear,
|
||||||
|
bear_matOutline,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct material_descriptor bear_material[] = {
|
||||||
|
};
|
33616
model/bear/model.h
Normal file
33616
model/bear/model.h
Normal file
File diff suppressed because it is too large
Load Diff
25
model/material.h
Normal file
25
model/material.h
Normal 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;
|
||||||
|
};
|
59
model/model.h
Normal file
59
model/model.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "math/vec3.hpp"
|
||||||
|
#include "math/vec2.hpp"
|
||||||
|
|
||||||
|
#ifdef __dreamcast__
|
||||||
|
using vertex_position = vec<3, float>;
|
||||||
|
using vertex_normal = vec<3, float>;
|
||||||
|
using vertex_texture = vec<2, float>;
|
||||||
|
#endif
|
||||||
|
#ifdef __saturn__
|
||||||
|
#include "math/fp.hpp"
|
||||||
|
using vertex_position = vec<3, fp16_16>;
|
||||||
|
using vertex_normal = vec<3, fp16_16>;
|
||||||
|
using vertex_texture = vec<2, fp16_16>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct object {
|
||||||
|
const union triangle * triangle;
|
||||||
|
const union quadrilateral * quadrilateral;
|
||||||
|
const int triangle_count;
|
||||||
|
const int quadrilateral_count;
|
||||||
|
const int material;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct model {
|
||||||
|
const vertex_position * position;
|
||||||
|
const vertex_texture * texture;
|
||||||
|
const vertex_normal * normal;
|
||||||
|
const struct object ** object;
|
||||||
|
const int object_count;
|
||||||
|
};
|
76
scu-dsp/div10.asm
Normal file
76
scu-dsp/div10.asm
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
mov 0,ct0 ; num
|
||||||
|
mov 0,ct1 ; vdp2 address
|
||||||
|
mov 0,ct3 ; output
|
||||||
|
mvi 12345,mc0 ; m0[0] (12345)
|
||||||
|
|
||||||
|
;; output: m3
|
||||||
|
base10_loop:
|
||||||
|
mov 0,ct0
|
||||||
|
mvi div10_unsigned,pc
|
||||||
|
;; [X ] [Y ] [D1 ]
|
||||||
|
mov mc0,y mov 1,lop ; mvi imm,pc delay slot (executed twice)
|
||||||
|
;; after function return:
|
||||||
|
mov all,mc0 ; m0[1] (1234)
|
||||||
|
mov all,pl ; ??? why can't this happen in the next instruction?
|
||||||
|
;; mod10: multiply by 10:
|
||||||
|
sl mov alu,a
|
||||||
|
sl mov alu,a
|
||||||
|
sl mov alu,a
|
||||||
|
add mov alu,a
|
||||||
|
add mov alu,a mov 0,ct0 ; restore ct0 after 'mov all,mc1'
|
||||||
|
|
||||||
|
;; a: 12340
|
||||||
|
mov mc0,a mov all,pl
|
||||||
|
|
||||||
|
;; a: 12345 m0[0]
|
||||||
|
;; p: 12340
|
||||||
|
|
||||||
|
;; mod10: subtract (a - p)
|
||||||
|
sub mov alu,a
|
||||||
|
|
||||||
|
;; a: 5
|
||||||
|
|
||||||
|
;; store digit in m3
|
||||||
|
mov mc0,p clr a mov all,mc3 ; m0[1]
|
||||||
|
|
||||||
|
;; p: 1234
|
||||||
|
;; a: 0
|
||||||
|
add mov alu,a mov 0,ct0
|
||||||
|
|
||||||
|
;; a: 1234
|
||||||
|
jmp nz,base10_loop
|
||||||
|
mov all,mc0 ; jmp delay slot
|
||||||
|
|
||||||
|
endi
|
||||||
|
nop
|
||||||
|
|
||||||
|
;; argument: ry
|
||||||
|
;; return: a ← ry / 10
|
||||||
|
;; maximum ry is somewhere between 2 ^ 21 and 2 ^ 22
|
||||||
|
div10_unsigned:
|
||||||
|
;; 1 / 10 * (2 ^ 24) ~= 1677722 = 0x19999a
|
||||||
|
mvi 1677722,rx
|
||||||
|
mov mul,p clr a
|
||||||
|
ad2 mov alu,a
|
||||||
|
|
||||||
|
;; ALH: [nmlkjihgfedcba9876543210________]
|
||||||
|
;; ALL: [76543210________________________]
|
||||||
|
|
||||||
|
clr a mov alh,pl ; alh is (a >> 16)
|
||||||
|
add mov alu,a
|
||||||
|
|
||||||
|
;; ALL: [nmlkjihgfedcba9876543210________]
|
||||||
|
|
||||||
|
;; rotate left 24 requires fewer cycles than shift right 8
|
||||||
|
rl8 mov alu,a
|
||||||
|
rl8 mov alu,a
|
||||||
|
rl8 mov alu,a
|
||||||
|
|
||||||
|
;; ALL: [________nmlkjihgfedcba9876543210]
|
||||||
|
|
||||||
|
;; mask 24 bit result
|
||||||
|
mvi 0xffffff,pl
|
||||||
|
|
||||||
|
;; return to caller ; reset ct0
|
||||||
|
btm
|
||||||
|
and mov alu,a mov 0,ct0
|
35
scu-dsp/div10.cpp
Normal file
35
scu-dsp/div10.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "cdc/serial.h"
|
||||||
|
#include "scu.h"
|
||||||
|
#include "vdp2.h"
|
||||||
|
|
||||||
|
#include "scu-dsp/div10.dsp.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
scu.reg.PPAF = 0; // stop execution
|
||||||
|
scu.reg.PPAF = (1 << 15) | 0; // reset PC
|
||||||
|
|
||||||
|
uint32_t * program = (uint32_t *)&_binary_scu_dsp_div10_dsp_start;
|
||||||
|
int program_length = ((int)&_binary_scu_dsp_div10_dsp_size) / 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < program_length; i++) {
|
||||||
|
uint32_t p = program[i];
|
||||||
|
scu.reg.PPD = p;
|
||||||
|
serial_integer(p, 8, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
scu.reg.PPAF = (1 << 16); // execute
|
||||||
|
|
||||||
|
int end_flag = 0;
|
||||||
|
while (end_flag == 0) {
|
||||||
|
end_flag = (scu.reg.PPAF >> 18) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scu.reg.PPAF = 0;
|
||||||
|
scu.reg.PDA = 64 * 3; // m3[0]
|
||||||
|
|
||||||
|
serial_string("answer:\n");
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
serial_integer(scu.reg.PDD, 8, '\n');
|
||||||
|
}
|
||||||
|
}
|
5
scu-dsp/div10.dsp.h
Normal file
5
scu-dsp/div10.dsp.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
extern uint32_t _binary_scu_dsp_div10_dsp_start __asm("_binary_scu_dsp_div10_dsp_start");
|
||||||
|
extern uint32_t _binary_scu_dsp_div10_dsp_end __asm("_binary_scu_dsp_div10_dsp_end");
|
||||||
|
extern uint32_t _binary_scu_dsp_div10_dsp_size __asm("_binary_scu_dsp_div10_dsp_size");
|
104
scu-dsp/div10_vdp2.asm
Normal file
104
scu-dsp/div10_vdp2.asm
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
mov 0,ct0 ; num
|
||||||
|
mov 0,ct1 ; vdp2 address
|
||||||
|
mov 0,ct3 ; output
|
||||||
|
mvi 12345,mc0 ; m0[0] (12345)
|
||||||
|
|
||||||
|
;; clear m3
|
||||||
|
mov 7,lop
|
||||||
|
lps
|
||||||
|
mov 0,mc3
|
||||||
|
mov 0,ct3
|
||||||
|
|
||||||
|
;; output: m3
|
||||||
|
base10_loop:
|
||||||
|
mov 0,ct0
|
||||||
|
mvi div10_unsigned,pc
|
||||||
|
;; [X ] [Y ] [D1 ]
|
||||||
|
mov mc0,y mov 1,lop ; mvi imm,pc delay slot (executed twice)
|
||||||
|
;; after function return:
|
||||||
|
mov all,mc0 ; m0[1] (1234)
|
||||||
|
mov all,pl ; ??? why can't this happen in the next instruction?
|
||||||
|
;; mod10: multiply by 10:
|
||||||
|
sl mov alu,a
|
||||||
|
sl mov alu,a
|
||||||
|
sl mov alu,a
|
||||||
|
add mov alu,a
|
||||||
|
add mov alu,a mov 0,ct0 ; restore ct0 after 'mov all,mc1'
|
||||||
|
|
||||||
|
;; a: 12340
|
||||||
|
mov mc0,a mov all,pl
|
||||||
|
|
||||||
|
;; a: 12345 m0[0]
|
||||||
|
;; p: 12340
|
||||||
|
|
||||||
|
;; mod10: subtract (a - p)
|
||||||
|
sub mov alu,a
|
||||||
|
|
||||||
|
;; a: 5
|
||||||
|
|
||||||
|
;; convert to vdp2 character
|
||||||
|
mvi 16,pl
|
||||||
|
add mov alu,a
|
||||||
|
|
||||||
|
;; store digit in m3
|
||||||
|
mov mc0,p clr a mov all,mc3 ; m0[1]
|
||||||
|
|
||||||
|
;; p: 1234
|
||||||
|
;; a: 0
|
||||||
|
add mov alu,a mov 0,ct0
|
||||||
|
|
||||||
|
;; a: 1234
|
||||||
|
jmp nz,base10_loop
|
||||||
|
mov all,mc0 ; jmp delay slot
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; transfer to vdp2
|
||||||
|
;;
|
||||||
|
|
||||||
|
;; vdp2 address calculation
|
||||||
|
mvi ((8 * 0x4000 + (64 - 8) * 4 + 0x05e00000) >> 2),wa0
|
||||||
|
mov 0,ct3
|
||||||
|
;; clr a mov 0,ct3
|
||||||
|
;; add mov alu,a
|
||||||
|
;; mov all,wa0
|
||||||
|
|
||||||
|
;; end vdp2 address calculation
|
||||||
|
dma1 mc3,d0,8
|
||||||
|
dma_wait:
|
||||||
|
jmp t0,dma_wait
|
||||||
|
nop
|
||||||
|
|
||||||
|
endi
|
||||||
|
nop
|
||||||
|
|
||||||
|
;; argument: ry
|
||||||
|
;; return: a ← ry / 10
|
||||||
|
;; maximum ry is somewhere between 2 ^ 21 and 2 ^ 22
|
||||||
|
div10_unsigned:
|
||||||
|
;; 1 / 10 * (2 ^ 24) ~= 1677722 = 0x19999a
|
||||||
|
mvi 1677722,rx
|
||||||
|
mov mul,p clr a
|
||||||
|
ad2 mov alu,a
|
||||||
|
|
||||||
|
;; ALH: [nmlkjihgfedcba9876543210________]
|
||||||
|
;; ALL: [76543210________________________]
|
||||||
|
|
||||||
|
clr a mov alh,pl ; alh is (a >> 16)
|
||||||
|
add mov alu,a
|
||||||
|
|
||||||
|
;; ALL: [nmlkjihgfedcba9876543210________]
|
||||||
|
|
||||||
|
;; rotate left 24 requires fewer cycles than shift right 8
|
||||||
|
rl8 mov alu,a
|
||||||
|
rl8 mov alu,a
|
||||||
|
rl8 mov alu,a
|
||||||
|
|
||||||
|
;; ALL: [________nmlkjihgfedcba9876543210]
|
||||||
|
|
||||||
|
;; mask 24 bit result
|
||||||
|
mvi 0xffffff,pl
|
||||||
|
|
||||||
|
;; return to caller ; reset ct0
|
||||||
|
btm
|
||||||
|
and mov alu,a mov 0,ct0
|
171
scu-dsp/div10_vdp2.cpp
Normal file
171
scu-dsp/div10_vdp2.cpp
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
#include "cdc/serial.h"
|
||||||
|
#include "scu.h"
|
||||||
|
#include "vdp2.h"
|
||||||
|
#include "../common/vdp2_func.hpp"
|
||||||
|
|
||||||
|
#include "scu-dsp/div10_vdp2.dsp.h"
|
||||||
|
|
||||||
|
#include "font/hp_100lx_4bit_flip.data.h"
|
||||||
|
|
||||||
|
void cell_data()
|
||||||
|
{
|
||||||
|
const uint32_t * start = reinterpret_cast<uint32_t *>(&_binary_font_hp_100lx_4bit_flip_data_start);
|
||||||
|
const int size = reinterpret_cast<uint32_t>(&_binary_font_hp_100lx_4bit_flip_data_size);
|
||||||
|
|
||||||
|
// the start of VRAM-A0
|
||||||
|
for (int i = 0; i < (size / 4); i++) {
|
||||||
|
vdp2.vram.u32[i] = start[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void palette_data()
|
||||||
|
{
|
||||||
|
vdp2.cram.u16[0] = 0x0000;
|
||||||
|
vdp2.cram.u16[1] = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vdp2_init()
|
||||||
|
{
|
||||||
|
v_blank_in();
|
||||||
|
|
||||||
|
// DISP: Please make sure to change this bit from 0 to 1 during V blank.
|
||||||
|
vdp2.reg.TVMD = ( TVMD__DISP | TVMD__LSMD__NON_INTERLACE
|
||||||
|
| TVMD__VRESO__240 | TVMD__HRESO__NORMAL_320);
|
||||||
|
|
||||||
|
/* set the color mode to 5bits per channel, 1024 colors */
|
||||||
|
vdp2.reg.RAMCTL = RAMCTL__CRMD__RGB_5BIT_1024
|
||||||
|
| RAMCTL__VRAMD
|
||||||
|
| RAMCTL__VRBMD
|
||||||
|
| RAMCTL__RDBSA0__CHARACTER_PATTERN_TABLE // VRAM-A0 0x000000
|
||||||
|
| RAMCTL__RDBSA1__PATTERN_NAME_TABLE; // VRAM-A1 0x020000
|
||||||
|
|
||||||
|
vdp2.reg.VRSIZE = 0;
|
||||||
|
|
||||||
|
/* enable display of NBG0 */
|
||||||
|
vdp2.reg.BGON = BGON__R0ON | BGON__R0TPON;
|
||||||
|
|
||||||
|
/* set character format for NBG0 to palettized 16 color
|
||||||
|
set enable "cell format" for NBG0
|
||||||
|
set character size for NBG0 to 1x1 cell */
|
||||||
|
vdp2.reg.CHCTLB = CHCTLB__R0CHCN__16_COLOR
|
||||||
|
| CHCTLB__R0BMEN__CELL_FORMAT
|
||||||
|
| CHCTLB__R0CHSZ__1x1_CELL;
|
||||||
|
|
||||||
|
/* plane size */
|
||||||
|
vdp2.reg.PLSZ = PLSZ__RAPLSZ__1x1
|
||||||
|
| PLSZ__RBPLSZ__1x1;
|
||||||
|
|
||||||
|
/* map plane offset
|
||||||
|
1-word: value of bit 6-0 * 0x2000
|
||||||
|
2-word: value of bit 5-0 * 0x4000
|
||||||
|
*/
|
||||||
|
// plane_a_offset is at the start of VRAM-A1
|
||||||
|
constexpr int plane_a = 8;
|
||||||
|
constexpr int plane_a_offset = plane_a * 0x4000;
|
||||||
|
|
||||||
|
constexpr int page_size = 64 * 64 * 2; // N0PNB__1WORD (16-bit)
|
||||||
|
constexpr int plane_size = page_size * 1;
|
||||||
|
|
||||||
|
/* cycle pattern table not used for RBG0 ? */
|
||||||
|
vdp2.reg.CYCA0 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCA1 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCB0 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCB1 = 0x0F44F99F;
|
||||||
|
|
||||||
|
vdp2.reg.MPOFR = MPOFR__RAMP(0); // bits 8~6
|
||||||
|
vdp2.reg.MPABRA = MPABRA__RAMPB(plane_a) | MPABRA__RAMPA(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPCDRA = MPCDRA__RAMPD(plane_a) | MPCDRA__RAMPC(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPEFRA = MPEFRA__RAMPF(plane_a) | MPEFRA__RAMPE(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPGHRA = MPGHRA__RAMPH(plane_a) | MPGHRA__RAMPG(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPIJRA = MPIJRA__RAMPJ(plane_a) | MPIJRA__RAMPI(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPKLRA = MPKLRA__RAMPL(plane_a) | MPKLRA__RAMPK(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPMNRA = MPMNRA__RAMPN(plane_a) | MPMNRA__RAMPM(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPOPRA = MPOPRA__RAMPP(plane_a) | MPOPRA__RAMPO(plane_a); // bits 5~0
|
||||||
|
|
||||||
|
vdp2.reg.PNCR = PNCR__R0PNB__2WORD;
|
||||||
|
|
||||||
|
vdp2.reg.RPMD = RPMD__ROTATION_PARAMETER_A;
|
||||||
|
|
||||||
|
//vdp2.reg.RPRCTL = 0;
|
||||||
|
|
||||||
|
vdp2.reg.KTCTL = 0;
|
||||||
|
|
||||||
|
vdp2.reg.KTAOF = 0;
|
||||||
|
|
||||||
|
vdp2.reg.PRIR = 3;
|
||||||
|
|
||||||
|
palette_data();
|
||||||
|
cell_data();
|
||||||
|
|
||||||
|
volatile struct vdp2_rotation_parameter_table * table = (struct vdp2_rotation_parameter_table *)&vdp2.vram.u32[0x4000 / 4];
|
||||||
|
table->screen_start_coordinate_xst = 0;
|
||||||
|
table->screen_start_coordinate_yst = 0;
|
||||||
|
table->screen_start_coordinate_zst = 0;
|
||||||
|
table->screen_vertical_coordinate_increment_dxst = 0;
|
||||||
|
table->screen_vertical_coordinate_increment_dyst = (1 << 16);
|
||||||
|
table->screen_horizontal_coordinate_increment_dx = (1 << 16);
|
||||||
|
table->screen_horizontal_coordinate_increment_dy = 0;
|
||||||
|
table->rotation_matrix_parameter_a = (-1 << 16);
|
||||||
|
table->rotation_matrix_parameter_b = 0;
|
||||||
|
table->rotation_matrix_parameter_c = 0;
|
||||||
|
table->rotation_matrix_parameter_d = 0;
|
||||||
|
table->rotation_matrix_parameter_e = (1 << 16);
|
||||||
|
table->rotation_matrix_parameter_f = 0;
|
||||||
|
table->viewpoint_coordinate_px = 0;
|
||||||
|
table->viewpoint_coordinate_py = 0;
|
||||||
|
table->viewpoint_coordinate_pz = 0;
|
||||||
|
table->center_point_coordinate_px = 0;
|
||||||
|
table->center_point_coordinate_py = 0;
|
||||||
|
table->center_point_coordinate_pz = 0;
|
||||||
|
table->horizontal_shift_mx = 0;
|
||||||
|
table->horizontal_shift_my = 0;
|
||||||
|
table->scaling_coefficient_kx = (1 << 16);
|
||||||
|
table->scaling_coefficient_ky = (1 << 16);
|
||||||
|
|
||||||
|
vdp2.reg.RPTA = (((uint32_t)table) >> 1) & 0x7ffff;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
for (int i = 0; i < 64 * 64; i++) {
|
||||||
|
vdp2.vram.u32[(plane_a_offset / 4) + i] = ' ' - 0x20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vdp2_init();
|
||||||
|
|
||||||
|
scu.reg.PPAF = 0; // stop execution
|
||||||
|
scu.reg.PPAF = (1 << 15) | 0; // reset PC
|
||||||
|
|
||||||
|
uint32_t * program = (uint32_t *)&_binary_scu_dsp_div10_vdp2_dsp_start;
|
||||||
|
int program_length = ((int)&_binary_scu_dsp_div10_vdp2_dsp_size) / 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < program_length; i++) {
|
||||||
|
uint32_t p = program[i];
|
||||||
|
scu.reg.PPD = p;
|
||||||
|
//serial_integer(p, 8, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
scu.reg.PPAF = (1 << 16); // execute
|
||||||
|
|
||||||
|
int end_flag = 0;
|
||||||
|
while (end_flag == 0) {
|
||||||
|
end_flag = (scu.reg.PPAF >> 18) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scu.reg.PPAF = 0;
|
||||||
|
scu.reg.PDA = 64 * 3; // m3[0]
|
||||||
|
|
||||||
|
serial_string("answer:\n");
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
serial_integer(scu.reg.PDD, 8, '\n');
|
||||||
|
}
|
||||||
|
serial_string("answer2:\n");
|
||||||
|
volatile uint32_t * buf = &vdp2.vram.u32[(8 * 0x4000) / 4 + 64];
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
uint32_t addr = (uint32_t)&buf[-(i + 1)];
|
||||||
|
serial_integer(addr, 8, ' ');
|
||||||
|
serial_integer(buf[-(i + 1)], 8, '\n');
|
||||||
|
}
|
||||||
|
}
|
5
scu-dsp/div10_vdp2.dsp.h
Normal file
5
scu-dsp/div10_vdp2.dsp.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
extern uint32_t _binary_scu_dsp_div10_vdp2_dsp_start __asm("_binary_scu_dsp_div10_vdp2_dsp_start");
|
||||||
|
extern uint32_t _binary_scu_dsp_div10_vdp2_dsp_end __asm("_binary_scu_dsp_div10_vdp2_dsp_end");
|
||||||
|
extern uint32_t _binary_scu_dsp_div10_vdp2_dsp_size __asm("_binary_scu_dsp_div10_vdp2_dsp_size");
|
93
scu-dsp/parse10.asm
Normal file
93
scu-dsp/parse10.asm
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
;; input m0[0] start address
|
||||||
|
;; [X ] [Y ] [D1 ]
|
||||||
|
;; mov 0,ct0
|
||||||
|
;; mov mc0,ra0
|
||||||
|
|
||||||
|
;; variables:
|
||||||
|
;; m0[0]
|
||||||
|
;; m0[1] dma read value (local); post-shift 4-byte remainder (global)
|
||||||
|
;; m0[2] saved accumulator (global)
|
||||||
|
|
||||||
|
setup:
|
||||||
|
;; [X ] [Y ] [D1 ]
|
||||||
|
mov 1,ct0
|
||||||
|
mov 0,ct3
|
||||||
|
mov 0,mc0
|
||||||
|
mov 0,mc0
|
||||||
|
mvi parse_base10,pc
|
||||||
|
mov 1,lop
|
||||||
|
;; parse_base10 return
|
||||||
|
mov all,mc3
|
||||||
|
|
||||||
|
mvi parse_base10,pc
|
||||||
|
mov 1,lop
|
||||||
|
;; parse_base10 return
|
||||||
|
mov all,mc3
|
||||||
|
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
parse_base10:
|
||||||
|
;; [X ] [Y ] [D1 ]
|
||||||
|
mov 1,ct0
|
||||||
|
mov m0,p mov m0,a
|
||||||
|
add
|
||||||
|
jmp nz,parse_loop
|
||||||
|
clr a ; delay slot
|
||||||
|
dma_next_chunk:
|
||||||
|
;; dma d0,mc0,1
|
||||||
|
;; begin fake number 0x39322033 "92 3"
|
||||||
|
mvi 0x393220,pl
|
||||||
|
add mov alu,a mov 0x33,pl
|
||||||
|
rl8 mov alu,a mov 1,ct0
|
||||||
|
add mov all,mc0
|
||||||
|
;; end fake number
|
||||||
|
end_dma_next_chunk:
|
||||||
|
parse_loop:
|
||||||
|
;; extract first (leftmost) digit
|
||||||
|
mov 1,ct0
|
||||||
|
mov mc0,a mov 0x7f,pl
|
||||||
|
or
|
||||||
|
jmp s,end_of_input
|
||||||
|
rl8 mov alu,a mov 10,rx ; m0[2] 0x00000000
|
||||||
|
jmp z,dma_next_chunk
|
||||||
|
and mov m0,y mov all,pl
|
||||||
|
|
||||||
|
;; MUL: post-multiplication accumulator
|
||||||
|
;; P: post-mask digit
|
||||||
|
;; A: pre-xor string
|
||||||
|
mov 1,ct0
|
||||||
|
xor clr a mov all,mc0 ; m0[1] 0x20323300
|
||||||
|
|
||||||
|
add mov alu,a mov 0x30,pl ; 0x30 ascii '0'
|
||||||
|
|
||||||
|
;; A: post-mask digit
|
||||||
|
;;
|
||||||
|
sub mov alu,a mov 10,pl
|
||||||
|
|
||||||
|
;; if ((0x39 - 0x30) < 0) goto non_digit;
|
||||||
|
jmp s,non_digit
|
||||||
|
;; possibly set S flag for `jmp ns,non_digit`
|
||||||
|
sub mov 2,ct0 ; sub in delay slot
|
||||||
|
;; if (((0x39 - 0x30) - 10) >= 0) goto non_digit;
|
||||||
|
jmp ns,non_digit
|
||||||
|
mov mul,p mov 2,ct0 ; mov in delay slot
|
||||||
|
;; P: accumulator * 10 result
|
||||||
|
digit:
|
||||||
|
;; we have a valid digit; add it to the accumulator; save to m0[2]
|
||||||
|
;; [X ] [Y ] [D1 ]
|
||||||
|
jmp parse_loop
|
||||||
|
add mov all,mc0 ; add in delay slot ; m0[2] 0x00000009
|
||||||
|
|
||||||
|
non_digit:
|
||||||
|
;; this is not a valid digit; return and clear the accumulator as A
|
||||||
|
;; [X ] [Y ] [D1 ]
|
||||||
|
btm
|
||||||
|
mov m0,a mov 0,mc0 ; clr in delay slot ; m0[2]
|
||||||
|
|
||||||
|
;; m0:
|
||||||
|
;; 00000000 32330000 00000009 0000000
|
||||||
|
end_of_input:
|
||||||
|
btm
|
||||||
|
clr a
|
164
tools/ttf_bitmap2.cpp
Normal file
164
tools/ttf_bitmap2.cpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
int
|
||||||
|
load_bitmap_char(FT_Face face,
|
||||||
|
FT_ULong char_code,
|
||||||
|
bool hflip,
|
||||||
|
uint8_t * buf)
|
||||||
|
{
|
||||||
|
FT_Error error;
|
||||||
|
FT_UInt glyph_index = FT_Get_Char_Index(face, char_code);
|
||||||
|
|
||||||
|
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||||
|
if (error) {
|
||||||
|
fprintf(stderr, "FT_Load_Glyph %s\n", FT_Error_String(error));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("horiBearingX: %ld\n", face->glyph->metrics.horiBearingX >> 6);
|
||||||
|
printf("horiBearingY: %ld\n", face->glyph->metrics.horiBearingY >> 6);
|
||||||
|
printf("horiAdvance: %ld\n", face->glyph->metrics.horiAdvance >> 6);
|
||||||
|
printf("width: %ld\n", face->glyph->metrics.width >> 6);
|
||||||
|
printf("height: %ld\n", face->glyph->metrics.height >> 6);
|
||||||
|
|
||||||
|
assert(face->glyph->format == FT_GLYPH_FORMAT_BITMAP);
|
||||||
|
assert(face->glyph->bitmap.num_grays == 2);
|
||||||
|
|
||||||
|
for (int y = 0; y < (int)face->glyph->bitmap.rows; y++) {
|
||||||
|
uint8_t * row = &face->glyph->bitmap.buffer[y * face->glyph->bitmap.pitch];
|
||||||
|
for (int x = 0; x < (int)face->glyph->bitmap.width; x += 1) {
|
||||||
|
const int bit = (row[x / 8] >> (7 - (x % 8))) & 1;
|
||||||
|
//std::cerr << (bit ? "█" : " ");
|
||||||
|
if (hflip)
|
||||||
|
buf[y * face->glyph->bitmap.width + (7 - x)] = bit;
|
||||||
|
else
|
||||||
|
buf[y * face->glyph->bitmap.width + x] = bit;
|
||||||
|
}
|
||||||
|
//std::cerr << "|\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return face->glyph->bitmap.rows * face->glyph->bitmap.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_font(FT_Library * library, FT_Face * face, const char * font_file_path)
|
||||||
|
{
|
||||||
|
FT_Error error;
|
||||||
|
|
||||||
|
error = FT_Init_FreeType(library);
|
||||||
|
if (error) {
|
||||||
|
fprintf(stderr, "FT_Init_FreeType\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = FT_New_Face(*library, font_file_path, 0, face);
|
||||||
|
if (error) {
|
||||||
|
fprintf(stderr, "FT_New_Face\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = FT_Select_Size(*face, 0);
|
||||||
|
if (error) {
|
||||||
|
fprintf(stderr, "FT_Select_Size: %d: %s\n", error, FT_Error_String(error));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usage(const char * argv_0)
|
||||||
|
{
|
||||||
|
printf("%s [start-hex] [end-hex] [font-width] [font-height] [hflip] [font-file-path] [output-file-path]\n", argv_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pack_4bit(const uint8_t * src, int width, int height, int size, uint8_t * dst)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
while (offset < size) {
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width; x += 2) {
|
||||||
|
int px0 = src[offset + y * width + x + 0];
|
||||||
|
int px1 = src[offset + y * width + x + 1];
|
||||||
|
dst[(offset / 2) + y * (width / 2) + (x / 2)] = (px0 << 4) | (px1 << 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += width * height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char * argv[])
|
||||||
|
{
|
||||||
|
if (argc != 8) {
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * endptr;
|
||||||
|
|
||||||
|
int start_hex = strtol(argv[1], &endptr, 16);
|
||||||
|
assert(*endptr == 0);
|
||||||
|
int end_hex = strtol(argv[2], &endptr, 16);
|
||||||
|
assert(*endptr == 0);
|
||||||
|
|
||||||
|
int font_width = strtol(argv[3], &endptr, 10);
|
||||||
|
assert(*endptr == 0);
|
||||||
|
int font_height = strtol(argv[4], &endptr, 10);
|
||||||
|
assert(*endptr == 0);
|
||||||
|
|
||||||
|
int hflip = strtol(argv[5], &endptr, 10);
|
||||||
|
assert(*endptr == 0);
|
||||||
|
assert(hflip == 0 || hflip == 1);
|
||||||
|
|
||||||
|
const char * font_file_path = argv[6];
|
||||||
|
const char * output_file_path = argv[7];
|
||||||
|
|
||||||
|
printf("start_hex %x\n", start_hex);
|
||||||
|
printf("end_hex %x\n", start_hex);
|
||||||
|
printf("font_width %d\n", font_width);
|
||||||
|
printf("font_height %d\n", font_height);
|
||||||
|
printf("font_file_path %s\n", font_file_path);
|
||||||
|
printf("output_file_path %s\n", output_file_path);
|
||||||
|
|
||||||
|
FT_Library library;
|
||||||
|
FT_Face face;
|
||||||
|
int res;
|
||||||
|
res = load_font(&library, &face, font_file_path);
|
||||||
|
if (res < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int texture_buf_size = font_width * font_height * ((end_hex - start_hex) + 1);
|
||||||
|
uint8_t * texture = (uint8_t *)malloc(texture_buf_size);
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
for (int char_code = start_hex; char_code <= end_hex; char_code++) {
|
||||||
|
assert(offset < texture_buf_size);
|
||||||
|
|
||||||
|
res = load_bitmap_char(face,
|
||||||
|
char_code,
|
||||||
|
hflip,
|
||||||
|
&texture[offset]);
|
||||||
|
if (res < 0)
|
||||||
|
return - 1;
|
||||||
|
|
||||||
|
assert(res == font_width * font_height);
|
||||||
|
|
||||||
|
offset += res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * pack = (uint8_t *)malloc(texture_buf_size / 2);
|
||||||
|
pack_4bit(texture, font_width, font_height, offset, pack);
|
||||||
|
|
||||||
|
FILE * out = fopen(output_file_path, "w");
|
||||||
|
if (out == NULL) {
|
||||||
|
perror("fopen(w)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//fwrite((void *)texture, texture_buf_size, 1, out);
|
||||||
|
fwrite((void *)pack, texture_buf_size / 2, 1, out);
|
||||||
|
fclose(out);
|
||||||
|
}
|
243
vdp1/bear.cpp
Normal file
243
vdp1/bear.cpp
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "vdp2.h"
|
||||||
|
#include "vdp1.h"
|
||||||
|
|
||||||
|
#include <concepts>
|
||||||
|
|
||||||
|
#include "common/vdp2_func.hpp"
|
||||||
|
|
||||||
|
#include "math/fp.hpp"
|
||||||
|
#include "math/vec3.hpp"
|
||||||
|
#include "math/mat4x4.hpp"
|
||||||
|
|
||||||
|
#include "cos.hpp"
|
||||||
|
|
||||||
|
#include "model/model.h"
|
||||||
|
#include "model/bear/material.h"
|
||||||
|
#include "model/bear/model.h"
|
||||||
|
|
||||||
|
// |--
|
||||||
|
// |
|
||||||
|
// |
|
||||||
|
|
||||||
|
using vec3 = vec<3, fp16_16>;
|
||||||
|
using mat4x4 = mat<4, 4, fp16_16>;
|
||||||
|
|
||||||
|
struct canvas {
|
||||||
|
fp16_16 width;
|
||||||
|
fp16_16 height;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr struct canvas canvas = { 240, 240 };
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
vec<3, T> viewport_to_canvas(T x, T y)
|
||||||
|
{
|
||||||
|
return vec<3, T>(x * canvas.width, y * canvas.height, T(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<3, T> project_vertex(vec<3, T> const& v)
|
||||||
|
{
|
||||||
|
// / (v.z - T(5))
|
||||||
|
// / (v.z - T(5))
|
||||||
|
return viewport_to_canvas<T>((v.x * T(0.5) + T(2.0/3.0)),
|
||||||
|
(v.y * T(0.5) + T(0.5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline uint16_t rgb15(int32_t r, int32_t g, int32_t b)
|
||||||
|
{
|
||||||
|
return ((b & 31) << 10) | ((g & 31) << 5) | ((r & 31) << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr uint16_t colors[] = {
|
||||||
|
rgb15(31, 0, 0), // red
|
||||||
|
rgb15( 0, 31, 0), // green
|
||||||
|
rgb15( 0, 0, 31), // blue
|
||||||
|
rgb15(31, 0, 31), // magenta
|
||||||
|
rgb15( 0, 31, 31), // cyan
|
||||||
|
rgb15(31, 31, 0), // yellow
|
||||||
|
};
|
||||||
|
|
||||||
|
static int32_t tick = 0;
|
||||||
|
|
||||||
|
static inline void render_quad(int ix, const vec3 a, const vec3 b, const vec3 c, const vec3 d)
|
||||||
|
{
|
||||||
|
vdp1.vram.cmd[ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__POLYGON;
|
||||||
|
vdp1.vram.cmd[ix].LINK = 0;
|
||||||
|
vdp1.vram.cmd[ix].PMOD = PMOD__ECD | PMOD__SPD;
|
||||||
|
vdp1.vram.cmd[ix].COLR = COLR__RGB | colors[ix & 3];
|
||||||
|
|
||||||
|
vdp1.vram.cmd[ix].A.X = static_cast<int>(a.x);
|
||||||
|
vdp1.vram.cmd[ix].A.Y = static_cast<int>(a.y);
|
||||||
|
vdp1.vram.cmd[ix].B.X = static_cast<int>(b.x);
|
||||||
|
vdp1.vram.cmd[ix].B.Y = static_cast<int>(b.y);
|
||||||
|
vdp1.vram.cmd[ix].C.X = static_cast<int>(c.x);
|
||||||
|
vdp1.vram.cmd[ix].C.Y = static_cast<int>(c.y);
|
||||||
|
vdp1.vram.cmd[ix].D.X = static_cast<int>(d.x);
|
||||||
|
vdp1.vram.cmd[ix].D.Y = static_cast<int>(d.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
int render_object(int ix,
|
||||||
|
const mat4x4& screen,
|
||||||
|
const struct model * model,
|
||||||
|
const struct object * object0)
|
||||||
|
{
|
||||||
|
mat4x4 trans = screen;
|
||||||
|
|
||||||
|
for (int i = 0; i < object0->quadrilateral_count; i++) {
|
||||||
|
|
||||||
|
const union quadrilateral * quad0 = &object0->quadrilateral[i];
|
||||||
|
|
||||||
|
vec3 a0 = model->position[quad0->v[0].position];
|
||||||
|
vec3 b0 = model->position[quad0->v[1].position];
|
||||||
|
vec3 c0 = model->position[quad0->v[2].position];
|
||||||
|
vec3 d0 = model->position[quad0->v[3].position];
|
||||||
|
|
||||||
|
vec3 a = trans * a0;
|
||||||
|
vec3 b = trans * b0;
|
||||||
|
vec3 c = trans * c0;
|
||||||
|
vec3 d = trans * d0;
|
||||||
|
|
||||||
|
vec3 an0 = trans * model->normal[quad0->v[0].normal];
|
||||||
|
//vec3 l = {0, 0, 1};
|
||||||
|
fp16_16 cull = dot(a, an0);
|
||||||
|
|
||||||
|
if (cull.value > 0) {
|
||||||
|
// `origin` above is p==0 below; the `origin` calculation could
|
||||||
|
// be reused, though it would hurt readability slightly
|
||||||
|
/*
|
||||||
|
for (int p = 0; p < 4; p++) {
|
||||||
|
const vec3& v0 = vertices[face[p]];
|
||||||
|
|
||||||
|
// rotation
|
||||||
|
const vec3 v1 = transform * v0;
|
||||||
|
// translation
|
||||||
|
const vec3 v2{v1.x, v1.y + fp16_16(1), v1.z + fp16_16(2)};
|
||||||
|
|
||||||
|
const vec3 v3 = project_vertex(v2 / v2.z);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
render_quad(ix,
|
||||||
|
project_vertex(a / a.z),
|
||||||
|
project_vertex(b / b.z),
|
||||||
|
project_vertex(c / c.z),
|
||||||
|
project_vertex(d / d.z));
|
||||||
|
|
||||||
|
ix++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render()
|
||||||
|
{
|
||||||
|
tick++;
|
||||||
|
int ix = 2;
|
||||||
|
|
||||||
|
const mat4x4 scale {
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, -1, 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const int rx = tick >> 2;
|
||||||
|
const mat4x4 rotationX {
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, cos(rx), sin(rx), 0,
|
||||||
|
0, -sin(rx), cos(rx), 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const int ry = tick >> 1;
|
||||||
|
const mat4x4 rotationY {
|
||||||
|
cos(ry), 0, -sin(ry), 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
sin(ry), 0, cos(ry), 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mat4x4 translation = {
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, 1, 0, 4.5,
|
||||||
|
0, 0, 1, 6.5,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mat4x4 screen = translation * rotationY * scale;
|
||||||
|
|
||||||
|
//const vec3 camera = {0, 0, 0};
|
||||||
|
|
||||||
|
const int frame_ix0 = 0;
|
||||||
|
const struct model * model = &bear_model;
|
||||||
|
const struct object * object0 = bear_object[frame_ix0 * 2];
|
||||||
|
//const struct object * object1 = bear_object[frame_ix1 * 2];
|
||||||
|
|
||||||
|
ix = render_object(ix, screen, model, object0);
|
||||||
|
|
||||||
|
vdp1.vram.cmd[ix].CTRL = CTRL__END;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
v_blank_in();
|
||||||
|
|
||||||
|
// DISP: Please make sure to change this bit from 0 to 1 during V blank.
|
||||||
|
vdp2.reg.TVMD = ( TVMD__DISP | TVMD__LSMD__NON_INTERLACE
|
||||||
|
| TVMD__VRESO__240 | TVMD__HRESO__NORMAL_320);
|
||||||
|
|
||||||
|
// disable all VDP2 backgrounds (e.g: the Sega bios logo)
|
||||||
|
vdp2.reg.BGON = 0;
|
||||||
|
|
||||||
|
// VDP2 User's Manual:
|
||||||
|
// "When sprite data is in an RGB format, sprite register 0 is selected"
|
||||||
|
// "When the value of a priority number is 0h, it is read as transparent"
|
||||||
|
//
|
||||||
|
// The power-on value of PRISA is zero. Set the priority for sprite register 0
|
||||||
|
// to some number greater than zero, so that the color data is not interpreted
|
||||||
|
// as "transparent".
|
||||||
|
vdp2.reg.PRISA = PRISA__S0PRIN(1); // Sprite register 0 Priority Number
|
||||||
|
|
||||||
|
/* TVM settings must be performed from the second H-blank IN interrupt after the
|
||||||
|
V-blank IN interrupt to the H-blank IN interrupt immediately after the V-blank
|
||||||
|
OUT interrupt. */
|
||||||
|
// "normal" display resolution, 16 bits per pixel, 512x256 framebuffer
|
||||||
|
vdp1.reg.TVMR = TVMR__TVM__NORMAL;
|
||||||
|
|
||||||
|
// swap framebuffers every 1 cycle; non-interlace
|
||||||
|
vdp1.reg.FBCR = 0;
|
||||||
|
|
||||||
|
// during a framebuffer erase cycle, write the color "black" to each pixel
|
||||||
|
constexpr uint16_t black = 0x0000;
|
||||||
|
vdp1.reg.EWDR = black;
|
||||||
|
|
||||||
|
// the EWLR/EWRR macros use somewhat nontrivial math for the X coordinates
|
||||||
|
// erase upper-left coordinate
|
||||||
|
vdp1.reg.EWLR = EWLR__16BPP_X1(0) | EWLR__Y1(0);
|
||||||
|
|
||||||
|
// erase lower-right coordinate
|
||||||
|
vdp1.reg.EWRR = EWRR__16BPP_X3(319) | EWRR__Y3(239);
|
||||||
|
|
||||||
|
vdp1.vram.cmd[0].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__SYSTEM_CLIP_COORDINATES;
|
||||||
|
vdp1.vram.cmd[0].LINK = 0;
|
||||||
|
vdp1.vram.cmd[0].XC = 319;
|
||||||
|
vdp1.vram.cmd[0].YC = 239;
|
||||||
|
|
||||||
|
vdp1.vram.cmd[1].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__LOCAL_COORDINATE;
|
||||||
|
vdp1.vram.cmd[1].LINK = 0;
|
||||||
|
vdp1.vram.cmd[1].XA = 0;
|
||||||
|
vdp1.vram.cmd[1].YA = 0;
|
||||||
|
|
||||||
|
vdp1.vram.cmd[2].CTRL = CTRL__END;
|
||||||
|
|
||||||
|
// start drawing (execute the command list) on every frame
|
||||||
|
vdp1.reg.PTMR = PTMR__PTM__FRAME_CHANGE;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
v_blank_in();
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
}
|
189
vdp2/line_color_screen.cpp
Normal file
189
vdp2/line_color_screen.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
color data
|
||||||
|
|
||||||
|
255 colors, 3 bytes per channel, packed
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
image data
|
||||||
|
|
||||||
|
64*64 px, 1 byte per palette index
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "vdp2.h"
|
||||||
|
#include "../common/vdp2_func.hpp"
|
||||||
|
|
||||||
|
inline constexpr uint16_t rgb555(int r, int g, int b)
|
||||||
|
{
|
||||||
|
if (r > 255) r = 255;
|
||||||
|
if (g > 255) g = 255;
|
||||||
|
if (b > 255) b = 255;
|
||||||
|
if (r < 0) r = 0;
|
||||||
|
if (g < 0) g = 0;
|
||||||
|
if (b < 0) b = 0;
|
||||||
|
|
||||||
|
return ((b >> 3) << 10) // blue
|
||||||
|
| ((g >> 3) << 5) // green
|
||||||
|
| ((r >> 3) << 0); // red
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void fill(T * buf, T v, int32_t n) noexcept
|
||||||
|
{
|
||||||
|
while (n > 0) {
|
||||||
|
*buf++ = v;
|
||||||
|
n -= (sizeof (T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct color {
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct interp {
|
||||||
|
int line;
|
||||||
|
struct color color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct interp gradient[] = {
|
||||||
|
{ 0, {0x59, 0x6b, 0x88}},
|
||||||
|
{ 40, {0x59, 0x6b, 0x88}},
|
||||||
|
{ 80, {0xa8, 0x34, 0x14}},
|
||||||
|
{110, {0xac, 0xa5, 0x30}},
|
||||||
|
{120, {0xac, 0xa5, 0x30}},
|
||||||
|
{140, {0xa8, 0x34, 0x14}},
|
||||||
|
{999, {0xa8, 0x34, 0x14}},
|
||||||
|
};
|
||||||
|
|
||||||
|
const int gradient_len = (sizeof (gradient)) / (sizeof (gradient[0]));
|
||||||
|
|
||||||
|
struct color lerp(struct color a, struct color b, int start, int end, int y)
|
||||||
|
{
|
||||||
|
if (start == end) {
|
||||||
|
return (struct color){a.r, a.g, a.b};
|
||||||
|
}
|
||||||
|
if (end == 999) {
|
||||||
|
return (struct color){a.r, a.g, a.b};
|
||||||
|
}
|
||||||
|
|
||||||
|
int dr = ((int)b.r - (int)a.r);
|
||||||
|
int dg = ((int)b.g - (int)a.g);
|
||||||
|
int db = ((int)b.b - (int)a.b);
|
||||||
|
|
||||||
|
int t1 = end - start;
|
||||||
|
int t0 = y - start;
|
||||||
|
|
||||||
|
return (struct color){
|
||||||
|
(uint8_t)((int)a.r + dr * t0 / t1),
|
||||||
|
(uint8_t)((int)a.g + dg * t0 / t1),
|
||||||
|
(uint8_t)((int)a.b + db * t0 / t1),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_gradient()
|
||||||
|
{
|
||||||
|
struct interp * prev = &gradient[0];
|
||||||
|
struct interp * cur = prev;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < 240; y++) {
|
||||||
|
if (y >= cur->line) {
|
||||||
|
prev = cur;
|
||||||
|
i += 1;
|
||||||
|
cur = &gradient[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct color c = lerp(prev->color, cur->color, prev->line, cur->line, y);
|
||||||
|
vdp2.vram.u16[y] = rgb555(c.r, c.g, c.b);
|
||||||
|
//vdp2.vram.u16[y] = rgb555(cur->color.r, cur->color.g, cur->color.b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
v_blank_in();
|
||||||
|
|
||||||
|
// DISP: Please make sure to change this bit from 0 to 1 during V blank.
|
||||||
|
vdp2.reg.TVMD = ( TVMD__DISP | TVMD__LSMD__NON_INTERLACE
|
||||||
|
| TVMD__VRESO__240 | TVMD__HRESO__NORMAL_320);
|
||||||
|
|
||||||
|
|
||||||
|
/* set the color mode to 5bits per channel, 1024 colors */
|
||||||
|
vdp2.reg.RAMCTL = RAMCTL__CRMD__RGB_5BIT_1024;
|
||||||
|
|
||||||
|
/* enable display of NBG0 */
|
||||||
|
//vdp2.reg.BGON = BGON__N0ON;
|
||||||
|
|
||||||
|
/* set character format for NBG0 to palettized 2048 color
|
||||||
|
set enable "cell format" for NBG0
|
||||||
|
set character size for NBG0 to 1x1 cell */
|
||||||
|
vdp2.reg.CHCTLA = CHCTLA__N0CHCN__2048_COLOR
|
||||||
|
| CHCTLA__N0BMEN__CELL_FORMAT
|
||||||
|
| CHCTLA__N0CHSZ__1x1_CELL;
|
||||||
|
/* "Note: In color RAM modes 0 and 2, 2048-color becomes 1024-color" */
|
||||||
|
|
||||||
|
/* use 1-word (16-bit) pattern names */
|
||||||
|
vdp2.reg.PNCN0 = PNCN0__N0PNB__1WORD;
|
||||||
|
|
||||||
|
/* plane size */
|
||||||
|
vdp2.reg.PLSZ = PLSZ__N0PLSZ__1x1;
|
||||||
|
|
||||||
|
/* map plane offset
|
||||||
|
1-word: value of bit 6-0 * 0x2000
|
||||||
|
2-word: value of bit 5-0 * 0x4000
|
||||||
|
*/
|
||||||
|
constexpr int plane_a = 2;
|
||||||
|
constexpr int plane_a_offset = plane_a * 0x2000;
|
||||||
|
|
||||||
|
constexpr int page_size = 64 * 64 * 2; // N0PNB__1WORD (16-bit)
|
||||||
|
constexpr int plane_size = page_size * 1;
|
||||||
|
|
||||||
|
vdp2.reg.MPOFN = MPOFN__N0MP(0); // bits 8~6
|
||||||
|
vdp2.reg.MPABN0 = MPABN0__N0MPB(plane_a) | MPABN0__N0MPA(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPCDN0 = MPCDN0__N0MPD(plane_a) | MPCDN0__N0MPC(plane_a); // bits 5~0
|
||||||
|
|
||||||
|
constexpr int cell_size = (8 * 8) * 2; // N0CHCN__2048_COLOR (16-bit)
|
||||||
|
constexpr int character_size = cell_size * (1 * 1); // N0CHSZ__1x1_CELL
|
||||||
|
constexpr int character_offset = character_size / 0x20;
|
||||||
|
|
||||||
|
// zeroize character/cell data from 0 up to plane_a_offset
|
||||||
|
fill<uint32_t>(&vdp2.vram.u32[(0 / 2)], 0, plane_a_offset);
|
||||||
|
|
||||||
|
// "zeroize" plane_a to the 0x40th (64th) character index (an unused/transparent character)
|
||||||
|
// this creates the '40' indexes in the below picture
|
||||||
|
fill<uint16_t>(&vdp2.vram.u16[(plane_a_offset / 2)], character_offset * 0x40, plane_size);
|
||||||
|
|
||||||
|
constexpr int pixel_width = 64;
|
||||||
|
constexpr int pixel_height = 64;
|
||||||
|
constexpr int cell_horizontal = pixel_width / 8;
|
||||||
|
constexpr int cell_vertical = pixel_height / 8;
|
||||||
|
|
||||||
|
constexpr int page_width = 64;
|
||||||
|
|
||||||
|
/*
|
||||||
|
set plane_a character index data to this (hex):
|
||||||
|
|
||||||
|
|
|
||||||
|
00 01 02 03 04 05 06 07 40 40 ..
|
||||||
|
08 09 0a 0b 0c 0d 0e 0f 40 40 ..
|
||||||
|
10 11 12 13 14 15 16 17 40 40 ..
|
||||||
|
18 19 1a 1b 1c 1d 1e 1f 40 40 ..
|
||||||
|
20 21 22 23 24 25 26 27 40 40 ..
|
||||||
|
28 29 2a 2b 2c 2d 2e 2f 40 40 ..
|
||||||
|
30 31 32 33 34 35 36 37 40 40 ..
|
||||||
|
-- 38 39 3a 3b 3c 3d 3e 3f 40 40 ..
|
||||||
|
40 40 40 40 40 40 40 40 40 40 ..
|
||||||
|
40 40 40 40 40 40 40 40 40 40 ..
|
||||||
|
.. .. .. .. .. .. .. .. .. .. ..
|
||||||
|
|
||||||
|
(the above numbers are not pre-multiplied by character_offset)
|
||||||
|
*/
|
||||||
|
|
||||||
|
vdp2.reg.BKTA = BKTA__BKCLMD_PER_LINE;
|
||||||
|
|
||||||
|
gen_gradient();
|
||||||
|
}
|
86
vdp2/nbg0_font.cpp
Normal file
86
vdp2/nbg0_font.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "vdp2.h"
|
||||||
|
#include "../common/vdp2_func.hpp"
|
||||||
|
|
||||||
|
#include "font/hp_100lx_4bit.data.h"
|
||||||
|
|
||||||
|
void cell_data()
|
||||||
|
{
|
||||||
|
const uint32_t * start = reinterpret_cast<uint32_t *>(&_binary_font_hp_100lx_4bit_data_start);
|
||||||
|
const int size = reinterpret_cast<uint32_t>(&_binary_font_hp_100lx_4bit_data_size);
|
||||||
|
|
||||||
|
for (int i = 0; i < (size / 4); i++) {
|
||||||
|
vdp2.vram.u32[i] = start[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void palette_data()
|
||||||
|
{
|
||||||
|
vdp2.cram.u16[0] = 0x0000;
|
||||||
|
vdp2.cram.u16[1] = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
v_blank_in();
|
||||||
|
|
||||||
|
// DISP: Please make sure to change this bit from 0 to 1 during V blank.
|
||||||
|
vdp2.reg.TVMD = ( TVMD__DISP | TVMD__LSMD__NON_INTERLACE
|
||||||
|
| TVMD__VRESO__240 | TVMD__HRESO__NORMAL_320);
|
||||||
|
|
||||||
|
/* set the color mode to 5bits per channel, 1024 colors */
|
||||||
|
vdp2.reg.RAMCTL = RAMCTL__CRMD__RGB_5BIT_1024
|
||||||
|
| RAMCTL__VRAMD | RAMCTL__VRBMD;
|
||||||
|
|
||||||
|
vdp2.reg.VRSIZE = 0;
|
||||||
|
|
||||||
|
/* enable display of NBG0 */
|
||||||
|
vdp2.reg.BGON = BGON__N0ON | BGON__N0TPON;
|
||||||
|
|
||||||
|
/* set character format for NBG0 to palettized 16 color
|
||||||
|
set enable "cell format" for NBG0
|
||||||
|
set character size for NBG0 to 1x1 cell */
|
||||||
|
vdp2.reg.CHCTLA = CHCTLA__N0CHCN__16_COLOR
|
||||||
|
| CHCTLA__N0BMEN__CELL_FORMAT
|
||||||
|
| CHCTLA__N0CHSZ__1x1_CELL;
|
||||||
|
|
||||||
|
/* plane size */
|
||||||
|
vdp2.reg.PLSZ = PLSZ__N0PLSZ__1x1;
|
||||||
|
|
||||||
|
/* map plane offset
|
||||||
|
1-word: value of bit 6-0 * 0x2000
|
||||||
|
2-word: value of bit 5-0 * 0x4000
|
||||||
|
*/
|
||||||
|
constexpr int plane_a = 1;
|
||||||
|
constexpr int plane_a_offset = plane_a * 0x4000;
|
||||||
|
|
||||||
|
constexpr int page_size = 64 * 64 * 2; // N0PNB__1WORD (16-bit)
|
||||||
|
constexpr int plane_size = page_size * 1;
|
||||||
|
|
||||||
|
vdp2.reg.CYCA0 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCA1 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCB0 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCB1 = 0x0F44F99F;
|
||||||
|
|
||||||
|
vdp2.reg.MPOFN = MPOFN__N0MP(0); // bits 8~6
|
||||||
|
vdp2.reg.MPABN0 = MPABN0__N0MPB(plane_a) | MPABN0__N0MPA(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPCDN0 = MPCDN0__N0MPD(plane_a) | MPCDN0__N0MPC(plane_a); // bits 5~0
|
||||||
|
|
||||||
|
palette_data();
|
||||||
|
cell_data();
|
||||||
|
|
||||||
|
vdp2.reg.PNCN0 = PNCN0__N0PNB__2WORD;
|
||||||
|
for (int i = 0; i < 64 * 64; i++) {
|
||||||
|
vdp2.vram.u32[(plane_a_offset / 4) + i] = ' ' - 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * test = "conversion from 8";
|
||||||
|
int ix = 0;
|
||||||
|
while (*test) {
|
||||||
|
uint8_t c = *test++;
|
||||||
|
vdp2.vram.u32[(plane_a_offset / 4) + ix++] = c - 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
139
vdp2/rbg0_font.cpp
Normal file
139
vdp2/rbg0_font.cpp
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "vdp2.h"
|
||||||
|
#include "../common/vdp2_func.hpp"
|
||||||
|
|
||||||
|
#include "font/hp_100lx_4bit.data.h"
|
||||||
|
|
||||||
|
void cell_data()
|
||||||
|
{
|
||||||
|
const uint32_t * start = reinterpret_cast<uint32_t *>(&_binary_font_hp_100lx_4bit_data_start);
|
||||||
|
const int size = reinterpret_cast<uint32_t>(&_binary_font_hp_100lx_4bit_data_size);
|
||||||
|
|
||||||
|
// the start of VRAM-A0
|
||||||
|
for (int i = 0; i < (size / 4); i++) {
|
||||||
|
vdp2.vram.u32[i] = start[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void palette_data()
|
||||||
|
{
|
||||||
|
vdp2.cram.u16[0] = 0x0000;
|
||||||
|
vdp2.cram.u16[1] = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
v_blank_in();
|
||||||
|
|
||||||
|
// DISP: Please make sure to change this bit from 0 to 1 during V blank.
|
||||||
|
vdp2.reg.TVMD = ( TVMD__DISP | TVMD__LSMD__NON_INTERLACE
|
||||||
|
| TVMD__VRESO__240 | TVMD__HRESO__NORMAL_320);
|
||||||
|
|
||||||
|
/* set the color mode to 5bits per channel, 1024 colors */
|
||||||
|
vdp2.reg.RAMCTL = RAMCTL__CRMD__RGB_5BIT_1024
|
||||||
|
| RAMCTL__VRAMD
|
||||||
|
| RAMCTL__VRBMD
|
||||||
|
| RAMCTL__RDBSA0__CHARACTER_PATTERN_TABLE // VRAM-A0 0x000000
|
||||||
|
| RAMCTL__RDBSA1__PATTERN_NAME_TABLE; // VRAM-A1 0x020000
|
||||||
|
|
||||||
|
vdp2.reg.VRSIZE = 0;
|
||||||
|
|
||||||
|
/* enable display of NBG0 */
|
||||||
|
vdp2.reg.BGON = BGON__R0ON | BGON__R0TPON;
|
||||||
|
|
||||||
|
/* set character format for NBG0 to palettized 16 color
|
||||||
|
set enable "cell format" for NBG0
|
||||||
|
set character size for NBG0 to 1x1 cell */
|
||||||
|
vdp2.reg.CHCTLB = CHCTLB__R0CHCN__16_COLOR
|
||||||
|
| CHCTLB__R0BMEN__CELL_FORMAT
|
||||||
|
| CHCTLB__R0CHSZ__1x1_CELL;
|
||||||
|
|
||||||
|
/* plane size */
|
||||||
|
vdp2.reg.PLSZ = PLSZ__RAPLSZ__1x1
|
||||||
|
| PLSZ__RBPLSZ__1x1;
|
||||||
|
|
||||||
|
/* map plane offset
|
||||||
|
1-word: value of bit 6-0 * 0x2000
|
||||||
|
2-word: value of bit 5-0 * 0x4000
|
||||||
|
*/
|
||||||
|
// plane_a_offset is at the start of VRAM-A1
|
||||||
|
constexpr int plane_a = 8;
|
||||||
|
constexpr int plane_a_offset = plane_a * 0x4000;
|
||||||
|
|
||||||
|
constexpr int page_size = 64 * 64 * 2; // N0PNB__1WORD (16-bit)
|
||||||
|
constexpr int plane_size = page_size * 1;
|
||||||
|
|
||||||
|
/* cycle pattern table not used for RBG0 ? */
|
||||||
|
vdp2.reg.CYCA0 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCA1 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCB0 = 0x0F44F99F;
|
||||||
|
vdp2.reg.CYCB1 = 0x0F44F99F;
|
||||||
|
|
||||||
|
vdp2.reg.MPOFR = MPOFR__RAMP(0); // bits 8~6
|
||||||
|
vdp2.reg.MPABRA = MPABRA__RAMPB(plane_a) | MPABRA__RAMPA(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPCDRA = MPCDRA__RAMPD(plane_a) | MPCDRA__RAMPC(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPEFRA = MPEFRA__RAMPF(plane_a) | MPEFRA__RAMPE(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPGHRA = MPGHRA__RAMPH(plane_a) | MPGHRA__RAMPG(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPIJRA = MPIJRA__RAMPJ(plane_a) | MPIJRA__RAMPI(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPKLRA = MPKLRA__RAMPL(plane_a) | MPKLRA__RAMPK(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPMNRA = MPMNRA__RAMPN(plane_a) | MPMNRA__RAMPM(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPOPRA = MPOPRA__RAMPP(plane_a) | MPOPRA__RAMPO(plane_a); // bits 5~0
|
||||||
|
|
||||||
|
vdp2.reg.PNCR = PNCR__R0PNB__2WORD;
|
||||||
|
|
||||||
|
vdp2.reg.RPMD = RPMD__ROTATION_PARAMETER_A;
|
||||||
|
|
||||||
|
//vdp2.reg.RPRCTL = 0;
|
||||||
|
|
||||||
|
vdp2.reg.KTCTL = 0;
|
||||||
|
|
||||||
|
vdp2.reg.KTAOF = 0;
|
||||||
|
|
||||||
|
vdp2.reg.PRIR = 3;
|
||||||
|
|
||||||
|
palette_data();
|
||||||
|
cell_data();
|
||||||
|
|
||||||
|
volatile struct vdp2_rotation_parameter_table * table = (struct vdp2_rotation_parameter_table *)&vdp2.vram.u32[0x4000 / 4];
|
||||||
|
table->screen_start_coordinate_xst = 0;
|
||||||
|
table->screen_start_coordinate_yst = 0;
|
||||||
|
table->screen_start_coordinate_zst = 0;
|
||||||
|
table->screen_vertical_coordinate_increment_dxst = 0;
|
||||||
|
table->screen_vertical_coordinate_increment_dyst = (1 << 16);
|
||||||
|
table->screen_horizontal_coordinate_increment_dx = (1 << 16);
|
||||||
|
table->screen_horizontal_coordinate_increment_dy = 0;
|
||||||
|
table->rotation_matrix_parameter_a = (-1 << 16);
|
||||||
|
table->rotation_matrix_parameter_b = 0;
|
||||||
|
table->rotation_matrix_parameter_c = 0;
|
||||||
|
table->rotation_matrix_parameter_d = 0;
|
||||||
|
table->rotation_matrix_parameter_e = (1 << 16);
|
||||||
|
table->rotation_matrix_parameter_f = 0;
|
||||||
|
table->viewpoint_coordinate_px = 0;
|
||||||
|
table->viewpoint_coordinate_py = 0;
|
||||||
|
table->viewpoint_coordinate_pz = 0;
|
||||||
|
table->center_point_coordinate_px = 0;
|
||||||
|
table->center_point_coordinate_py = 0;
|
||||||
|
table->center_point_coordinate_pz = 0;
|
||||||
|
table->horizontal_shift_mx = 0;
|
||||||
|
table->horizontal_shift_my = 0;
|
||||||
|
table->scaling_coefficient_kx = (1 << 16);
|
||||||
|
table->scaling_coefficient_ky = (1 << 16);
|
||||||
|
|
||||||
|
vdp2.reg.RPTA = (((uint32_t)table) >> 1) & 0x7ffff;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
for (int i = 0; i < 64 * 64; i++) {
|
||||||
|
vdp2.vram.u32[(plane_a_offset / 4) + i] = ' ' - 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * test = "If sound level changes progressively, volume on 3 bit makes audi";
|
||||||
|
int ix = 0;
|
||||||
|
while (*test) {
|
||||||
|
uint8_t c = *test++;
|
||||||
|
vdp2.vram.u32[(plane_a_offset / 4) + ix++] = c - 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
170
vec4.hpp
Normal file
170
vec4.hpp
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "math.hpp"
|
||||||
|
#include "vec.hpp"
|
||||||
|
|
||||||
|
//
|
||||||
|
// vec4
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct vec<4, T>
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct { T x, y, z, w; };
|
||||||
|
struct { T a, r, g, b; };
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr vec();
|
||||||
|
inline constexpr vec(T scalar);
|
||||||
|
inline constexpr vec(T _x, T _y, T _z, T _w);
|
||||||
|
inline constexpr vec(const vec<3, T>& v);
|
||||||
|
|
||||||
|
constexpr inline vec<4, T> operator-() const;
|
||||||
|
inline constexpr T const& operator[](int i) const;
|
||||||
|
inline constexpr vec<4, T>& operator=(vec<4, T> const& v);
|
||||||
|
inline constexpr vec<4, T>& operator+=(vec<4, T> const& v);
|
||||||
|
inline constexpr vec<4, T>& operator-=(vec<4, T> const& v);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T>::vec()
|
||||||
|
: x(0), y(0), z(0), w(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T>::vec(T scalar)
|
||||||
|
: x(scalar), y(scalar), z(scalar), w(scalar)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T>::vec(T _x, T _y, T _z, T _w)
|
||||||
|
: x(_x), y(_y), z(_z), w(_w)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T>::vec(const vec<3, T>& v)
|
||||||
|
: x(v.x), y(v.y), z(v.z), w(1.f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr inline vec<4, T> vec<4, T>::operator-() const
|
||||||
|
{
|
||||||
|
return vec<4, T>(-x, -y, -z, -w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T const& vec<4, T>::operator[](int i) const
|
||||||
|
{
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
default: [[fallthrough]];
|
||||||
|
case 0: return x;
|
||||||
|
case 1: return y;
|
||||||
|
case 2: return z;
|
||||||
|
case 3: return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T>& vec<4, T>::operator=(vec<4, T> const& v)
|
||||||
|
{
|
||||||
|
this->x = static_cast<T>(v.x);
|
||||||
|
this->y = static_cast<T>(v.y);
|
||||||
|
this->z = static_cast<T>(v.z);
|
||||||
|
this->w = static_cast<T>(v.w);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T>& vec<4, T>::operator+=(vec<4, T> const& v)
|
||||||
|
{
|
||||||
|
*this = *this + vec<4, T>(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T>& vec<4, T>::operator-=(vec<4, T> const& v)
|
||||||
|
{
|
||||||
|
*this = *this - vec<4, T>(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> operator+(vec<4, T> const& v1, vec<4, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<4, T>(v1.x + v2.x,
|
||||||
|
v1.y + v2.y,
|
||||||
|
v1.z + v2.z,
|
||||||
|
v1.w + v2.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> operator-(vec<4, T> const& v1, vec<4, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<4, T>(v1.x - v2.x,
|
||||||
|
v1.y - v2.y,
|
||||||
|
v1.z - v2.z,
|
||||||
|
v1.w - v2.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> operator*(vec<4, T> const& v1, vec<4, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<4, T>(v1.x * v2.x,
|
||||||
|
v1.y * v2.y,
|
||||||
|
v1.z * v2.z,
|
||||||
|
v1.w * v2.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> operator*(vec<4, T> const& v1, T const& scalar)
|
||||||
|
{
|
||||||
|
return v1 * vec<4, T>(scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> operator*(T const& scalar, vec<4, T> const& v1)
|
||||||
|
{
|
||||||
|
return vec<4, T>(scalar) * v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> operator/(vec<4, T> const& v1, vec<4, T> const& v2)
|
||||||
|
{
|
||||||
|
return vec<4, T>(v1.x / v2.x,
|
||||||
|
v1.y / v2.y,
|
||||||
|
v1.z / v2.z,
|
||||||
|
v1.w / v2.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> operator/(vec<4, T> const& v1, T const& scalar)
|
||||||
|
{
|
||||||
|
return v1 / vec<4, T>(scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T dot(vec<4, T> const& v1, vec<4, T> const& v2)
|
||||||
|
{
|
||||||
|
vec<4, T> tmp(v1 * v2);
|
||||||
|
return tmp.x + tmp.y + tmp.z + tmp.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr vec<4, T> functor1(T (&func) (T const& x), vec<4, T> const& v)
|
||||||
|
{
|
||||||
|
return vec<4, T>(func(v.x), func(v.y), func(v.z), func(v.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline constexpr vec<4, U> functor1(U (&func) (T const& x), vec<4, T> const& v)
|
||||||
|
{
|
||||||
|
return vec<4, U>(func(v.x), func(v.y), func(v.z), func(v.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T magnitude(vec<4, T> const& v)
|
||||||
|
{
|
||||||
|
return sqrt(dot(v, v));
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user