From the GCC manual.
> GCC permits a C structure to have no members:
struct empty {
};
> The structure has size zero. In C++, empty structures are part of the
> language. G++ treats empty structures as if they had a single member of type
> char.
I was not aware of the different behavior in C++.
This fixes every maple example--most were broken for multiple reasons, including
this one.
This also enables SH4 caching. This includes linking code/data into the P1
area (previously this was not the case).
The maple examples (which indeed involve much use of DMA) require much work to
successfully work with the operand and copyback caches. The vibration example
currently is the most complete, though I should consider more on how I want to
structure maple response operand cache invalidation more generally.
Also adds the incomplete modifier_volume example.
This also adds vec2 for UV coordinates, and obj_to_cpp has been
modified to parse vertex texture coordinates from obj files.
This still needs to be cleaned up, particularly to properly pass the
texture size around--there are a few unnecessary '128x256' magic
numbers scattered in the code.
On an emulator, the receive buffer is filled with the correct/expected
data for 'device status'.
I found this experiment useful:
- it revealed a bug in my register struct generator code (the
maple_if-related registers were not at the correct offsets)
- it validates my understanding about endianness-swapping between the
maple bus and the SH4
This also includes an example for generating a quad primitive. In
flycast, this is very obviously rendered as two triangles. On real
hardware, this appears to be a "native" quad.
This draws a nice macaw texture in a square-shaped triangle
strip. The square is then rotated around the y-axis.
I dealt with myriad bugs while experimenting with this, all of them
entirely my fault:
- macaw texture colors were incorrect because GIMP was exporting raw
RGB data in gamma-corrected sRGB space, whereas the Dreamcast is in
linear color space.
- macaw texture colors were incorrect because I truncated color values
to the least significant rather than most significant bits.
- macaw rotation around the Y axis caused the macaw texture to
distort, stretch and recurse in interesting and unexpected ways. This
was caused by sending Z values in the wrong coordinate space (Z)
contrast to what is expected by the Dreamcast (1/z). Reordering
z-coordinate operations so that the reciprocal is computed last
resolved this.
- macaw rotation around the Y axis caused the macaw texture to warp
unexpectedly, but only on real hardware. This was caused by
unnecessarily negating Z coordinate values.
Behavior for each of the Z-coordinate issues differed between Flycast
and real Dreamcast hardware.
I also did several tests related to SH4 cache behavior, particularly
related to the "copy-back" mode. I verified copy-back behavior on a
real dreamcast, and experimented with the operand cache write-back
instruction, "ocbwb".
In particular, when the `scene` buffer is access from cacheable
memory, e.g: the P1 area, and CCR__CB is enabled, DMA from physical
memory to the TA FIFO polygon converter will fail because the scene
data has not yet been written to physical memory yet. `ocbwb` can be
used to "write back" scene from the SH4 operand cache to physical
memory--only the latter is visible from the CH2-DMA perspective.
This rearranges scene.cpp to a file organization that more closely
follows which code is responsible for what area of (hardware)
initialization.
All TA and CORE register accesses now use the new ta_bits.h and
core_bits.h, respectively.