Currently, if the user wants to load a GRF file with a palette, the
function NE_MaterialTexLoadGRF() will fail unless it is provided a palette
object.
With this change, if a palette object isn't provided, it will be created
and marked for automatic deletion when the material is deleted.
In many cases the developer doesn't want to keep track of palettes and
materials as two different objects. This is only required if a palette
needs to be shared between multiple materials.
In cases where there a palette is only used by one material, this new
function can be used so that the developer doesn't need to keep track of
the palette object, only the material.
Now that there are 4 different possibilities (not initialized, single
screen 3D mode, dual 3D mode, safe dual 3D mode) it is better to have an
enum instead of multiple bools.
The previous code relied too much on assertions, even for things that
are just regular things that may happen while the application is running
(like running out of memory).
- Many assertions have been turned into permanent checks
- Some functions now return "success" or "failure".
- NE_Init3D() and NE_InitDual3D() (and others) have been reworked to
handle failures gracefully.
Until now, a mesh was always owned by one single model. This made it
very difficult to clone models, because the mesh was always owned by one
of them. Whenever you deleted that model, the mesh was also deleted, and
all the cloned models would be unusable.
With the new system, there is a list of meshes with counters of how many
models use them. This way no matter how many models use the mesh, the
mesh will only be deleted when the last model is deleted.
In addition, in a similar way as before, a mesh has a flag that signals
if free() has to be called on the mesh data when the mesh is deleted.
This is useful when the mesh is loaded from a filesystem and stored in a
buffer allocated with malloc(), which is what Nitro Engine does.
Note that this code should be considered experimental for the time
being, until some tests are added.
Previously it wasn't possible to load one texture to a material, clone the
material, and assign different palettes to each clone of the material.
With this change, it is possible to have the same texture with different
palettes.
This is done to make it easier to implement compressed texture loading.
The main change is to stop allowing widths that aren't a power of two:
- Supporting them complicates the loading code a lot.
- Compressed textures can't really be expanded because they are composed
by many 4x4 sub-images.
- They don't save space in VRAM.
- They save space in the final ROM, but you can achieve the same effect
compressing them with LZSS compression, for example.
The example incomplete_texture has been updated to reflect the new
limitations.
Remove support for asking for a specific alignment. Now, the only
supported alignment is 16 bytes, and all sizes are rounded up to 16
bytes. This is the minimum alignment needed for some palettes, which is
the most restrictive case.
This change is a bit wasteful, but it only really matters for 4-color
palettes and textures, which can be aligned to 8 bytes, and it isn't a
problem because:
- 4-color palettes, which can be aligned to 8 bytes, would rarely use
fewer than 4 colors. Even if they do use fewer than 4 colors, it would
only waste 8 bytes.
- Textures: It's impossible that a texture doesn't have a size that is
multiple of 16. It can only happen if the texture has a width of 8
pixels and a height that isn't a multiple of two... which is a very
unusual situation.
The benefit of this change is that the code is much easier to understand
and much more maintainable, which will be needed when support for
compressed textures is added, as the code will need to support more
features.
NE_MaterialClone() clones everything, not just the texture.
NE_MaterialSetPalette() sets the palette of the material, not the
palette of the texture (different materials may use the same texture but
different palettes.
This helps the compiler issue warning if there is some logical error in
the code, and it helps the developer realize if some assumption with
the code is wrong.
With a bit of help of `indent -linux`, but mostly by hand. Also used
`iconv -f ISO-8859-1 -t UTF-8//TRANSLIT` to convert to UTF-8.
There is still some refactoring left to do.