Generally I prefer to use bitmap tables to draw parts of an image, but that requires all of the sub-images to be laid out in rectangles of the same size. If bitmap tables are not suitable for your purpose, then what you are doing should work. The only thing I'm not sure about is the math in (animIndex * charSize) - ((charIndex % 16) * charSize * 2) and ((int)(charIndex / 16) * charSize). But since I don't know how your spritesheet is arranged, I can't say for sure. You say that it doesn't do what you want, but what does the code actually do?
It cycles through these characters using the D-Pad, each with two frames of animation (image is cropped)
It's just a test, really. What I'm wondering is if there's a (more straighforward) way to draw a scene from a spritesheet, without having to split the image. playdate->graphics->tileBitmap seems to draw only the top left rect of the image afaik.
And I know I shouldn't be worrying about performance right now, but it's already at 49FPS with only one character on screen. I've seen whole games and more complex demos running at 50. Perhaps it's because the image is "big" (1536x1968).
Ah, I misunderstood your original post. So the setClipRect code does actually do what you want? If you are worried about optimization, I guess you could convert the division and modulus to bit shifting operations since they are power of two. The compiler optimization might do that automatically, I'm not sure.
In your case, I don't see any downside to using bitmap tables. It's basically a convenience feature that allows you to access a spritesheet by index. You don't really have to "split" the images, unless I am misunderstanding your use case.
As for tileBitmap, I think that is just for repeating a bitmap multiple times in a rectangle, not for drawing part of a bitmap.
I totally misunderstood how bitmap tables were supposed to work. I assumed I had to add bitmaps one by one. I completely missed the part on setting a postfix for the spritesheet. Going back and forth between Lua and C is a pain, it's explained a lot better in the former. I also forgot I was clearing the whole screen each frame.