Skip to content

Commit 7e8100f

Browse files
committed
Final version with assets.
1 parent 85880d6 commit 7e8100f

File tree

13 files changed

+556
-54
lines changed

13 files changed

+556
-54
lines changed

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
PSX.Dev-README.md
21
*.elf
32
*.map
43
*.cpe
54
*.ps-exe
65
*.dep
76
*.o
8-
*.a
7+
*.a
8+
*.bin
9+
comport.txt

Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@ all: demo.ps-exe
33
core:
44
$(MAKE) -C core
55

6-
loader:
6+
loader: core music
77
$(MAKE) -C loader
88

9+
music:
10+
$(MAKE) -C music
11+
912
clean:
1013
$(MAKE) -C core clean
1114
rm -f demo.ps-exe
15+
$(MAKE) -C loader clean
16+
$(MAKE) -C music clean
1217

1318
demo.ps-exe: core loader
1419
cp loader/loader.ps-exe demo.ps-exe
1520
# ps1-packer loader/loader.ps-exe -o demo.ps-exe
1621

17-
.PHONY: clean core loader
22+
.PHONY: clean core loader music

core/LittleCottonPillow-v260.hit

53.1 KB
Binary file not shown.

core/Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@ TYPE = ps-exe
55

66
SRCS = \
77
torus.cpp \
8+
LittleCottonPillow-v260.hit \
9+
../third_party/nugget/modplayer/modplayer.c \
810

911
CXXFLAGS = -std=c++20
1012

1113
LDFLAGS += -Wl,-wrap,memcpy -Wl,-wrap,memset
14+
LDFLAGS += -Xlinker --defsym=TLOAD_ADDR=0x80001000
1215

1316
include ../third_party/nugget/psyqo/psyqo.mk
1417

1518
core.bin: $(TARGET).ps-exe
16-
../ps1-packer $< -raw -o $@
19+
../ps1-packer $< -raw -nokernel -resetstack -o $@
1720

1821
core.o: core.bin
1922
$(PREFIX)-objcopy -I binary --set-section-alignment .data=4 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@
23+
24+
%.o: %.hit
25+
$(PREFIX)-objcopy -I binary --set-section-alignment .data=4 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@

core/torus.cpp

Lines changed: 83 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ SOFTWARE.
3131

3232
#include "EASTL/internal/function.h"
3333
#include "common/syscalls/syscalls.h"
34+
#include "psyqo/fragment-concept.hh"
35+
extern "C" {
36+
#include "modplayer/modplayer.h"
37+
}
38+
#include "psyqo/advancedpad.hh"
3439
#include "psyqo/application.hh"
3540
#include "psyqo/fixed-point.hh"
3641
#include "psyqo/font.hh"
@@ -47,7 +52,6 @@ SOFTWARE.
4752
#include "psyqo/primitives/rectangles.hh"
4853
#include "psyqo/primitives/sprites.hh"
4954
#include "psyqo/scene.hh"
50-
#include "psyqo/simplepad.hh"
5155
#include "psyqo/soft-math.hh"
5256
#include "psyqo/trigonometry.hh"
5357
#include "psyqo/vector.hh"
@@ -56,6 +60,8 @@ using namespace psyqo::fixed_point_literals;
5660
using namespace psyqo::timer_literals;
5761
using namespace psyqo::trig_literals;
5862

63+
extern const struct MODFileFormat _binary_LittleCottonPillow_v260_hit_start;
64+
5965
namespace {
6066

6167
// We're going to use the scratchpad to store the color lookup tables.
@@ -66,11 +72,11 @@ constexpr psyqo::Color c_backgroundColor{{.r = 0x34, .g = 0x58, .b = 0x6c}};
6672
// This is for debugging purposes only.
6773
template <typename T>
6874
void printVec(const T& v) {
69-
ramsyscall_printf("x: ");
75+
syscall_puts("x: ");
7076
v.x.print([](char c) { syscall_putchar(c); });
71-
ramsyscall_printf(", y: ");
77+
syscall_puts(", y: ");
7278
v.y.print([](char c) { syscall_putchar(c); });
73-
ramsyscall_printf(", z: ");
79+
syscall_puts(", z: ");
7480
v.z.print([](char c) { syscall_putchar(c); });
7581
syscall_putchar('\n');
7682
}
@@ -82,7 +88,8 @@ class TorusDemo final : public psyqo::Application {
8288
public:
8389
psyqo::Font<2> m_font;
8490
psyqo::Trig<> m_trig;
85-
psyqo::SimplePad m_input;
91+
psyqo::AdvancedPad m_input;
92+
unsigned m_musicTimer;
8693
};
8794

8895
TorusDemo torusDemo;
@@ -146,10 +153,10 @@ struct TorusTemplate {
146153
psyqo::GTE::write<psyqo::GTE::Register::IR3, psyqo::GTE::Safe>(reinterpret_cast<uint32_t*>(&t.z.value));
147154
psyqo::GTE::Kernels::cp();
148155
// The result is stored in the LV register, so first we simply read it.
149-
psyqo::GTE::read<psyqo::GTE::PseudoRegister::LV>(&cp);
156+
psyqo::GTE::read<psyqo::GTE::PseudoRegister::LV>(cp);
150157
// Then we square LV to get the square of the length of the normal.
151158
psyqo::GTE::Kernels::sqr();
152-
psyqo::GTE::read<psyqo::GTE::PseudoRegister::LV>(&sq);
159+
psyqo::GTE::read<psyqo::GTE::PseudoRegister::LV>(sq);
153160
// We still need to add the three components of the square.
154161
auto square = sq.x + sq.y + sq.z;
155162
// Finally, we compute the square root of the square of the length of the normal.
@@ -323,12 +330,12 @@ class TorusScene final : public psyqo::Scene {
323330
// The generator finished, our scene starts. We set the proper context.
324331
m_lastFrameCounter = gpu().getFrameCount();
325332
m_sequenceStartTime = gpu().now();
326-
torusDemo.m_input.setOnEvent([this](const psyqo::SimplePad::Event& event) {
327-
if (event.type != psyqo::SimplePad::Event::ButtonReleased) return;
328-
if (event.button == psyqo::SimplePad::Button::Triangle) {
333+
torusDemo.m_input.setOnEvent([this](const psyqo::AdvancedPad::Event& event) {
334+
if (event.type != psyqo::AdvancedPad::Event::ButtonReleased) return;
335+
if (event.button == psyqo::AdvancedPad::Button::Triangle) {
329336
m_lutIndex = (m_lutIndex + 1) % 3;
330337
}
331-
if (event.button == psyqo::SimplePad::Button::Cross) {
338+
if (event.button == psyqo::AdvancedPad::Button::Cross) {
332339
m_lutInverted = !m_lutInverted;
333340
}
334341
const psyqo::Color* lut = nullptr;
@@ -448,12 +455,12 @@ class TorusScene final : public psyqo::Scene {
448455
constexpr psyqo::Angle rippleIncrement = 1.0_pi / Count;
449456
psyqo::Angle ripple = rippleIncrement * torusIndex;
450457
auto& torus = m_tori[torusIndex];
451-
ramsyscall_printf("Generating torus %u\n", torusIndex);
458+
// ramsyscall_printf("Generating torus %u\n", torusIndex);
452459

453460
auto amplitude = torusDemo.m_trig.sin(ripple) * 0.6_fp;
454461
unsigned index = 0;
455462
for (psyqo::Angle outside = 0; outside < 2.0_pi; outside += incrementOutside) {
456-
auto rot = psyqo::SoftMath::generateRotationMatrix33(outside, psyqo::SoftMath::Axis::Z, &torusDemo.m_trig);
463+
auto rot = psyqo::SoftMath::generateRotationMatrix33(outside, psyqo::SoftMath::Axis::Z, torusDemo.m_trig);
457464
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::Rotation>(rot);
458465
psyqo::FixedPoint<> rippleAmplitude = amplitude * torusDemo.m_trig.sin(outside * 5 + ripple * 8) + 1.5_fp;
459466
for (psyqo::Angle inside = 0; inside < 2.0_pi; inside += incrementInside) {
@@ -548,12 +555,20 @@ TorusScene::SequenceItem TorusScene::sequence[] = {
548555
{3.0_s, ""},
549556
{2.0_s, "Yep."},
550557
{2.0_s, "Yep. That's projected shadows."},
551-
{2.0_s, ""},
558+
{5.0_s, ""},
552559
{3.0_s, "By the way..."},
553560
{2.0_s, "... it's interactive..."},
554561
{2.0_s, ""},
555562
{2.0_s, "Try pressing buttons."},
556563
{4.0_s, ""},
564+
{0.5_s, "Credits."},
565+
{0.5_s, "Credits.."},
566+
{4.0_s, "Credits..."},
567+
{4.0_s, "Torus Code & Design: Pixel"},
568+
{4.0_s, "Music: Sicklebrick"},
569+
{4.0_s, "Splash screen: Smidgens"},
570+
{4.0_s, "Fonts: Zingot Games"},
571+
{5.0_s, ""},
557572
{2.0_s, "And that's it."},
558573
{2.0_s, ""},
559574
{3.0_s, "Thanks for watching."},
@@ -581,25 +596,43 @@ class TorusGeneratorScene final : public psyqo::Scene {
581596
void frame() override;
582597
unsigned m_generationFrame = 0;
583598
uint32_t m_startTimestamp = 0;
599+
struct Splash {
600+
psyqo::Prim::TPage tpage1;
601+
psyqo::Prim::Sprite splash1;
602+
psyqo::Prim::TPage tpage2;
603+
psyqo::Prim::Sprite splash2;
604+
};
605+
psyqo::Fragments::SimpleFragment<Splash> m_splashFragment;
584606
// Our generator scene won't try to double buffer, so we only need one set of primitives.
585607
struct ProgressBar {
586608
psyqo::Prim::PolyLine<4> line;
587609
psyqo::Prim::Rectangle rect;
588-
} m_progressBar;
610+
};
611+
psyqo::Fragments::SimpleFragment<ProgressBar> m_progressBarFragment;
589612
uint8_t computePixel(uint8_t x, uint8_t y);
590613

591614
public:
592615
TorusGeneratorScene() {
593616
// Preparing the progress bar drawing calls.
594-
m_progressBar.line.setColor({{.r = 255, .g = 255, .b = 255}});
595-
m_progressBar.line.points[0] = {{.x = 30, .y = 118}};
596-
m_progressBar.line.points[1] = {{.x = 30, .y = 138}};
597-
m_progressBar.line.points[2] = {{.x = 290, .y = 138}};
598-
m_progressBar.line.points[3] = {{.x = 290, .y = 118}};
599-
m_progressBar.line.points[4] = {{.x = 30, .y = 118}};
600-
m_progressBar.rect.position = {{.x = 32, .y = 120}};
601-
m_progressBar.rect.size = {{.w = 0, .h = 17}};
602-
m_progressBar.rect.setColor({{.r = 255, .g = 255, .b = 255}});
617+
m_progressBarFragment.primitive.line.setColor({{.r = 255, .g = 255, .b = 255}});
618+
m_progressBarFragment.primitive.line.points[0] = {{.x = 30, .y = 118}};
619+
m_progressBarFragment.primitive.line.points[1] = {{.x = 30, .y = 138}};
620+
m_progressBarFragment.primitive.line.points[2] = {{.x = 290, .y = 138}};
621+
m_progressBarFragment.primitive.line.points[3] = {{.x = 290, .y = 118}};
622+
m_progressBarFragment.primitive.line.points[4] = {{.x = 30, .y = 118}};
623+
m_progressBarFragment.primitive.rect.position = {{.x = 32, .y = 120}};
624+
m_progressBarFragment.primitive.rect.size = {{.w = 0, .h = 17}};
625+
m_progressBarFragment.primitive.rect.setColor({{.r = 255, .g = 255, .b = 255}});
626+
m_splashFragment.primitive.tpage1.attr.setPageX(8).setPageY(1).enableDisplayArea().setDithering(false).set(
627+
psyqo::Prim::TPageAttr::Tex16Bits);
628+
m_splashFragment.primitive.splash1.setColor({{.r = 128, .g = 128, .b = 128}});
629+
m_splashFragment.primitive.splash1.position = {{.x = 0, .y = 0}};
630+
m_splashFragment.primitive.splash1.size = {{.w = 256, .h = 240}};
631+
m_splashFragment.primitive.tpage2.attr.setPageX(12).setPageY(1).enableDisplayArea().setDithering(false).set(
632+
psyqo::Prim::TPageAttr::Tex16Bits);
633+
m_splashFragment.primitive.splash2.setColor({{.r = 128, .g = 128, .b = 128}});
634+
m_splashFragment.primitive.splash2.position = {{.x = 256, .y = 0}};
635+
m_splashFragment.primitive.splash2.size = {{.w = 64, .h = 240}};
603636
}
604637
};
605638

@@ -615,11 +648,16 @@ void TorusDemo::prepare() {
615648
.set(psyqo::GPU::Interlace::PROGRESSIVE)
616649
.set(psyqo::GPU::MiscSetting::KEEP_VRAM);
617650
gpu().initialize(config);
651+
m_input.initialize();
618652
}
619653

620654
void TorusDemo::createScene() {
655+
MOD_LoadEx(&_binary_LittleCottonPillow_v260_hit_start, NULL);
656+
m_musicTimer = gpu().armPeriodicTimer(MOD_hblanks * psyqo::GPU::US_PER_HBLANK, [this](uint32_t) {
657+
MOD_Poll();
658+
gpu().changeTimerPeriod(m_musicTimer, MOD_hblanks * psyqo::GPU::US_PER_HBLANK);
659+
});
621660
m_font.uploadSystemFont(gpu());
622-
m_input.initialize();
623661
pushScene(&torusGeneratorScene);
624662
}
625663

@@ -674,11 +712,12 @@ void TorusGeneratorScene::frame() {
674712
psyqo::Prim::FlushCache fc;
675713
gpu().sendPrimitive(fc);
676714
pushScene(&torusScene);
715+
return;
677716
}
678717
m_generationFrame++;
679718
uint32_t elapsed = (gpu().now() - m_startTimestamp) / 1000;
680719
int32_t eta = (elapsed * eastl::max(TorusScene::Count, size_t(256))) / m_generationFrame - elapsed;
681-
gpu().clear(c_backgroundColor);
720+
gpu().sendFragment(m_splashFragment);
682721
if (m_generationFrame < 128) {
683722
torusDemo.m_font.print(gpu(), "Generating animation...", {{.x = 60, .y = 80}},
684723
{{.r = 255, .g = 255, .b = 255}});
@@ -692,8 +731,8 @@ void TorusGeneratorScene::frame() {
692731
torusDemo.m_font.printf(gpu(), {{.x = 60, .y = 160}}, {{.r = 255, .g = 255, .b = 255}}, "Elapsed: %us, ETA: %us",
693732
elapsed / 1000, eastl::max(eta, int32_t(0)) / 1000);
694733
// This is the only dynamic part of the progress bar, so that's the only write to our draw calls we're doing.
695-
m_progressBar.rect.size.w = int16_t(m_generationFrame);
696-
gpu().sendPrimitive(m_progressBar);
734+
m_progressBarFragment.primitive.rect.size.w = int16_t(m_generationFrame);
735+
gpu().sendFragment(m_progressBarFragment);
697736
}
698737

699738
void TorusScene::checkSequence(uint32_t currentTime) {
@@ -772,11 +811,11 @@ void TorusScene::frame() {
772811
// These matrix multiplications are done in software, and they're not particularly fast, but it's done only once per
773812
// frame, so it's not really a problem. The computation could be accelerated using the GTE however, but we're not
774813
// starving for CPU at this point, so it's all good.
775-
auto transform = psyqo::SoftMath::generateRotationMatrix33(m_angleX, psyqo::SoftMath::Axis::X, &torusDemo.m_trig);
776-
auto rot = psyqo::SoftMath::generateRotationMatrix33(m_angleY, psyqo::SoftMath::Axis::Y, &torusDemo.m_trig);
777-
psyqo::SoftMath::multiplyMatrix33(&transform, &rot, &transform);
778-
psyqo::SoftMath::generateRotationMatrix33(&rot, m_angleZ, psyqo::SoftMath::Axis::Z, &torusDemo.m_trig);
779-
psyqo::SoftMath::multiplyMatrix33(&transform, &rot, &transform);
814+
auto transform = psyqo::SoftMath::generateRotationMatrix33(m_angleX, psyqo::SoftMath::Axis::X, torusDemo.m_trig);
815+
auto rot = psyqo::SoftMath::generateRotationMatrix33(m_angleY, psyqo::SoftMath::Axis::Y, torusDemo.m_trig);
816+
psyqo::SoftMath::multiplyMatrix33(transform, rot, &transform);
817+
psyqo::SoftMath::generateRotationMatrix33(&rot, m_angleZ, psyqo::SoftMath::Axis::Z, torusDemo.m_trig);
818+
psyqo::SoftMath::multiplyMatrix33(transform, rot, &transform);
780819
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::Rotation>(transform);
781820

782821
// All these will be reused multiple times over the course of the frame.
@@ -876,8 +915,8 @@ void TorusScene::frame() {
876915
// shadow texture, and we multiply it by a 90 degree rotation around the X axis, as the platform is going to be
877916
// rendered visually underneath the torus. This will make the appearance that everything has been projected
878917
// properly, but it's all just a visual trick.
879-
psyqo::SoftMath::generateRotationMatrix33(&rot, 0.5_pi, psyqo::SoftMath::Axis::X, &torusDemo.m_trig);
880-
psyqo::SoftMath::multiplyMatrix33(&transform, &rot, &transform);
918+
psyqo::SoftMath::generateRotationMatrix33(&rot, 0.5_pi, psyqo::SoftMath::Axis::X, torusDemo.m_trig);
919+
psyqo::SoftMath::multiplyMatrix33(transform, rot, &transform);
881920
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::Rotation>(transform);
882921

883922
// At this point, our background DMA chain has most likely finished. At some point, we want to send
@@ -917,13 +956,13 @@ void TorusScene::frame() {
917956
psyqo::Vec3 v1 = m_tori[animationIndex].normals[i + 1];
918957
psyqo::Vec3 v2 = m_tori[animationIndex].normals[i + 2];
919958
psyqo::GTE::Kernels::rtpt();
920-
auto sz = -psyqo::SoftMath::matrixVecMul3z(&transform, &v0);
959+
auto sz = -psyqo::SoftMath::matrixVecMul3z(transform, v0);
921960
int32_t z = sz.integer<256>() - 1;
922961
zNormal[i + 0] = eastl::clamp(z, int32_t(0), int32_t(255));
923-
sz = -psyqo::SoftMath::matrixVecMul3z(&transform, &v1);
962+
sz = -psyqo::SoftMath::matrixVecMul3z(transform, v1);
924963
z = sz.integer<256>() - 1;
925964
zNormal[i + 1] = eastl::clamp(z, int32_t(0), int32_t(255));
926-
sz = -psyqo::SoftMath::matrixVecMul3z(&transform, &v2);
965+
sz = -psyqo::SoftMath::matrixVecMul3z(transform, v2);
927966
z = sz.integer<256>() - 1;
928967
zNormal[i + 2] = eastl::clamp(z, int32_t(0), int32_t(255));
929968
psyqo::GTE::read<psyqo::GTE::Register::SXY0>(&projected[i + 0].packed);
@@ -937,7 +976,7 @@ void TorusScene::frame() {
937976
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::V0>(m_tori[animationIndex].vertices[i]);
938977
psyqo::Vec3 v = m_tori[animationIndex].normals[i];
939978
psyqo::GTE::Kernels::rtps();
940-
auto sz = -psyqo::SoftMath::matrixVecMul3z(&transform, &v);
979+
auto sz = -psyqo::SoftMath::matrixVecMul3z(transform, v);
941980
int32_t z = sz.integer<256>() - 1;
942981
zNormal[i] = eastl::clamp(z, int32_t(0), int32_t(255));
943982
psyqo::GTE::read<psyqo::GTE::Register::SXY2>(&projected[i].packed);
@@ -1038,4 +1077,8 @@ void TorusScene::frame() {
10381077
}
10391078
}
10401079

1041-
int main() { return torusDemo.run(); }
1080+
int main() {
1081+
*((volatile uint8_t*)0x23) = 0;
1082+
psyqo::Kernel::takeOverKernel();
1083+
return torusDemo.run();
1084+
}

loader/Makefile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ TYPE = ps-exe
33

44
SRCS = \
55
loader.c \
6-
texture.tex \
6+
font.tex \
7+
splash.tex \
78
../third_party/nugget/common/crt0/crt0.s \
89
../core/core.o \
10+
../music/music-upload.o \
911

1012
LDFLAGS += -Xlinker --defsym=TLOAD_ADDR=0x80100000
1113

1214
include ../third_party/nugget/common.mk
1315

14-
texture.o: texture.tex
15-
$(PREFIX)-objcopy -I binary --set-section-alignment .data=16 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@
16+
%.o: %.tex
17+
$(PREFIX)-objcopy -I binary --set-section-alignment .data=4 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@
File renamed without changes.

0 commit comments

Comments
 (0)