Closed Nokia64 closed 2 years ago
That read
method should always block waiting for data. If data can't be read, an IOException
should be thrown. Data should be stored in b[]
as it they're read until len
bytes have been read or an IOException
is thrown.
In the event of an IOException
, any bytes that were already stored in b[]
will still be stored. This should be the only case where less than len
bytes of data are returned.
(While the documentation doesn't clarify, I expect that no bytes will be read and stored in b[] in the case of an IndexOutOfBoundsException as that can be detected early.)
Sorry that I can't be of more help at the moment...
I tried to launch this game and found a problem in RMS. The game catches the RecordStoreNotFoundException
, but the RecordStore catches it on its own code and rethrows a more generalized RecordStoreException
: https://github.com/hex007/freej2me/blob/cce8347047159a29f44f2c5a9ec0e9ac78609d51/src/javax/microedition/rms/RecordStore.java#L102-L113
As for images, KEmulator loads them using SWT, since ImageIO is more capricious - that is, the problem is probably in the features of the image format.
Thanks a lot woesss! #118 's working nicely for me, too The RMS patch will fix a huge ton of games, btw What was ultimately the issue? I see you entirely reworked getResourceAsStream()
Also thank you recompileorg for clarifying on the read() method! I'll wait for the PR to be merged and close this issue
P.S: Now there's another mystery 😉 The same exact problem appears at KEmulator too, but not a real Nokia I'll open a new issue for this later (hopefully soon, been real busy lately -.-)
Sorry it took so long. We've got a new baby and things are a bit crazy.
Thanks woesss for the great work!
@Nokia64, You guessed correctly - the problem is in the read method, it does not guarantee that all data will be read in one call. ByteArrayInputStream
doesn't have this problem.
Characters disappear because the clip area is set incorrectly - I did not understand why, possibly due to a thread race condition.
P.S. Hmm... I did not see the root of the problem - the main class is loaded by another method and is not processed with ASM, which replaces getResourceAsStream()
. That is, in other games, resources from the main class code may not be loaded at all.
P.S: Now there's another mystery wink
I figured out the reason for this problem.
The game calls NokiaUI's DirectUtils.getDirectGraphics()
and uses the resulting object to the end. But the emulator creates a new Graphics
object for every call to paint, and setting it (like setClip()
) has no effect on that DirectGraphics
object because it uses the Graphics
instance passed to the getDirectGraphics()
method.
The game Omega Mission by Gamebo (tested JAR md5:
9f353fbf1c7bf54aa306ce63ed7f1fd6
) crashes during initialization in FreeJ2ME due to it passing a damaged PNG image tojavax.microedition.lcdui.Image.createImage(byte[], int, int)
. The images load fine in KEmulator and a Nokia 7230Tracing it back, such image is stored into a packed resources file (
/1
into the JAR) and read into a byte array by a custom routine at the game (GameMidlet.a(String,int,int)
) which uses a DataInputStream to read the file from the JAR then pass it to createImage(). The image data is 15KB but it appears to be truncated at around ~7KB as passed to createImage() A small visual treat to spice up the issueThe game expects a single call to
DataInputStream.read(byte[] b, int off, int len)
to return all the data and ignores its return value, while according to the javadocs it appears not to neccesarily do so (https://nikita36078.github.io/J2ME_Docs/docs/midp-2.0/java/io/InputStream.html#read(byte[],%20int,%20int)) (I'm unsure about it, though. Don't clearly understand when it's supposed to return less data than available and when to block)I think the FreeJ2ME-passed InputStream object doesn't returns all the available data from the stream on a
read(byte[] b, int off, int len)
call, behaviour this game appears to rely on. The game code is obfuscated and also performs an intermediate transform on the data, though. Will try setting up a small test MIDlet instead to be able to better peek into what's going on.Thank you!