1) It's an API for the sprite manager, so it gets a subroutine because that's how APIs work (I'm not going to inline that into an unrelated portion of code and ruin organization when it's a non-issue)Miquel wrote: ↑Fri Nov 10, 2017 2:17 pmAbout the "Reset/Clear" function:
As you do with a typical 3D game where you resend all the meshes (triangles) every frame to the render engine, I think is convenient to reset the sprite list every frame not as an optional behaviour in your custom code but as an embedded working idea for most situations. Are there exceptions? Of course! but for the complexity of a MD game is necessary this approach as a basis.
2) I actually managed to get bitten once by not making clear optional (tip: don't ever do a fade in function that halts the game unless you explicitly make it not clear the sprite table)
I normally arrange things into "major" and "minor" subroutines. The former are the big chunks of program logic and use up all registers, the latter are meant to be helpers within an algorithm and are only expected to scratch a few (since the remainder registers would be still in use by the algorithm that invoked them).Miquel wrote: ↑Fri Nov 10, 2017 2:17 pmAbout the "AddSprite" function, but first a little about the 68K philosophy:
The idea behind the implementation of the 68000 itself is that ideally a function/routine uses all free 15 registers and when it needs more register another function is called. Was designed this way because an experienced programmer uses around 10 local variables in a complex function. Probably right now you are thinking that not all functions should be complex in a program, if so: don't forget about inlining/macros/defines and it's virtues.
This is how the cpu is optimized at it's maximum, you use all 15 registers for your current task, you need to call for another task, you push almost all registers, push the parameters, do the call to subroutine, do the task, pop back all the register,... and so on.
So calling to a subroutine is a heavy task!
Also I don't know how pushing registers all the time is faster, memory accesses are slow. Better to reserve a few registers to scratch for minor subroutines. Heck, even the 68000 C ABI reserves a few for this reason.
The reason you don't build complex primitives on top of PutPixel is because often you can optimize away all the checks by doing clipping first (and I haven't found a way to get rid of the checks AddSprite does, as in a metasprite you still want to get rid of the sprites outside the boundaries, and you always want to check against the sprite limit to prevent a crash).Miquel wrote: ↑Fri Nov 10, 2017 2:17 pmAbout the "AddSprite":
In the same way in other environments, while going for real, you don't do a "PutPixel" or a "PutTriangle" because the continuing calling/returning will completely kill the cpu, the same happens on the 68K when trying to use a "AddSprite".
The reason you don't do PutTriangle but instead whole models (and in practice not even that, you just build a huge list to be sent all at once) is because the CPU-GPU bus and starting a draw call is a massive bottleneck. Remember OpenGL used to literally work the PutTriangle way at some point - because early on that didn't matter.
And that isn't any different here, in fact: ClearSprite starts the list, AddSprite builds the list, UpdateSprite submits it.