Android - Assests loading with splash and device detection.

Previous topic - Next topic

spacefractal

I have looked into those issues a glbasic app might look like its crashing under assets copy as well missing some info you could use (example detection a Kindle Fire).

To get this to work, you must create a another directly with name "Splash" in "distribute\Android\assets" (DONT create Splash folder in the Media folder, its must been outside that). Inside Splash folder, you can add your splash picture, example splash.jpg. While that splash.jpg is shown, Media assests would copied to the SDCARD in a thread.

Here I then use PLATFORMINFO$("TEMP") info to check if its have been copied or not, and when its finished I got the "temp" path. Howover I do also abused that command to add some info to that as well, so you cannot use PLATFORMINFO$("TEMP") directly to get the temp folder, but you can use StringField(PLATFORMINFO$("TEMP"), 1, "|") instead.

Here is the glbasic code for doing above:

Code (glbasic) Select

AndroidLoading()
AndroidSettings()

FUNCTION AndroidLoading:
STDOUT "WAITCOPY()"
LOCAL file$=GETCURRENTDIR$()+"/Splash/splash.jpg"

IF PLATFORMINFO$("DEVICE")="TOUCHSCREEN" OR PLATFORMINFO$("DEVICE")="KEYBOARD"
SLEEP 250
LIMITFPS 10
LOCAL x, y
GETSCREENSIZE x, y
LOCAL image=0
LOCAL SCALING=y/320
IF SCALING<0.5 THEN SCALING=0.5
IF SCALING>1.0 THEN SCALING=1

WHILE PLATFORMINFO$("TEMP")="INSTALLING" AND PLATFORMINFO$("TEMP")<>""
ControlTilt() // Make sure to set orintation
IF image=0
IF DOESFILEEXIST(file$)=1
LOADSPRITE file$, 1
image=1
ENDIF
ENDIF
IF image=1
// draw rutunes here, example splash icons or such (I used functions here, but you have the idea)
PaintImage(1, 0, 0, 1, 0, 0)
ENDIF
SHOWSCREEN
WEND
ENDIF
LOADSPRITE "", 1
ENDFUNCTION

FUNCTION AndroidSettings:
LOCAL osproduct$
LOCAL osdevice$
LOCAL OSManufacturer$
LOCAL osmodel$
LOCAL info$=PLATFORMINFO$("TEMP")
info$=REPLACE$(info$, "null", "")
FOR i=2 TO 7
LOCAL name$=StringField$(info$, i, "|"); name$=LCASE$(name$); name$=TRIM$(name$)
LOCAL value$=StringField$(name$, 2, "="); value$=LCASE$(value$); value$=TRIM$(value$)
name$=StringField$(name$, 1, "=")
IF name$<>""
IF name$="osproduct" THEN osproduct$=value$
IF name$="osdevice" THEN osdevice$=value$
IF name$="osmanufacturer" THEN OSManufacturer$=value$
IF name$="osmodel" THEN osmodel$=value$
ELSE
BREAK
ENDIF
NEXT

STDOUT "product: "+osproduct$+" "+osdevice$+" "+OSManufacturer$+" "+osmodel$
IF osproduct$="touchpad" AND osdevice$="tenderloin" THEN STDOUT "HP Touchpad"
IF osmodel$="'kindle fire" AND OSManufacturer$="amazon" THEN STDOUT "Amazon Kindle Fire"
ENDFUNCTION

FUNCTION ControlTilt: direct=0 // perform ORIENTATION check before showing the loading image, or its might shown wrong direction.
STATIC COUNTER=0
STATIC ORIN=0
LOCAL x, y
LOCAL NEWRIENTATION
STATIC yres, xres

COUNTER=COUNTER+1
IF COUNTER>100 THEN COUNTER=85
IF (COUNTER=17 OR direct=1)
IF ORIN>-1 AND GETORIENTATION()<>ORIN
SETORIENTATION ORIN
RETURN
ENDIF
ENDIF
IF MOD(COUNTER, 15)<>5 THEN RETURN

IF GETORIENTATION()=0
y=GETJOYY(0)*100
x=GETJOYX(0)*100
ELSEIF GETORIENTATION()=1
y=-GETJOYX(0)*100
x=GETJOYY(0)*100
ELSEIF GETORIENTATION()=2
y=-GETJOYY(0)*100
x=-GETJOYX(0)*100
ELSE
y=GETJOYX(0)*100
x=-GETJOYY(0)*100
ENDIF

IF (y>60 OR KEY(17)=1) AND ORIN<>2
ORIN=2; COUNTER=0;
ELSEIF (y<-60 OR KEY(31)=1) AND ORIN<>0
ORIN=0; COUNTER=0;
ELSEIF (x>60 OR KEY(32)=1) AND ORIN<>3
ORIN=3; COUNTER=0;
ELSEIF (x<-60 OR KEY(30)=1) AND ORIN<>1
ORIN=1; COUNTER=0;
ENDIF
ENDFUNCTION

FUNCTION PaintImage: ID, x#, y#, zoom#, xspot, yspot // paint image with some hotspot features.
LOCAL h#, w#, img, SH, SW, PX#, PY#, PW#, PH#
LOCAL img=ID

GETSPRITESIZE img, w, h
GETSCREENSIZE SW, SH

// math placement for hotspots
IF xspot=-1 THEN PX=x#
IF xspot=0 THEN PX=SW/2.0-(w#*zoom#/2.0)+x#
IF xspot=1 THEN PX=SW-w#*zoom#-x#
IF yspot=-1 THEN PY=y#
IF yspot=0 THEN PY=SH/2.0-(h*zoom#/2.0)+y#
IF yspot=1 THEN PY=SH-h#*zoom#-y#
PW=w*zoom#
PH=h*zoom#

// draw a sprite top on the drawrect box, but its slighty off. Also some rotation support, not finished, but dont think about it.
ZOOMSPRITE img, PX#-((1-zoom#)*w#)/2, PY#-((1-zoom#)*h#)/2, PW#/w#, PH#/h#
ENDFUNCTION

FUNCTION StringField$: TXT$, index%, Delimeter$ // a very handy stringfield function, which is very much missing in glbasic.
LOCAL i, char$
LOCAL RESULT$=""
FOR i=0 TO LEN(TXT$)
LOCAL char$=MID$(TXT$, i, 1)
IF char$=Delimeter$ OR i=LEN(TXT$)
index%=index%-1
IF index%=0 AND i=LEN(TXT$)
RETURN RESULT$+char$
ENDIF
IF index%=0 THEN RETURN RESULT$
IF i=LEN(TXT$) THEN RETURN ""
RESULT$=""
ELSE
RESULT$=RESULT$+char$
ENDIF
NEXT
RETURN ""
ENDFUNCTION


The changed SDLActivity.java is in Attachements and must been in Compiler\platform\android\templateproj\src\com\glbasic\test in glbasic main folder. You can also add more into to the TEMP folder by adding more info in around line 115. Fell free to do that.

Howover this code does NOT fix the surface issue, which I guess Gernot allreadt have fixed (twice?). Also I have only access to the early v11 beta, so its must been tested in the newer as well copied the changed code..... I could do that if I got a never version eventuelly.

[attachment deleted by admin]
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

spacefractal

I have updated SDLActivity.java by fixing CopyAssests() to first modify time after all files have been copied. This prevent the app crash if the user have closed down while copy assets and then missing them in the reload.

Also I have out commented egl.eglWaitGL() as well egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null) in flipEGL() as well. On my HP touchpad that gave a boost from 20fps to fluid 30fps with vety few frameskips in my game (while I use LIMITFPS 30 on Android).

Im not sure why those does, but seen they are not needed at all and allready happens with LIMITFPS and thinks its shometimes have waited one more vblank as its should.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

Slim

Thanks, will have to give it a try once I fix the capacitive touch digitizer on my Droid.

spacefractal

howover its would been very excellent assets files could been read directly from the apk (just a renamed zip), which would save a lots of memory. Its seen its allways copy the assests files to the internal memory and not to SDCARD, even I have added the permissions to the menifest file.

For Greedy Mouse, there is a too lengthly installation in about 40 secs and easy to break and need to recopy again. Its is not a very smart method, but its does works correctly (which is most important and cool for v1.0).

Actuelly I also found this, which I guess would been the best alternative for direct assest access (and hence its would automatic been better zip/shoebox support as well, which is great?
http://androgeek.info/?p=275

Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

spacefractal

Im are curretly looking how to do a better assests loading, because Greedy Mouse sometimes still fail and can crash under install. When that happens, then the game would not function correctly. That is pretty annoying for me its its users. So the current assets loading also not work and is to buggy to use.

So Im in this week seen a way to do a direct communication with java from GlBasic. The good new, its seen its actulley is possible!

More info later how doing that (when I have complete code), but for now I just say Im using NETWEBEND to send a command to SDLActivity.Java (to public static int glb_open_url(String url)) and I can retrieve using PLATFORMINFO$("TEMP"). So Im currectly abusing those two commands to doing various tasks than they orignally is used for (except NETWEBEND still open a webpage if http: is used).

A neat little trick and its that I have looking for in month. Of course I still see own command doing this task, buts is much better than nothing.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

spacefractal

Here is a faster recursive copy function, which can been used in SDLActivity.Java
Code (glbasic) Select

private void recursiveCopy(String path, int file) {
Log.i("glbasic", "attempting to copy folder: ".concat(path));
try {
if (file==0)
{ String[] list = getAssets().list(path);
Log.i("glbasic", path.concat(" is a directory"));
File newDir = new File(getFilesDir().getAbsolutePath().concat(File.separator).concat(path));
newDir.mkdir();
Log.i("glbasic", "created directory: ".concat(newDir.getAbsolutePath()).concat(", copying content..."));
for (String item : list)
{ if ("" != path)
{ recursiveCopy(path.concat(File.separator).concat(item), 1); }
else
{ recursiveCopy(item, 0);
}
}
} else { // path ist kein Verzeichnis (oder leer)
Log.i("glbasic", path.concat(" is a file, reading..."));

File newDir = new File(getFilesDir().getAbsolutePath().concat(File.separator).concat(path));
File sourceFile = new File(path);

int copyfile=0;
if (newDir.exists() && sourceFile.exists())
{ copyfile=0;
if (newDir.length()!=sourceFile.length() || sourceFile.length()<1)
{ copyfile=1;
boolean ok=newDir.delete();
}
}
else
{
copyfile=1;
}

if (copyfile==1)
{ InputStream in = getAssets().open(path);
FileOutputStream out = new FileOutputStream(getFilesDir().getAbsolutePath().concat(File.separator).concat(path));
int read;
byte[] buffer = new byte[4096];
while ((read = in.read(buffer)) > 0)
{ out.write(buffer, 0, read);
}
out.close();
in.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}


The reason the copy was pretty slow is the String[] list = getAssets().list(path); command, which take a while each time its invoked. That command is really only required for each folder, not on file. So I but a another argument to the function, so its allready known its a file or not. Also its also compare if the file allready exit or not. So if its should crash, then its just countinue where its left. Also if filesize is different, its also copy the file. So no more require to delete the whole folder for each update.

Greedy Mouse using with direct java communication also load much much faster, even on first time.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

Kitty Hello


spacefractal

yep, its safe to use for direct replace (and adding the second argument). Remember start the function by a folder first to the second argument.

The function even should also works, even without doing recursivedelete first. Howover here, that can been a bit less safe. Assest files will only been updated and replaced, if filesize changes.

In Greedy Mouse, Im not doing recursivedelete at all, due Im not using bmp and other fixed filesize files.

Today I just added License Policy Manager to my project. This due I now do java communication directly by abusing those two commands. I do code snippet later.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/