Terrain collision is done
现在终于可以自由的做东西了,算是一个新的起点,啥都从头写,太多东西需要去做。
有人喊我继续更新模拟器,加这个加那个。。。但目前来说还得先放一放了。。
XXXXXXXXXXXXX图片删了XXXXXXXXXXXXXXXXXXXX
现在终于可以自由的做东西了,算是一个新的起点,啥都从头写,太多东西需要去做。
有人喊我继续更新模拟器,加这个加那个。。。但目前来说还得先放一放了。。
XXXXXXXXXXXXX图片删了XXXXXXXXXXXXXXXXXXXX
English & Chinese are added, 2008.07.26
Users can add their own language file for the emulator.
—/language //language path
————/default.txt //rename your language file to default.
————/english.txt
————/chinese.txt
there are 2 big bugs in v0.9.5 released at 07/03/2008
Now fixed.. 
Strange usage of Canvas.setFullMode(boolean) ?。。。
———- Before calling setFullMode, the routine records the height of canvas(getHeight()) into "a"
———- After then, for(; a == getHeight(); sleep(200L)); so so so….
To running "Iron man", I fill up the setFullMode function!! — add Ticker to "normal mode" Canvas
It’s a problem one year before… refer to: http://lyo.blogsome.com/2007/03/24/javautiltimer-diffs-in-j2me-j2se/
Today,I meet the problem again!After hours testing & coding, it was done!so exciting!^_^
Powerful ASM lib ( http://asm.objectweb.org/ )
==========
We need to replace 2 classes: java.util.Timer & java.util.TimerTask ( they must in the same package:( )
1. get both classes’ source codes from MIDP implement.
2. adapter user’s classes
// deal with the super class
public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String[] interfaces)
{
if(superName.equals("java/util/TimerTask"))
{
super.visit(version, access, name, signature, "xxx/xxx/xxx/SubTimerTask", interfaces);
return;
}
else if(superName.equals("java/util/Timer"))
{
super.visit(version, access, name, signature, "xxx/xxx/xxx/Timer", interfaces);
return;
}
super.visit(version, access, name, signature, superName, interfaces);
}
// deal with class members
public FieldVisitor visitField(int access, String name,
String desc, String signature, Object value)
{
if(desc.equals("Ljava/util/Timer;"))
desc = "Lxxx/xxx/xxx/Timer;";
return cv.visitField(access, name, desc, signature, value);
}
3. adapter new Timer()
public void visitTypeInsn(final int opcode, final String desc)
{
……….
if(desc.equals("java/util/Timer"))
{
super.visitTypeInsn(opcode, "xxx/xxx/xxx/Timer");
return;
}
……….
}
4. adapter method calls
public void visitMethodInsn(int opcode, String owner, String name, String desc)
{
……….
if(owner.equals("java/util/Timer"))
{
if(desc.indexOf("java/util/TimerTask") != -1)
desc = desc.replaceAll("java/util/TimerTask", "xxx/xxx/xxx/SubTimerTask");
super.visitMethodInsn(opcode, "xxx/xxx/xxx/Timer", name, desc);
return;
}
else if(owner.equals("java/util/TimerTask"))
{
super.visitMethodInsn(opcode, "xxx/xxx/xxx/SubTimerTask", name, desc);
return;
}
……….
}
=========
This will be included in next version of KEmulator…
Fast, High-quality != Easy-porting ? NO!!
But…
import java.io.*;
import javax.microedition.io.*;
public class TestInput {
public static void main( String args[] ) {
try {
String uri = \"file:c:/autoexec.bat\";
InputConnection conn = (InputConnection)
Connector.open( uri,
Connector.READ );
InputStream in = conn.openInputStream();
int ch;
conn.close(); // doesn’t close input stream!
while( ( ch = in.read() ) != -1 ){
System.out.print( (char) ch );
}
in.close();
}
catch( ConnectionNotFoundException e ){
System.out.println( “File could not be
found!” );
}
catch( IOException e ){
System.out.println( e.toString() );
}
System.exit( 0 );
}
}
Notice that the program can safely close the connection after it obtains the input stream!!! The input stream isn’t closed !! And the output stream either.