saturn-examples/raytracing/main-saturn.cpp
Zack Buhman 511bfd1d0c remove duplicate start functions
This is now provided by default in saturn/common.mk.

Also updates moved header names, changed bit macro names, and changes
to the common.mk build process.
2023-07-30 18:03:19 +00:00

135 lines
2.8 KiB
C++

#include "vdp2.h"
#include "vdp1.h"
#include "scu.h"
#include "smpc.h"
#include "sh2.h"
#include "vec3.hpp"
#include "fp.hpp"
#include "raytracing.hpp"
constexpr inline
fp16_16 clamp(fp16_16 const& n)
{
return (n > fp16_16(1) ? fp16_16(1) : (n < fp16_16(0) ? fp16_16(0) : n));
};
template<typename T, int P>
inline constexpr T rgb(const vec3& color)
{
constexpr int channel_mask = (1 << P) - 1;
constexpr int last_bit = ((sizeof(T) * 8) - 1);
vec3 c = functor1(clamp, color) * fp16_16(channel_mask);
T red = static_cast<T>(c.x.value >> 16);
T green = static_cast<T>(c.y.value >> 16);
T blue = static_cast<T>(c.z.value >> 16);
return (1 << last_bit)
| (blue << (P * 2))
| (green << (P * 1))
| (red << (P * 0));
}
constexpr auto rgb15 = rgb<uint16_t, 5>;
constexpr auto rgb24 = rgb<uint32_t, 8>;
void put_pixel(int32_t x, int32_t y, const vec3& color)
{
int sx = 320 / 2 + x;
int sy = 240 / 2 - y;
if (sx >= 320 || sx < 0 || sy >= 240 || sy < 0)
return;
vdp2.vram.u16[512 * sy + sx] = rgb15(color);
}
template <class T>
void fill(T * buf, T v, int32_t n) noexcept
{
while (n > 0) {
*buf++ = v;
n -= (sizeof (T));
}
}
extern "C"
void slave_main(void)
{
render(1, put_pixel);
while (1) {}
}
void start_slave()
{
/*
Items Common to Command Issue Timing
As mentioned above, issuing commands for 300 µs from V-BLANK-IN is
prohibited.
*/
while ((smpc.reg.SF & 0x01) == 1);
smpc.reg.SF = 1;
smpc.reg.COMREG = COMREG__SSHOFF;
while ((smpc.reg.SF & 0x01) == 1);
/*
volatile void (*foo)(uint32_t, void*);
foo = *(volatile void (**)(uint32_t, void*))0x6000310;
foo(0x94, (void*)&slave_main);
*/
sh2_vec[0x94] = (uint32_t)(&slave_main);
for (int i = 0; i < 10; i++)
asm volatile ("nop");
smpc.reg.SF = 1;
smpc.reg.COMREG = COMREG__SSHON;
while ((smpc.reg.SF & 0x01) == 1);
}
void main()
{
// 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);
vdp2.reg.BGON = BGON__N0ON;
vdp2.reg.CHCTLA = (
CHCTLA__N0CHCN__32K_COLOR // 15 bits per pixel, RGB
// CHCTLA__N0CHCN__16M_COLOR // 24 bits per pixel
| CHCTLA__N0BMSZ__512x256_DOT
| CHCTLA__N0BMEN__BITMAP_FORMAT
);
vdp2.reg.MPOFN = MPOFN__N0MP(0);
constexpr s32 plane_size = 512 * 256 * 4;
fill<volatile uint32_t>(&vdp2.vram.u32[0x0 / 4], (1 << 31), plane_size);
vdp2.reg.SCXIN0 = 0;
vdp2.reg.SCXDN0 = 0;
vdp2.reg.SCYIN0 = 0;
vdp2.reg.SCYDN0 = 0;
vdp2.reg.ZMXIN0 = 1;
vdp2.reg.ZMXDN0 = 0;
vdp2.reg.ZMYIN0 = 1;
vdp2.reg.ZMYDN0 = 0;
vdp2.reg.VCSTA = 0;
vdp2.reg.WCTLA = 0;
vdp2.reg.WCTLB = 0;
vdp2.reg.WCTLC = 0;
start_slave();
render(0, put_pixel);
}