1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-03 11:11:20 +00:00
QB64-PE/source/android/android_methods.bas

552 lines
18 KiB
QBasic

SUB AryAddStr (Ary() AS STRING, value AS STRING) 'create new entry and return its index
IF LEN(Ary(0)) = 0 THEN Ary(0) = "0"
index = VAL(Ary(0)) + 1
lastIndex = UBOUND(Ary)
IF index > lastIndex THEN
lastIndex = index * 2
REDIM _PRESERVE Ary(lastIndex) AS STRING
END IF
Ary(0) = STR$(index)
Ary(index) = value
AryNewStr = index
END SUB
FUNCTION AryLastStr (Ary() AS STRING) 'get last used index or 0 if none used
IF LEN(Ary(0)) = 0 THEN Ary(0) = "0"
AryLastStr = VAL(Ary(0))
END FUNCTION
SUB CreateAndroidProject_ReplaceInFile (thisFile$, find$, replaceWith$)
fh = FREEFILE
OPEN thisFile$ FOR BINARY AS #fh
a$ = SPACE$(LOF(fh))
GET #fh, , a$
starti=1
DO WHILE INSTR(starti, a$, find$) > 0
i = INSTR(starti, a$, find$)
a$ = LEFT$(a$, i - 1) + replaceWith$ + RIGHT$(a$, LEN(a$) - i - LEN(find$) + 1)
starti=i+len(replaceWith$)
LOOP
CLOSE #fh
KILL thisFile$
OPEN thisFile$ FOR BINARY AS #fh
PUT #1, , a$
CLOSE #fh
END SUB
FUNCTION CreateAndroidProject_EscapeFileName$ (a$, method)
a2$ = ""
FOR i = 1 TO LEN(a$)
c$ = CHR$(ASC(a$, i))
IF method <> 2 THEN
IF c$ = ":" THEN c$ = "\:"
END IF
IF c$ = "\" THEN c$ = "\\"
a2$ = a2$ + c$
NEXT
CreateAndroidProject_EscapeFileName$ = a2$
END FUNCTION
FUNCTION CreateAndroidProject_FindFile$ (thisFile$)
fh = FREEFILE
OPEN "programs\android\template\located_files.txt" FOR BINARY AS #fh: CLOSE #fh
OPEN "programs\android\template\located_files.txt" FOR INPUT AS #fh
DO UNTIL EOF(fh)
LINE INPUT #fh, a2$
IF RIGHT$(a2$, LEN(thisFile$)) = thisFile$ THEN
IF _FILEEXISTS(a2$) THEN 'verify file exists
CreateAndroidProject_FindFile$ = a2$
CLOSE #fh
EXIT FUNCTION
END IF
END IF
LOOP
CLOSE #fh
SHELL _HIDE "cmd /c dir /s /b " + CHR$(34) + "c:\" + thisFile$ + CHR$(34) + " >internal\temp\files.txt"
OPEN "internal\temp\files.txt" FOR INPUT AS #fh
a$ = ""
IF NOT EOF(fh) THEN
LINE INPUT #fh, a$
END IF
CLOSE #fh
IF a$ <> "" THEN
inLocatedFiles = 0
OPEN "programs\android\template\located_files.txt" FOR INPUT AS #fh
DO UNTIL EOF(fh)
LINE INPUT #fh, a2$
IF a2$ = a$ THEN
inLocatedFiles = 1
END IF
LOOP
CLOSE #fh
IF inLocatedFiles = 0 THEN
OPEN "programs\android\template\located_files.txt" FOR APPEND AS #fh
PRINT #fh, a$
CLOSE #fh
END IF
END IF
CreateAndroidProject_FindFile$ = a$
END FUNCTION
FUNCTION CreateAndroidProject_GetNdkPath$
CreateAndroidProject_Message "Locating NDK in filesystem (this could take a while the first time)"
thisFile$ = CreateAndroidProject_FindFile$("ndk-build")
IF thisFile$ <> "" THEN
CreateAndroidProject_Message "NDK located at '" + thisFile$ + "'"
END IF
IF thisFile$ = "" THEN
CreateAndroidProject_Message "NDK not found. Assuming 'c:\ndk\ndk-build'"
thisFile$ = "c:\ndk\ndk-build" 'use default path
END IF
FOR i = LEN(thisFile$) TO 1 STEP -1
IF ASC(thisFile$, i) = 92 THEN
thisFile$ = LEFT$(thisFile$, i - 1)
EXIT FOR
END IF
NEXT
CreateAndroidProject_GetNdkPath$ = thisFile$
END FUNCTION
FUNCTION CreateAndroidProject_GetSdkPath$
CreateAndroidProject_Message "Locating SDK in filesystem (this could take a while the first time)"
thisFile$ = CreateAndroidProject_FindFile$("AVD Manager.exe")
IF thisFile$ <> "" THEN
CreateAndroidProject_Message "SDK located at '" + thisFile$ + "'"
END IF
IF thisFile$ = "" THEN
CreateAndroidProject_Message "SDK not found. Assuming '%appdata%\..\local\android\sdk\AVD Manager.exe'"
thisFile$ = "%appdata%\..\local\android\sdk\AVD Manager.exe" 'use default path
END IF
FOR i = LEN(thisFile$) TO 1 STEP -1
IF ASC(thisFile$, i) = 92 THEN
thisFile$ = LEFT$(thisFile$, i - 1)
EXIT FOR
END IF
NEXT
CreateAndroidProject_GetSdkPath$ = thisFile$
END FUNCTION
FUNCTION CreateAndroidProject_GetGradlePath$
CreateAndroidProject_Message "Locating Gradle in filesystem (this could take a while the first time)"
thisFile$ = CreateAndroidProject_FindFile$("gradle.bat")
IF thisFile$ <> "" THEN
CreateAndroidProject_Message "Gradle located at '" + thisFile$ + "'"
END IF
IF thisFile$ = "" THEN
thisFile$ = "C:\Program Files\Android\Android Studio\gradle\gradle-2.2.1\bin\gradle.bat"
CreateAndroidProject_Message "Gradle not found. Assuming '+thisFile$+" '"
END IF
FOR i = LEN(thisFile$) TO 1 STEP -1
IF ASC(thisFile$, i) = 92 THEN
thisFile$ = LEFT$(thisFile$, i - 1)
EXIT FOR
END IF
NEXT
CreateAndroidProject_GetGradlePath$ = thisFile$
END FUNCTION
SUB CreateAndroidProject_Message (message AS STRING)
statusWindowX=2
statusWindowY=idewy - 3
statusWindowHeight=3
statusWindowWidth=idewx - 2
'clear status window
for y=statusWindowY to statusWindowY+statusWindowHeight-1
locate y,statusWindowX: PRINT SPACE$(statusWindowWidth);
next
for y=statusWindowY to statusWindowY+statusWindowHeight-1
messageLength=len(message)
if messageLength>0 then
if messageLength>statusWindowWidth then messageLength=statusWindowWidth
locate y,statusWindowX: print left$(message,messageLength);
message=right$(message,len(message)-messageLength)
end if
next
PCOPY 3, 0
END SUB
SUB CreateAndroidProject_RestoreFile (file AS STRING, projectFolder AS STRING)
SHELL _HIDE "cmd /c copy programs\android\template\untitled\" + file + " " + projectFolder + "\" + file
END SUB
FUNCTION CreateAndroidProject_PathReference$ (path AS STRING)
a$ = path
FOR i = 1 TO LEN(a$)
IF ASC(a$, i) = 92 THEN ASC(a$, i) = 47
NEXT
CreateAndroidProject_PathReference$ = a$
END FUNCTION
SUB CreateAndroidProject_AddDir (code AS STRING, dir AS STRING)
'mkdir("subfolder",0770);
code = code + "mkdir(" + CHR$(34) + CreateAndroidProject_PathReference$(dir) + CHR$(34) + ",0770);" + CHR$(13) + CHR$(10)
END SUB
SUB CreateAndroidProject_AddFile (code AS STRING, file AS STRING)
'android_get_file_asset(mgr, "subfolder/subfolderfile.txt");
code = code + "android_get_file_asset(mgr," + CHR$(34) + CreateAndroidProject_PathReference$(file) + CHR$(34) + ");" + CHR$(13) + CHR$(10)
END SUB
SUB CreateAndroidProject (projectName2 AS STRING)
'sanitise project name
dim projectName as string
for projectNameI=1 to len(projectName2)
projectNameA$=LCASE$(mid$(projectName2,projectNameI,1))
projectNameAsc=ASC(projectNameA$)
projectNameAValid=0
if projectNameAsc>=97 and projectNameAsc<122 then projectNameAValid=1
if len(projectName)>=1 then
if projectNameAsc>=48 and projectNameAsc<=57 then projectNameAValid=1
end if
if projectNameAValid then projectName=projectName+projectNameA$
next
if projectName="" then projectName="untitled"
projectVersion$ = "QB64_ANDROID_1.5"
DIM projectFolder AS STRING
DIM cFolder AS STRING
cFolder = "internal\c"
projectFolder = "programs\android\" + projectName
versionFile$ = projectFolder + "\qb64_android_version.txt"
sameVersion = 0
newProject = 1
IF _DIREXISTS(projectFolder) THEN
'check version
IF _FILEEXISTS(versionFile$) THEN
fh = FREEFILE
OPEN versionFile$ FOR INPUT AS #fh
LINE INPUT #fh, a$
IF a$ = projectVersion$ THEN sameVersion = 1: newProject = 0
CLOSE #fh
END IF
IF sameVersion = 0 THEN
'existing project incompatible, remove it
CreateAndroidProject_Message "Removing existing project"
SHELL _HIDE "cmd /c rmdir /s /q " + projectFolder
ELSE
CreateAndroidProject_Message "Updating existing project"
END IF
END IF
IF newProject THEN
CreateAndroidProject_Message "Creating new project"
CreateAndroidProject_Message "Copying project template"
IF _DIREXISTS(projectFolder) = 0 THEN MKDIR projectFolder
SHELL _HIDE "cmd /c xcopy /e programs\android\template\untitled\*.* " + projectFolder
'copy c folder (without unnecessary files)
CreateAndroidProject_Message "Copying C folder"
fh = FREEFILE
OPEN "internal\temp\xcopy_exclude.txt" FOR OUTPUT AS #fh
PRINT #fh, "c_compiler\"
PRINT #fh, "os\"
PRINT #fh, "download\"
PRINT #fh, ".bat"
PRINT #fh, ".command"
PRINT #fh, ".sh"
PRINT #fh, ".o"
PRINT #fh, ".a"
PRINT #fh, ".lib"
PRINT #fh, ".txt"
PRINT #fh, ".bin"
CLOSE fh
SHELL _HIDE "cmd /c xcopy /e /EXCLUDE:internal\temp\xcopy_exclude.txt " + cFolder + "\*.* " + projectFolder + "\app\src\main\jni\c"
'set version
fh = FREEFILE
OPEN versionFile$ FOR OUTPUT AS #fh
PRINT #fh, projectVersion$
CLOSE #fh
ELSE
CreateAndroidProject_Message "Cleaning project"
SHELL _HIDE "cmd /c del /q " + projectFolder + "\app\src\main\jni\temp\*.*" 'must be unindexed temp folder
'restore key files
CreateAndroidProject_Message "Restoring setting files"
CreateAndroidProject_RestoreFile "local.properties", projectFolder
CreateAndroidProject_RestoreFile "untitled.iml", projectFolder
CreateAndroidProject_RestoreFile ".idea\modules.xml", projectFolder
CreateAndroidProject_RestoreFile ".idea\name", projectFolder
CreateAndroidProject_RestoreFile "app\app.iml", projectFolder
CreateAndroidProject_RestoreFile "app\build.gradle", projectFolder
CreateAndroidProject_RestoreFile "add\src\main\AndroidManifest.xml", projectFolder
CreateAndroidProject_RestoreFile "app\src\main\res\values\strings.xml", projectFolder
END IF
CreateAndroidProject_Message "Copying TEMP" + tempfolderindexstr2 + " (program source files) folder"
SHELL _HIDE "cmd /c copy internal\temp" + tempfolderindexstr2 + "\*.txt " + projectFolder + "\app\src\main\jni\temp" 'indexed to unindexed
'remove unrequired files
delStr$ = "cmd /c del /q " + projectFolder + "\app\src\main\jni\temp\"
SHELL _HIDE delStr$ + "xcopy_exclude.txt"
SHELL _HIDE delStr$ + "root.txt"
SHELL _HIDE delStr$ + "paths.txt"
SHELL _HIDE delStr$ + "files.txt"
'prepend fullscreen directive to main.txt
CreateAndroidProject_Message "Prepending _FULLSCREEN _SQUAREPIXELS directive"
thisFile$ = projectFolder + "\app\src\main\jni\temp\main.txt"
fh = FREEFILE
OPEN thisFile$ FOR BINARY AS #fh
a$ = SPACE$(LOF(fh))
GET #fh, , a$
CLOSE #fh
KILL thisFile$
OPEN thisFile$ FOR BINARY AS #fh
a2$ = "sub__fullscreen( 3 ,0);"
PUT #1, , a2$
PUT #1, , a$
CLOSE #fh
CreateAndroidProject_Message "Updating project references"
fh = FREEFILE
OPEN projectFolder + "\local.properties" FOR OUTPUT AS #fh
PRINT #fh, "sdk.dir=" + CreateAndroidProject_EscapeFileName$(CreateAndroidProject_GetSdkPath$, 1)
PRINT #fh, "ndk.dir=" + CreateAndroidProject_EscapeFileName$(CreateAndroidProject_GetNdkPath$, 1)
CLOSE #fh
IF _FILEEXISTS(projectFolder + "\" + projectName$ + ".iml") THEN KILL projectFolder + "\" + projectName$ + ".iml"
NAME projectFolder + "\untitled.iml" AS projectFolder + "\" + projectName$ + ".iml"
CreateAndroidProject_ReplaceInFile projectFolder + "\.idea\modules.xml", "untitled", projectName$
CreateAndroidProject_ReplaceInFile projectFolder + "\.idea\gradle.xml", "$QB64_GRADLE_HOME$", CreateAndroidProject_GetGradlePath$
CreateAndroidProject_ReplaceInFile projectFolder + "\.idea\.name", "untitled", projectName$
CreateAndroidProject_ReplaceInFile projectFolder + "\app\app.iml", "untitled", projectName$
CreateAndroidProject_ReplaceInFile projectFolder + "\app\build.gradle", "untitled", projectName$
CreateAndroidProject_ReplaceInFile projectFolder + "\app\build.gradle", "$QB64_NDK_BUILD_CMD_FILE$", CreateAndroidProject_EscapeFileName$(CreateAndroidProject_GetNdkPath$, 2) + "\\ndk-build.cmd"
CreateAndroidProject_ReplaceInFile projectFolder + "\app\src\main\AndroidManifest.xml", "untitled", projectName$
CreateAndroidProject_ReplaceInFile projectFolder + "\app\src\main\res\values\strings.xml", "untitled", projectName$
'REDIM SHARED installFiles(0) AS STRING
'REDIM SHARED installFilesIn(0) AS STRING
'REDIM SHARED installFolder(0) AS STRING
'REDIM SHARED installFolderIn(0) AS STRING
'IF idemode THEN basPath$ = idepath$ + pathsep$ ELSE basPath$ = getfilepath$(sourcefile$)
'IF LEN(basPath$) > 0 THEN
' IF RIGHT$(basPath$, 1) = "/" OR RIGHT$(basPath$, 1) = "\" THEN basPath$ = LEFT$(basPath$, LEN(basPath$) - 1)
'END IF
'IF basPath$ = "" THEN basPath$ = "."
'to prevent misunderstanding files will first be moved to an isolation folder
'this isolation folder will be destroyed after work is completed
'create empty assets folder
DO WHILE _DIREXISTS(projectFolder + "\app\src\main\assets") 'just by waiting this problem can sometimes be resolved automatically
CreateAndroidProject_Message "Waiting to clean open/locked folder '" + projectFolder + "\app\src\main\assets'..."
_LIMIT 10
SHELL _HIDE "cmd /c rmdir /s /q " + projectFolder + "\app\src\main\assets"
LOOP
MKDIR projectFolder + "\app\src\main\assets" 'may fail if assets folder is open/locked and this folder MUST be empty before continuing
dirCode$ = ""
fileCode$ = ""
CreateAndroidProject_Message "Adding $INSTALLFOLDER(s)"
FOR f = 1 TO AryLastStr(installFolder())
p$ = installFolder(f)
'IF idemode THEN basPath$ = idepath$ + pathsep$ ELSE basPath$ = getfilepath$(sourcefile$)
'IF LEN(basPath$) > 0 THEN
' IF RIGHT$(basPath$, 1) = "/" OR RIGHT$(basPath$, 1) = "\" THEN basPath$ = LEFT$(basPath$, LEN(basPath$) - 1)
'END IF
'IF basPath$ = "" THEN basPath$ = "."
basPath$ = installFolderSourceLocation(f)
IF LEN(basPath$) > 0 THEN
IF RIGHT$(basPath$, 1) = "/" OR RIGHT$(basPath$, 1) = "\" THEN basPath$ = LEFT$(basPath$, LEN(basPath$) - 1)
END IF
IF basPath$ = "" THEN basPath$ = "."
path$ = basPath$
IF p$ <> "" THEN path$ = path$ + "\" + p$
'purge temp_assets
IF _DIREXISTS(projectFolder + "\temp_assets") THEN SHELL _HIDE "cmd /c rmdir /s /q " + projectFolder + "\temp_assets"
MKDIR projectFolder + "\temp_assets"
'copy to temp_assets
SHELL _HIDE "cmd /c xcopy /e " + CHR$(34) + path$ + CHR$(34) + " " + projectFolder + "\temp_assets"
'files are now isolated in a known folder which makes path stripping easier
p$ = installFolderIn(f)
destPath$ = projectFolder$ + "\app\src\main\assets"
'build dest path (it may not exist)
tp$ = p$
ii = 0
DO WHILE INSTR(ii, tp$, "\")
i = INSTR(ii, tp$, "\")
IF i THEN
tp2$ = LEFT$(tp$, i - 1)
ii = i + 1
d$ = destPath$ + "\" + tp2$
IF _DIREXISTS(d$) = 0 THEN
MKDIR d$
CreateAndroidProject_AddDir dirCode$, tp2$
END IF
END IF
LOOP
tp2$ = tp$
IF tp2$ <> "" THEN
d$ = destPath$ + "\" + tp2$
IF _DIREXISTS(d$) = 0 THEN
MKDIR d$
CreateAndroidProject_AddDir dirCode$, tp2$
END IF
END IF
IF p$ <> "" THEN destPath$ = destPath$ + "\" + p$
androidPath$ = p$
IF LEN(androidPath$) <> 0 THEN androidPath$ = androidPath$ + "/"
'generate file listing
'PRINT "cmd /c dir /s /b " + projectFolder + "\temp_assets\*.* >internal\temp\files.txt"
SHELL _HIDE "cmd /c dir /s /b " + projectFolder + "\temp_assets\*.* >internal\temp\files.txt"
OPEN "internal\temp\files.txt" FOR INPUT AS #fh
DO UNTIL EOF(fh)
LINE INPUT #fh, f$
'will include files and folders
i = INSTR(f$, "\temp_assets\")
lf$ = androidPath$ + RIGHT$(f$, LEN(f$) - i - 12)
IF _DIREXISTS(f$) THEN
'it's a folder
'** add necessary code for building a folder **
CreateAndroidProject_AddDir dirCode$, lf$
ELSE
'it's a file
'** add necessary code importing an asset file **
CreateAndroidProject_AddFile fileCode$, lf$
END IF
LOOP
CLOSE #fh
'copy to assets folder app\src\main\assets
SHELL _HIDE "cmd /c xcopy /e " + projectFolder + "\temp_assets " + CHR$(34) + destPath$ + CHR$(34)
NEXT
CreateAndroidProject_Message "Adding $INSTALLFILES"
FOR f = 1 TO AryLastStr(installFiles())
p$ = installFiles(f)
basPath$ = installFilesSourceLocation(f)
IF LEN(basPath$) > 0 THEN
IF RIGHT$(basPath$, 1) = "/" OR RIGHT$(basPath$, 1) = "\" THEN basPath$ = LEFT$(basPath$, LEN(basPath$) - 1)
END IF
IF basPath$ = "" THEN basPath$ = "."
path$ = basPath$
IF p$ <> "" THEN path$ = path$ + "\" + p$
'purge temp_assets
IF _DIREXISTS(projectFolder + "\temp_assets") THEN SHELL _HIDE "cmd /c rmdir /s /q " + projectFolder + "\temp_assets"
MKDIR projectFolder + "\temp_assets"
'copy to temp_assets
SHELL _HIDE "cmd /c copy " + CHR$(34) + path$ + CHR$(34) + " " + projectFolder + "\temp_assets"
'files are now isolated in a known folder which makes path stripping easier
p$ = installFilesIn(f)
destPath$ = projectFolder$ + "\app\src\main\assets"
'build dest path (it may not exist)
tp$ = p$
ii = 0
DO WHILE INSTR(ii, tp$, "\")
i = INSTR(ii, tp$, "\")
IF i THEN
tp2$ = LEFT$(tp$, i - 1)
ii = i + 1
d$ = destPath$ + "\" + tp2$
IF _DIREXISTS(d$) = 0 THEN
MKDIR d$
CreateAndroidProject_AddDir dirCode$, tp2$
END IF
END IF
LOOP
tp2$ = tp$
IF tp2$ <> "" THEN
d$ = destPath$ + "\" + tp2$
IF _DIREXISTS(d$) = 0 THEN
MKDIR d$
CreateAndroidProject_AddDir dirCode$, tp2$
END IF
END IF
IF p$ <> "" THEN destPath$ = destPath$ + "\" + p$
androidPath$ = p$
IF LEN(androidPath$) <> 0 THEN androidPath$ = androidPath$ + "/"
'generate file listing
'PRINT "cmd /c dir /s /b " + projectFolder + "\temp_assets\*.* >internal\temp\files.txt"
SHELL _HIDE "cmd /c dir /s /b " + projectFolder + "\temp_assets\*.* >internal\temp\files.txt"
OPEN "internal\temp\files.txt" FOR INPUT AS #fh
DO UNTIL EOF(fh)
LINE INPUT #fh, f$
'will include files and folders
i = INSTR(f$, "\temp_assets\")
lf$ = androidPath$ + RIGHT$(f$, LEN(f$) - i - 12)
IF _DIREXISTS(f$) THEN
'it's a folder
'must be ignored
ELSE
'it's a file
'** add necessary code importing an asset file **
CreateAndroidProject_AddFile fileCode$, lf$
END IF
LOOP
CLOSE #fh
'copy to assets folder app\src\main\assets
SHELL _HIDE "cmd /c copy " + projectFolder + "\temp_assets\*.* " + CHR$(34) + destPath$ + CHR$(34)
NEXT
'purge temp_assets
IF _DIREXISTS(projectFolder + "\temp_assets") THEN SHELL _HIDE "cmd /c rmdir /s /q " + projectFolder + "\temp_assets"
OPEN projectFolder + "\app\src\main\jni\temp\assets.txt" FOR OUTPUT AS #1
PRINT #1, dirCode$
PRINT #1, fileCode$
CLOSE #1
'mkdir("subfolder",0770);
'android_get_file_asset(mgr, "subfolder/subfolderfile.txt");
CreateAndroidProject_Message "Android project generation complete"
END SUB