Changes
=== ints vs shorts vs chars ===
In the description of the methods below, you will notice that all methods take ints. This will not necessarily be the case in sMIDP2lib though. If Since it improves has been decided to limit the screen resolution to 256x256 pixels in order to gain more speed using unsigned shorts or even unsigned chars/bytes, then that'll probably all values can be what we'll do instead. For now, each method is described with ints thoughgiven in unsigned char size.
=== Memory requirements and handling ===
All loading of image and music into memory must of course be handled in some way. I am far from an expert on this area, but I imagine some kind of iterator, keeping track of where the next available memory is. Therefor we also need some way of freeing memory again, e.g. when we close a Player (for example to load a new tune).
This is far from worked out at this stage though.
=== RULES DECIDED SO FAR ===
==== Screen resolution ====
Has been set to 256x256 for optimal performance.
==== Global values accessible from all assembler routines ====
* There will be 4 assembler values called sMIDP2lib_clipX, sMIDP2lib_clipY, sMIDP2lib_clipWidth and sMIDP2lib_clipHeight. They'll contain the coordinates and dimensions set by setClip(int x, int y, int width, int height) method, so that all other assembler routines can retrieve them. Each of these 4 values will be 1 byte.
* There will be 1 assembler value called sMIDP2lib_color which contains the current color set by setColor(int color), so that all other assembler routines can retrieve it. This value will be 1 byte.
* There will be 1 assembler value called sMIDP2lib_currentBufferScreen which contains the number of the current non-visible buffer-screen. It'll either be 0 or 1. Each buffer-screen naturally has an address. These addresses will always be the same. They will never change. So assembler code can ask which screen is currently the non-visible buffer-screen. Note that the non-visible buffer-screen is the one being drawn to. The other screen is the one currently visible.
Terminilogy-wise, "buffer-screen" is what we call the screen we're currently drawing to. This screen will always be hidden as long as we're drawing to it. Only when called flushGraphics() will it become visible. "Visible screen" is the current visible screen (which is never touched while it is visible).
So flushGraphics() will mainly just do a check on which screen is currently the buffer-screen, and then make it visible screen, while making the visible screen the buffer-screen - and then next frame can begin.
<pre>
sMIDP2lib_clipX:
DB &00 ; Initial startup value
sMIDP2lib_clipY:
DB &00 ; Initial startup value
sMIDP2lib_clipWidth:
DB &ff ; Initial startup value
sMIDP2lib_clipHeight:
DB &ff ; Initial startup value
sMIDP2lib_color:
DB &01 ; Initial start value
sMIDP2lib_currentBufferScreen:
DB &00 ; Initial start value
sMIDP2lib_currentBufferScreenAddress:
DB &xx,&xx ; I don't know what the initial value will be yet
</pre>
== Supported Methods ==
The ones written ''in italic'' are some of the more heavier methods, and thus some that will most likely be implemented last in this first stage.
For all these methods goes, that coordinates (0,0) is located in the upper left corner of the screen. On the CPC, the lower right corner will be coordinate (319255,199255). '''Only MODE 1 will be supported in the first many versions of sMIDP2lib.''' If the project becomes popular, it's likely a MODE 0 version will be produced also.If possible, it might be a good idea to change the resolution of the CPC MODE 1 from 319*199 to 240*320, since this is the resolution commonly used in J2ME productions. ''Is it possible to get a MODE 1 resolution of 240x320 pixels that'll work with a lib like this?''Another idea is to use a resolution of 255x255 pixels, if 255 pixels ends up being a limitation of the drawLine() and other methods.
Besides the methods from the MIDP2.0 API, we also need a few additional methods that aren't part of the MIDP2.0 API. These methods are:
''J2ME description: Gets the width in pixels of the displayable area available to the application.''
In sMIDP2lib, this will simply return 319255
=== Displayable.getHeight() ===
''J2ME description: Gets the height in pixels of the displayable area available to the application.''
In sMIDP2lib, this will simply return 199255
=== Image.createImage(String source-filename) ===
unsigned char[] storedPieceOfBackground = new char[64]; // We only need space for 64 bytes, since that equals 256 pixels.
// We ignore the offset and scanlength. They'll need to be part of the method, but will be ignored.
</pre>
The variable sMIDP2lib_bufferscreen sMIDP2lib_bufferScreen is a struct containing a pointer to the address of the current buffer-screen, meaning the one we're currently drawing to. (We'll always be drawing to the non-visible screen). When ever flushGraphics() is called, the current non-visible buffer-screen is shown, and the previous visible screen not becomes the buffer-screen. Therefor, the pointer in the sMIDP2lib_bufferscreen sMIDP2lib_bufferScreen struct, will change value when flushGraphics() is called.
This is a good solution because we keep the MIDP2.0 API structure, and we aren't creating overhead since the data in the arrays can be overridden again and again.
A Java command-line utility will ideally be created (if one doesn't exist already) that will convert 8bit PNG files (and/or maybe other formats) into the sMIDP2lib image format.
== Issues to solve ==
Currently, there are the following issues to work out a solution for:
=== Double-buffering makes it problematic to "un-draw" ===
While double-buffering can potentially make things more smooth, it also causes some problems when it updates only parts of the screen.
Consider a sprite moving from left to right, an unknown number of pixels each frame, on top of a background. You would then use sMIDP2lib_bufferScreen.getRGB() to store the piece of background you're about to draw on, in order to be able to redraw the background in next frame. Let's say the sprite is about to be drawn at (10,0) and it's a 16x16 pixels bit sprite. Then before drawing the sprite, you would call sMIDP2lib_bufferScreen.getRGB() to save the 16x16 pixels piece of background, and then draw the sprite and then call flushGraphics().
Next frame, you will then want to draw that piece of the background again to cover our sprite before drawing the sprite in the next location. But since we switched buffer-screen with the flushGraphics(), we are now drawing on another screen where our sprite is actually placed on another location. Therefor we will most likely not be deleting it properly.
I don't have any ideas on how to solve this at the moment, other that either skipping the double-buffering part, or breaking the MIDP2.0 API rules. But I hope we'll find a solution.
== Contributers ==