News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_mr_lou

sMIDP2lib for SDCC

Started by mr_lou, 17:43, 20 December 11

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Axelay

Quote from: mr_lou on 09:16, 29 December 11

The thing is, we don't know what needs restoring or clearing in two frames time. We don't know if the coder is moving a sprite, or if he's drawing multiple copies of the sprite. The C coder has to be able to code as if it was J2ME. The fact that there are two buffer-screens is transparent to him.


I'm not familiar with how J2ME handles the screen, so how does it work to move a sprite and have the background preserved?  Does the coder restore it or is it handled 'transparently'?  If it is handled transparently, then might it be possible to have flushgraphics() automatically do the switch of the restore buffer too?  It would read it and restore the current invisible screen and reset the pointer to the start of the buffer for other functions to fill with as they write to the screen for use in two frames time.  But I'm wondering if the way J2ME works (sounds like everything is an object?) it might not lend itself to dividing things into background and foreground?  (you mention drawing the background with sprites)



Quote from: mr_lou on 09:16, 29 December 11
That's why I think the only solution is to
10 Draw to hidden screen + fill function buffer with binary code to call the same draw routine in next frame
20 Toggle screens to show the screen that was just drawn to + update the now invisible screen to contain the same content as the visible screen
30 GOTO 10

First thought is something like this: . o O ( Hmm, wouldn't that be rather slow? )
But then I think, that those other buffer-solutions should also be somewhat slow, so maybe the difference isn't that big?


I guess with my own projects CPU time having been 75%+ spent drawing and clearing after sprites etc on the screen, the idea that you would need to do it twice per frame sounds like a near halving of the frame rate, so I'm just hoping some other way can be found!


mr_lou

#26
Quote from: Axelay on 02:35, 31 December 11I'm not familiar with how J2ME handles the screen, so how does it work to move a sprite and have the background preserved?  Does the coder restore it or is it handled 'transparently'?  If it is handled transparently, then might it be possible to have flushgraphics() automatically do the switch of the restore buffer too?  It would read it and restore the current invisible screen and reset the pointer to the start of the buffer for other functions to fill with as they write to the screen for use in two frames time.  But I'm wondering if the way J2ME works (sounds like everything is an object?) it might not lend itself to dividing things into background and foreground?  (you mention drawing the background with sprites)
The way J2ME is drawing to the screen, is just like HTML5 Canvas is drawing to the screen. The developer has to do everything himself. (There are no objects)

J2ME devs typically just clear the whole screen with fillRect(0,0,width,height) and then draw everything again.
I'm guessing the CPC won't be fast enough to do that. Although Demoniak has produced a very fast routine to clear the screen, which is called in sMIDP2lib when fillRect() is called with a coordinate of 0,0 and a width and height of 255 (the whole screen), I think it would be too slow to draw the whole screen again in each frame.
So instead, I'm thinking we should store the piece of background we're about to place a sprite onto, so that we can redraw that piece of background later. Although this is typically not how J2ME devs does it, it is quite compatible with J2ME - and the code can therefor run on other platforms.



int[] pieceOfBackground = new int[256]; // Make room for a 16x16 pixel piece of background
Image.getRGB(pieceOfBackground, 100, 100, 16, 16); // Store the 16x16 pixels at coordinate 100,100. (Simplified example, getRGB has more parameters)
g.setClip(100,100,16,16); // Define the rectangle we'll be drawing to from now on.
g.drawImage(spriteSheet, 84, 100); // Draw sprite number 2 on the sprite-sheet at 100,100.



In next frame we'll start by calling g.drawRGB(pieceOfBackground,100,100,16,16) to cover the sprite from previous frame.

Quote from: Axelay on 02:35, 31 December 11I guess with my own projects CPU time having been 75%+ spent drawing and clearing after sprites etc on the screen, the idea that you would need to do it twice per frame sounds like a near halving of the frame rate, so I'm just hoping some other way can be found!
Yes I agree. That's also why I was thinking about something similar to your suggestion earlier. See this post. That idea only covered the getRGB and drawRGB methods though, and also seems a little unstable.

If something genius could be thought up, that would of course be the ultimate solution. But I can't think of anything.

mr_lou

An alternative project to sMIDP2lib could be a HTML5-Canvas based library, providing a subset of 2d-context canvas drawing methods of HTML5.
Just mentioning it, in case more people would rather contribute to a project like that.

That would mean that anything you code for the CPC using that library, would be able to run on any browser that supports HTML5, including Android and iPhone.

(Although you'd be able to do that with sMIDP2lib too, if/when it was implemented for HTML5 100%)

mr_lou

Well it's been a while. I haven't been able to think up any genius solution to the double-buffering, so I'm still leaning towards the draw-everything-twice idea.

Comparing with the other suggestion that an offscreen buffer would keep track of which parts of the screen was updated, and then just re-draw those parts, would logically also be the same as drawing stuff twice.

So I would like to see my idea about a function buffer in action. Of course I can't code this myself. So I need an assembler coder to help me.

mr_lou

Well, we're not getting anywhere if we keep double-buffering, so I think we'll drop it.

No double-buffering in sMIDP2lib then. (At least not for a while anyway).

So next step could be the music. sMIDP2lib should be able to playback STarKos music by calling some simple code:


music = Manager.createPlayer("music.bin"); // Loads the music from disk
music.start(); // Calls STarKos playback routine


So I figure, the createPlayer routine should probably check if the STarKos playback routine is loaded anywhere, and if not - then load it.
Then load the music.

The start() routine calls the address that starts the music.

But before we can implement this, we'll need to implement the memory handling. It might not be possible to do what I have in mind. I imagine an iterator always pointing to the next available free space. So when you call Manage.createPlayer("music.bin"); it loads the player at the next available address, and sets this address in a variable to tell sMIDP2lib that the playback routine is located there.
Then it loads the music at the next available free space, and puts that address into the music variable.

In order for this to work, it must be possible to load a STarKos binary file into whatever address we want, and I'm in doubt if we can do that. I mean, without saving the binary with that particular address. (We can't, because we don't know where it will be loaded).

So, what does the experts say?

Axelay

Quote from: mr_lou on 09:07, 31 December 11
That's also why I was thinking about something similar to your suggestion earlier. See this post. That idea only covered the getRGB and drawRGB methods though, and also seems a little unstable.

If something genius could be thought up, that would of course be the ultimate solution. But I can't think of anything.


Sorry for the delay in a reply.  I was just wondering what is it that seemed unstable about saving and restoring the background?

mr_lou

Quote from: Axelay on 03:20, 15 January 12Sorry for the delay in a reply.  I was just wondering what is it that seemed unstable about saving and restoring the background?
I was referring to my suggestion for a solution to the double-buffering. My description in this post seems a bit messy to me, and it only covers those two methods.

I think it might be best to drop double-buffering, at least at this point just the get things moving. Then maybe later we can look at it again.

demoniak

Added the void drawRect(unsigned short x1, unsigned short y1, unsigned short width, unsigned short height)  function
(see attached file)


mr_lou

Cool! Thanks a lot!  :)

mr_lou

Well, bumping this thread just to tell that I'm still quite interested in this project.

While the CPC version of sMIDP2lib has been standing still for a while, I have been looking into an HTML5 version.

Check this out: http://dewfall.dk/html5/sMIDP2lib.html
(Click Ok twice due to some issues I haven't fixed yet).

If you view the source, you'll see that it's not really HTML5/Javascript code, but more like J2ME code.
The J2ME code went through a little converter first, to rename all the "int", "long", "String" etc into "var". But otherwise not much has been changed from the J2ME project. (Such a converter is not needed for the Android version. It'll be necessary for the CPC version (SDCC), but that's not a problem).

I hope to revive the CPC version of sMIDP2lib soon, and make a similar little demo. So far the CPC version has a lot of the draw functions implemented. Next comes the image-drawing functions, which first requires us to agree on some simple image-format.

mr_lou

#35
P.S.: I should probably mention that the above link only works with non-Microsoft browsers. (I trust no one here in their right mind relies solely on Internet Explorer). Try with any other browser.

EDIT: Works now in Internet Explorer, and even on my Android phone (although with a very slow framerate).

Powered by SMFPacks Menu Editor Mod