vdp2/nbg0_16color: new example
This commit is contained in:
parent
db3729992e
commit
646a7af953
2
Makefile
2
Makefile
@ -42,6 +42,8 @@ raytracing/raytracing.elf: raytracing/main-saturn.o raytracing/raytracing.o sh/l
|
|||||||
|
|
||||||
vdp2/nbg0.elf: vdp2/nbg0.o res/butterfly.data.o res/butterfly.data.pal.o
|
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
|
||||||
|
|
||||||
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/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
|
||||||
|
@ -22,15 +22,15 @@ using vec3 = vec<3, fp16_16>;
|
|||||||
using mat4x4 = mat<4, 4, fp16_16>;
|
using mat4x4 = mat<4, 4, fp16_16>;
|
||||||
|
|
||||||
static vec4 vertices[8] = {
|
static vec4 vertices[8] = {
|
||||||
{-0.5, -0.5, 0.5, 1.0}, // top left front
|
{-1.0, -1.0, 1.0, 1.0}, // top left front
|
||||||
{ 0.5, -0.5, 0.5, 1.0}, // top right front
|
{ 1.0, -1.0, 1.0, 1.0}, // top right front
|
||||||
{ 0.5, 0.5, 0.5, 1.0}, // bottom right front
|
{ 1.0, 1.0, 1.0, 1.0}, // bottom right front
|
||||||
{-0.5, 0.5, 0.5, 1.0}, // bottom left front
|
{-1.0, 1.0, 1.0, 1.0}, // bottom left front
|
||||||
|
|
||||||
{-0.5, -0.5, -0.5, 1.0}, // top left back
|
{-1.0, -1.0, -1.0, 1.0}, // top left back
|
||||||
{ 0.5, -0.5, -0.5, 1.0}, // top right back
|
{ 1.0, -1.0, -1.0, 1.0}, // top right back
|
||||||
{ 0.5, 0.5, -0.5, 1.0}, // bottom right back
|
{ 1.0, 1.0, -1.0, 1.0}, // bottom right back
|
||||||
{-0.5, 0.5, -0.5, 1.0}, // bottom left back
|
{-1.0, 1.0, -1.0, 1.0}, // bottom left back
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t faces[6][4] = {
|
static uint32_t faces[6][4] = {
|
||||||
@ -47,21 +47,18 @@ struct canvas {
|
|||||||
fp16_16 height;
|
fp16_16 height;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr struct canvas canvas = { 240, 240 };
|
constexpr struct canvas canvas = { 320, 240 };
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
vec<3, T> viewport_to_canvas(T x, T y)
|
vec<3, T> viewport_to_canvas(T x, T y)
|
||||||
{
|
{
|
||||||
return vec<3, T>(x * canvas.width, y * canvas.height, T(1));
|
return vec<3, T>((canvas.width>>1) + x * canvas.height, (canvas.height>>1) - y * canvas.height - T(1), T(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr vec<3, T> project_vertex(vec<4, T> const& v)
|
inline constexpr vec<3, T> project_vertex(vec<4, T> const& v)
|
||||||
{
|
{
|
||||||
// / (v.z - T(5))
|
return viewport_to_canvas<T>((v.x / v.z), (v.y / v.z));
|
||||||
// / (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)
|
constexpr inline uint16_t rgb15(int32_t r, int32_t g, int32_t b)
|
||||||
@ -102,29 +99,35 @@ render()
|
|||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mat4x4 transform = rotationX * rotationY;
|
//const mat4x4 transform = rotationX * rotationY;
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) {
|
vec4 transforms[2] = {
|
||||||
|
{-1.5, 0.0, 7.0, 0.0},
|
||||||
|
{1.25, 2, 7.5, 0.0}
|
||||||
|
};
|
||||||
|
|
||||||
const uint32_t * face = faces[i];
|
for (vec4& t : transforms) {
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
|
||||||
vdp1.vram.cmd[ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__POLYLINE;
|
const uint32_t * face = faces[i];
|
||||||
vdp1.vram.cmd[ix].LINK = 0;
|
|
||||||
vdp1.vram.cmd[ix].PMOD = PMOD__ECD | PMOD__SPD;
|
|
||||||
vdp1.vram.cmd[ix].COLR = COLR__RGB | colors[i];
|
|
||||||
|
|
||||||
for (int p = 0; p < 4; p++) {
|
vdp1.vram.cmd[ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__POLYLINE;
|
||||||
const vec4& v0 = vertices[face[p]];
|
vdp1.vram.cmd[ix].LINK = 0;
|
||||||
|
vdp1.vram.cmd[ix].PMOD = PMOD__ECD | PMOD__SPD;
|
||||||
|
vdp1.vram.cmd[ix].COLR = COLR__RGB | colors[i];
|
||||||
|
|
||||||
const vec4 v1 = transform * v0;
|
for (int p = 0; p < 4; p++) {
|
||||||
|
const vec4& v0 = vertices[face[p]];
|
||||||
|
|
||||||
const vec3& v2 = project_vertex(v1);
|
const vec4& v1 = v0 + t;
|
||||||
|
|
||||||
vdp1.vram.cmd[ix].point[p].X = static_cast<int>(v2.x);
|
const vec3& v2 = project_vertex(v1);
|
||||||
vdp1.vram.cmd[ix].point[p].Y = static_cast<int>(v2.y);
|
|
||||||
|
vdp1.vram.cmd[ix].point[p].X = static_cast<int>(v2.x);
|
||||||
|
vdp1.vram.cmd[ix].point[p].Y = static_cast<int>(v2.y);
|
||||||
|
}
|
||||||
|
ix++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ix++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vdp1.vram.cmd[ix].CTRL = CTRL__END;
|
vdp1.vram.cmd[ix].CTRL = CTRL__END;
|
||||||
|
135
vdp2/nbg0_16color.cpp
Normal file
135
vdp2/nbg0_16color.cpp
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "vdp2.h"
|
||||||
|
#include "../common/vdp2_func.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
extern void * _kirby_data_pal_start __asm("_binary_res_kirby_data_pal_start");
|
||||||
|
extern void * _kirby_data_pal_size __asm("_binary_res_kirby_data_pal_size");
|
||||||
|
|
||||||
|
extern void * _kirby_data_start __asm("_binary_res_kirby_data_start");
|
||||||
|
extern void * _kirby_data_size __asm("_binary_res_kirby_data_size");
|
||||||
|
|
||||||
|
inline constexpr uint16_t rgb15(const uint8_t * buf)
|
||||||
|
{
|
||||||
|
return ((buf[2] >> 3) << 10) // blue
|
||||||
|
| ((buf[1] >> 3) << 5) // green
|
||||||
|
| ((buf[0] >> 3) << 0); // red
|
||||||
|
}
|
||||||
|
|
||||||
|
void palette_data()
|
||||||
|
{
|
||||||
|
const uint32_t buf_size = reinterpret_cast<uint32_t>(&_kirby_data_pal_size);
|
||||||
|
const uint8_t * buf = reinterpret_cast<uint8_t*>(&_kirby_data_pal_start);
|
||||||
|
uint32_t buf_ix = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < (buf_size / 3); i++) {
|
||||||
|
vdp2.cram.u16[i] = rgb15(&buf[buf_ix]);
|
||||||
|
buf_ix += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t cell_data(const uint32_t top)
|
||||||
|
{
|
||||||
|
const uint32_t buf_size = reinterpret_cast<uint32_t>(&_kirby_data_size);
|
||||||
|
const uint8_t * buf = reinterpret_cast<uint8_t*>(&_kirby_data_start);
|
||||||
|
|
||||||
|
// round to nearest multiple of 32
|
||||||
|
const uint32_t table_size = ((buf_size / 2) + 0x20 - 1) & (-0x20);
|
||||||
|
const uint32_t base_address = top - table_size; // in bytes
|
||||||
|
|
||||||
|
// px is a conversion from 8 bits per index to 4 bits per index
|
||||||
|
// the value is shifted to its position in a 32-bit big-endian value
|
||||||
|
#define px(x) (buf[i * 8 + ((x) & 0xf)] << ((7 - ((x) & 0xf)) * 4))
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < (buf_size / 8); i++) {
|
||||||
|
// write an entire row all at once
|
||||||
|
vdp2.vram.u32[(base_address / 4) + i] =
|
||||||
|
//vdp2.vram.u32[i] =
|
||||||
|
px(0) | px(1) | px(2) | px(3) | px(4) | px(5) | px(6) | px(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef px
|
||||||
|
|
||||||
|
return base_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void fill(T * buf, T v, int32_t n) noexcept
|
||||||
|
{
|
||||||
|
while (n > 0) {
|
||||||
|
*buf++ = v;
|
||||||
|
n -= (sizeof (T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
/* "Note: In color RAM modes 0 and 2, 2048-color becomes 1024-color" */
|
||||||
|
|
||||||
|
/* 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 = 0;
|
||||||
|
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.CYCB0 = 0x0F44F99F;
|
||||||
|
|
||||||
|
vdp2.reg.MPOFN = MPOFN__N0MP(0); // bits 8~6
|
||||||
|
vdp2.reg.MPABN0 = MPABN0__N0MPB(0) | MPABN0__N0MPA(plane_a); // bits 5~0
|
||||||
|
vdp2.reg.MPCDN0 = MPABN0__N0MPD(0) | MPABN0__N0MPC(0); // bits 5~0
|
||||||
|
|
||||||
|
// zeroize character/cell data from 0 up to plane_a_offset
|
||||||
|
fill<uint32_t>(&vdp2.vram.u32[(0 / 4)], 0, plane_a_offset);
|
||||||
|
|
||||||
|
uint32_t top = (sizeof (union vdp2_vram));
|
||||||
|
palette_data();
|
||||||
|
uint32_t kirby_address = top = cell_data(top);
|
||||||
|
uint32_t pattern_name = kirby_address / 32;
|
||||||
|
|
||||||
|
/* use 1-word (16-bit) pattern names */
|
||||||
|
//vdp2.reg.PNCN0 = PNCN0__N0PNB__1WORD | PNCN0__N0CNSM | PNCN0__N0SCN((pattern_name >> 10) & 0x1f);
|
||||||
|
//fill<uint16_t>(&vdp2.vram.u16[(plane_a_offset / 4)], pattern_name & 0xfff, plane_size);
|
||||||
|
|
||||||
|
/* use 2-word (32-bit) pattern names */
|
||||||
|
vdp2.reg.PNCN0 = PNCN0__N0PNB__2WORD;
|
||||||
|
fill<uint32_t>(&vdp2.vram.u32[(plane_a_offset / 2)], pattern_name, plane_size);
|
||||||
|
|
||||||
|
// both 1-word and 2-word have identical behavior; 2-word is enabled to reduce/focus suspicion.
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void start(void)
|
||||||
|
{
|
||||||
|
main();
|
||||||
|
while (1) {}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user