diff --git a/internal/c/common.cpp b/internal/c/common.cpp index 8147de594..72e44547c 100644 --- a/internal/c/common.cpp +++ b/internal/c/common.cpp @@ -73,6 +73,9 @@ #define int64 __int64 #endif +//#include +#include + #include #include @@ -92,7 +95,7 @@ #include #include #include -#include + //OS/compiler specific includes #ifdef QB64_WINDOWS @@ -435,7 +438,23 @@ struct device_struct{ int32 balls; int32 hats; }; + +//device_struct constants #define QUEUED_EVENTS_LIMIT 1024 +#define DEVICETYPE_CONTROLLER 1 +#define DEVICETYPE_KEYBOARD 2 +#define DEVICETYPE_MOUSE 3 + + + + + + + + + + + struct mem_block{ ptrszint offset; diff --git a/internal/c/libqb.cpp b/internal/c/libqb.cpp index 744bb408f..e58559cc9 100644 --- a/internal/c/libqb.cpp +++ b/internal/c/libqb.cpp @@ -52,6 +52,7 @@ #ifdef QB64_WINDOWS +#include #include #endif @@ -1165,7 +1166,9 @@ int32 mem_lock_freed_max=1000;//number of allocated entries int32 mem_lock_freed_n=0;//number of entries ptrszint *mem_lock_freed=(ptrszint*)malloc(sizeof(ptrszint)*mem_lock_freed_max); -inline void new_mem_lock(){ +//inline removed because it is incompatible with Android studio x86 build + +void new_mem_lock(){ if (mem_lock_freed_n){ mem_lock_tmp=(mem_lock*)mem_lock_freed[--mem_lock_freed_n]; }else{ @@ -1175,7 +1178,7 @@ inline void new_mem_lock(){ mem_lock_tmp->id=++mem_lock_id; } -inline void free_mem_lock(mem_lock *lock){ +void free_mem_lock(mem_lock *lock){ lock->id=0;//invalidate lock if (lock->type==1) free(lock->offset);//malloc type //add to freed list @@ -1270,6 +1273,18 @@ extern int32 device_last; extern int32 device_max; extern device_struct *devices; +extern uint8 getDeviceEventButtonValue(device_struct *device, int32 eventIndex, int32 objectIndex); +extern void setDeviceEventButtonValue(device_struct *device, int32 eventIndex, int32 objectIndex, uint8 value); +extern float getDeviceEventAxisValue(device_struct *device, int32 eventIndex, int32 objectIndex); +extern void setDeviceEventAxisValue(device_struct *device, int32 eventIndex, int32 objectIndex, float value); +extern float getDeviceEventWheelValue(device_struct *device, int32 eventIndex, int32 objectIndex); +extern void setDeviceEventWheelValue(device_struct *device, int32 eventIndex, int32 objectIndex, float value); +extern void setupDevice(device_struct *device); +extern int32 createDeviceEvent(device_struct *device); +extern void commitDeviceEvent(device_struct *device); + + + extern ontimer_struct *ontimer; extern onkey_struct *onkey; extern int32 onkey_inprogress; @@ -7414,6 +7429,7 @@ extern uint8 *mem_static_pointer; extern uint8 *mem_static_limit; uint8 *mem_static_malloc(uint32 size){ + size+=7; size-=(size&7);//align to 8 byte boundry if ((mem_static_pointer+=size)type==1){ if (i==i2){ if (axislastaxis){ - f=*(float*)(d->events+(d->event_size*(d->queued_events-1))+d->lastbutton+axis*4); + f=getDeviceEventAxisValue(d,d->queued_events-1,axis); if (f>-0.01&&f<=0.01) f=0; v=qbr_float_to_long(f*127.0)+127; if (v>254) v=254; @@ -28716,7 +28732,7 @@ void sub__maptriangle(int32 cull_options,float sx1,float sy1,float sx2,float sy2 return 0; }else{ //method 2: currently down - v=*(d->events+(d->event_size*(d->queued_events-1))+(button-1)); + v=getDeviceEventButtonValue(d,d->queued_events-1,button-1); if (v) return -1; else return 0; } }//button exists @@ -29474,6 +29490,155 @@ qbs *func__startdir(){ return temp; } +qbs *rootDir=NULL;//the dir moved to when program begins + +char *android_dir_downloads=NULL; +char *android_dir_documents=NULL; +char *android_dir_pictures=NULL; +char *android_dir_music=NULL; +char *android_dir_video=NULL; +char *android_dir_dcim=NULL; + +qbs *func__dir(qbs* context_in){ + + static qbs *context=NULL; + if (!context){context=qbs_new(0,0);} + + qbs_set(context,qbs_ucase(context_in)); + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("TEXT"))||qbs_equal(qbs_ucase(context),qbs_new_txt("DOCUMENT"))||qbs_equal(qbs_ucase(context),qbs_new_txt("DOCUMENTS"))||qbs_equal(qbs_ucase(context),qbs_new_txt("MY DOCUMENTS"))){ + #ifdef QB64_ANDROID + mkdir(android_dir_documents,0770); + return qbs_new_txt(android_dir_documents); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,5,NULL,0,osPath))){ //Documents + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("MUSIC"))||qbs_equal(qbs_ucase(context),qbs_new_txt("AUDIO"))||qbs_equal(qbs_ucase(context),qbs_new_txt("SOUND"))||qbs_equal(qbs_ucase(context),qbs_new_txt("SOUNDS"))||qbs_equal(qbs_ucase(context),qbs_new_txt("MY MUSIC"))){ + #ifdef QB64_ANDROID + mkdir(android_dir_music,0770); + return qbs_new_txt(android_dir_music); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,13,NULL,0,osPath))){ //Music + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("PICTURE"))||qbs_equal(qbs_ucase(context),qbs_new_txt("PICTURES"))||qbs_equal(qbs_ucase(context),qbs_new_txt("IMAGE"))||qbs_equal(qbs_ucase(context),qbs_new_txt("IMAGES"))||qbs_equal(qbs_ucase(context),qbs_new_txt("MY PICTURES"))){ + #ifdef QB64_ANDROID + mkdir(android_dir_pictures,0770); + return qbs_new_txt(android_dir_pictures); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,39,NULL,0,osPath))){//Pictures + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("DCIM"))||qbs_equal(qbs_ucase(context),qbs_new_txt("CAMERA"))||qbs_equal(qbs_ucase(context),qbs_new_txt("CAMERA ROLL"))||qbs_equal(qbs_ucase(context),qbs_new_txt("PHOTO"))||qbs_equal(qbs_ucase(context),qbs_new_txt("PHOTOS"))){ + #ifdef QB64_ANDROID + mkdir(android_dir_dcim,0770); + return qbs_new_txt(android_dir_dcim); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,39,NULL,0,osPath))){//Pictures + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("MOVIE"))||qbs_equal(qbs_ucase(context),qbs_new_txt("MOVIES"))||qbs_equal(qbs_ucase(context),qbs_new_txt("VIDEO"))||qbs_equal(qbs_ucase(context),qbs_new_txt("VIDEOS"))||qbs_equal(qbs_ucase(context),qbs_new_txt("MY VIDEOS"))){ + #ifdef QB64_ANDROID + mkdir(android_dir_video,0770); + return qbs_new_txt(android_dir_video); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,14,NULL,0,osPath))){ //Videos + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("DOWNLOAD"))||qbs_equal(qbs_ucase(context),qbs_new_txt("DOWNLOADS"))){ + #ifdef QB64_ANDROID + mkdir(android_dir_downloads,0770); + return qbs_new_txt(android_dir_downloads); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,0x0028,NULL,0,osPath))){//user folder + //XP & SHGetFolderPathA do not support the concept of a Downloads folder, however it can be constructed + mkdir((char*)((qbs_add(qbs_new_txt(osPath),qbs_new_txt_len("\\Downloads\0",11)))->chr)); + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\Downloads\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("DESKTOP"))){ + #ifdef QB64_ANDROID + mkdir(android_dir_downloads,0770); + return qbs_new_txt(android_dir_downloads); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,0,NULL,0,osPath))){ //Desktop + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("APPDATA"))||qbs_equal(qbs_ucase(context),qbs_new_txt("APPLICATION DATA"))||qbs_equal(qbs_ucase(context),qbs_new_txt("PROGRAM DATA"))||qbs_equal(qbs_ucase(context),qbs_new_txt("DATA"))){ + #ifdef QB64_ANDROID + return qbs_add(rootDir,qbs_new_txt("/")); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,0x001a,NULL,0,osPath))){ //CSIDL_APPDATA (%APPDATA%) + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + if (qbs_equal(qbs_ucase(context),qbs_new_txt("LOCALAPPDATA"))||qbs_equal(qbs_ucase(context),qbs_new_txt("LOCAL APPLICATION DATA"))||qbs_equal(qbs_ucase(context),qbs_new_txt("LOCAL PROGRAM DATA"))||qbs_equal(qbs_ucase(context),qbs_new_txt("LOCAL DATA"))){ + #ifdef QB64_ANDROID + return qbs_add(rootDir,qbs_new_txt("/")); + #endif + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,0x001c,NULL,0,osPath))){ //CSIDL_LOCAL_APPDATA (%LOCALAPPDATA%) + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + #endif + } + + //general fallback location + #ifdef QB64_WINDOWS + CHAR osPath[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPathA(NULL,0,NULL,0,osPath))){ //desktop + return qbs_add(qbs_new_txt(osPath),qbs_new_txt("\\")); + } + return qbs_new_txt(".\\");//current location + #else + #ifdef QB64_ANDROID + mkdir(android_dir_downloads,0770); + return qbs_new_txt(android_dir_downloads); + #endif + return qbs_new_txt("./");//current location + #endif +} + extern void set_dynamic_info(); @@ -29519,7 +29684,6 @@ qbs *func__startdir(){ env->ReleaseStringUTFChars( jpath, app_dir); // Pre-extract assets, to avoid Android-specific file opening - AAssetManager* mgr = app->activity->assetManager; /* Old code which pulled all root directory assets, in QB64 assets are specified in code so this just wastes time @@ -29533,13 +29697,78 @@ qbs *func__startdir(){ #include "../temp/assets.txt" + //get _DIR$(...) paths + {//upscope + + jfieldID fieldId; + jclass envClass = env->FindClass("android/os/Environment"); + char** targetString; + jstring jstrParam; + char* s; + jstring sType; + for (int i=1;i<=6;i++){ + + if (i==1){ + targetString=&android_dir_dcim; + fieldId=env->GetStaticFieldID(envClass, "DIRECTORY_DCIM", "Ljava/lang/String;"); + } + if (i==2){ + targetString=&android_dir_downloads; + fieldId=env->GetStaticFieldID(envClass, "DIRECTORY_DOWNLOADS", "Ljava/lang/String;"); + } + if (i==3){ + targetString=&android_dir_documents; + fieldId=env->GetStaticFieldID(envClass, "DIRECTORY_DOCUMENTS", "Ljava/lang/String;"); + } + if (i==4){ + targetString=&android_dir_pictures; + fieldId=env->GetStaticFieldID(envClass, "DIRECTORY_PICTURES", "Ljava/lang/String;"); + } + if (i==5){ + targetString=&android_dir_music; + fieldId=env->GetStaticFieldID(envClass, "DIRECTORY_MUSIC", "Ljava/lang/String;"); + } + if (i==6){ + targetString=&android_dir_video; + fieldId=env->GetStaticFieldID(envClass, "DIRECTORY_MOVIES", "Ljava/lang/String;"); + } + + + //retrieve jstring representation of environment variable + jstrParam = (jstring)env->GetStaticObjectField(envClass, fieldId); + s = env->GetStringUTFChars(jstrParam, NULL); + LOGI("String name of Environment.Variable: %s", s); + env->ReleaseStringUTFChars(jstrParam, s); + + //use jstring representation to retrieve folder name + sType=jstrParam; + jmethodID midEnvironmentGetExternalStoragePublicDirectory = env->GetStaticMethodID(envClass, "getExternalStoragePublicDirectory", "(Ljava/lang/String;)Ljava/io/File;"); + jobject oExternalStorageDirectory = NULL; + oExternalStorageDirectory = env->CallStaticObjectMethod(envClass, midEnvironmentGetExternalStoragePublicDirectory, sType); + jclass cFile = env->GetObjectClass(oExternalStorageDirectory); + jmethodID midFileGetAbsolutePath = env->GetMethodID(cFile, "getAbsolutePath", "()Ljava/lang/String;"); + env->DeleteLocalRef(cFile); + jstring extStoragePath = (jstring)env->CallObjectMethod(oExternalStorageDirectory, midFileGetAbsolutePath); + const char* extStoragePathString = env->GetStringUTFChars(extStoragePath, NULL); + LOGI("Path: %s", extStoragePathString);// /storage/emulated/0/Download + + *targetString=(char*)calloc(1,strlen(extStoragePathString)+2); + memcpy(*targetString,extStoragePathString,strlen(extStoragePathString)); + (*targetString)[strlen(extStoragePathString)]=47;//append "/" + + env->ReleaseStringUTFChars(extStoragePath, extStoragePathString); + env->DeleteLocalRef(sType); + } + + }//downscope + + + //JavaVMAttachArgs args = { JNI_VERSION_1_6, NULL, NULL }; //vm->AttachCurrentThread( &env, &args ); -//not sure why we do this... - //jmethodID activityConstructor = env->GetMethodID(app->activity->clazz, "", "()V"); //jobject object = env->NewObject(app->activity->clazz, activityConstructor); @@ -29968,6 +30197,9 @@ qbs_set(startDir,func__cwd()); #endif #endif +rootDir=qbs_new(0,0); +qbs_set(rootDir,func__cwd()); + unknown_opcode_mess=qbs_new(0,0); qbs_set(unknown_opcode_mess,qbs_new_txt_len("Unknown Opcode ( )\0",20)); @@ -30324,39 +30556,27 @@ qbs_set(startDir,func__cwd()); -//Init _DEVICEs -i=1; +//setup default _DEVICE(s) +i=0; + //keyboard -devices[i].type=2; +i++; +devices[i].type=DEVICETYPE_KEYBOARD; devices[i].name="[KEYBOARD][BUTTON]"; devices[i].lastbutton=512; -//calculate queue message size -x=512+8; -devices[i].event_size=x; -//create initial 'current' and 'previous' events -devices[i].events=(uint8*)calloc(2,x); -devices[i].max_events=2; -devices[i].queued_events=2; -devices[i].connected=1; -devices[i].used=1; devices[i].description="Keyboard"; -i++; +setupDevice(&devices[i]); + //mouse -devices[i].type=3; +i++; +devices[i].type=DEVICETYPE_MOUSE; devices[i].name="[MOUSE][BUTTON][AXIS][WHEEL]"; devices[i].lastbutton=3; devices[i].lastaxis=2; devices[i].lastwheel=3; -//calculate queue message size -x=devices[i].lastbutton+devices[i].lastaxis*4+devices[i].lastwheel*4+8; -devices[i].event_size=x; -//create initial 'current' and 'previous' events -devices[i].events=(uint8*)calloc(2,x); -devices[i].max_events=2; -devices[i].queued_events=2; -devices[i].connected=1; -devices[i].used=1; devices[i].description="Mouse"; +setupDevice(&devices[i]); + device_last=i; @@ -32938,29 +33158,14 @@ QB64_GAMEPAD_INIT(); keydown_special: static device_struct *d; d=&devices[1];//keyboard - if (*(d->events+((d->queued_events-1)*d->event_size)+code)!=1){//don't add message if already on - uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=(QUEUED_EVENTS_LIMIT/4)){//note: default event limit divied by 4 - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+code)=1; - if (special==2){special=1; d->queued_events++; goto keydown_special;} - if (special==1) *(d->events+(d->queued_events*d->event_size)+code)=0; - d->queued_events++; + if (getDeviceEventButtonValue(d,d->queued_events-1,code)!=1){//don't add message if already on + + int32 eventIndex=createDeviceEvent(d); + setDeviceEventButtonValue(d,eventIndex,code,1); + if (special==2){special=1; commitDeviceEvent(d); goto keydown_special;}//jump to ~5 lines above to add a 2nd key event + if (special==1) setDeviceEventButtonValue(d,eventIndex,code,0); + commitDeviceEvent(d); + }//not 1 }//core devices required @@ -32982,27 +33187,12 @@ QB64_GAMEPAD_INIT(); static device_struct *d; d=&devices[1];//keyboard - if (*(d->events+((d->queued_events-1)*d->event_size)+code)!=0){//don't add message if already on - uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=(QUEUED_EVENTS_LIMIT/4)){//note: default event limit divied by 4 - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+code)=0; - d->queued_events++; + if (getDeviceEventButtonValue(d,d->queued_events-1,code)!=0){//don't add message if already off + + int32 eventIndex=createDeviceEvent(d); + setDeviceEventButtonValue(d,eventIndex,code,0); + commitDeviceEvent(d); + }//not 1 }//core devices required @@ -33311,4 +33501,4 @@ sub__limit( 10 ); sub__display(); }while(1); //infinite loop (this function never exits) -} +} \ No newline at end of file diff --git a/internal/c/libqb/gui.cpp b/internal/c/libqb/gui.cpp index 00d1aff2e..27e210c1e 100644 --- a/internal/c/libqb/gui.cpp +++ b/internal/c/libqb/gui.cpp @@ -1950,26 +1950,11 @@ if (src_hardware_img->source_state.PO2_fix){ button--; static device_struct *d; d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+button)=0; - d->queued_events++; + + int32 eventIndex=createDeviceEvent(d); + setDeviceEventButtonValue(d,eventIndex,button,0); + commitDeviceEvent(d); + }//valid range }//core devices required @@ -2010,26 +1995,11 @@ if (src_hardware_img->source_state.PO2_fix){ button--; static device_struct *d; d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+button)=1; - d->queued_events++; + + int32 eventIndex=createDeviceEvent(d); + setDeviceEventButtonValue(d,eventIndex,button,1); + commitDeviceEvent(d); + //1-3 }else{ //not 1-3 @@ -2039,45 +2009,15 @@ if (src_hardware_img->source_state.PO2_fix){ if (button==4) f=-1; else f=1; static device_struct *d; d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+(3-1)*4)=f; - d->queued_events++; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+(3-1)*4)=0; - d->queued_events++; + + int32 eventIndex=createDeviceEvent(d); + setDeviceEventWheelValue(d,eventIndex,2,f); + commitDeviceEvent(d); + + eventIndex=createDeviceEvent(d); + setDeviceEventWheelValue(d,eventIndex,2,0); + commitDeviceEvent(d); + }//4-5 }//not 1-3 }//core devices required @@ -2132,25 +2072,8 @@ if (src_hardware_img->source_state.PO2_fix){ if (!device_mouse_relative){ static device_struct *d; d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes + int32 eventIndex=createDeviceEvent(d); static float fx,fy; static int32 z; fx=x; @@ -2169,59 +2092,30 @@ if (src_hardware_img->source_state.PO2_fix){ fy=fy/(float)(z-1);//0 to 1 fy*=2.0;//0 to 2 fy-=1.0;//-1 to 1 - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton)=fx; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+4)=fy; - d->queued_events++; + setDeviceEventAxisValue(d,eventIndex,0,fx); + setDeviceEventAxisValue(d,eventIndex,1,fy); + commitDeviceEvent(d); + }else{ static device_struct *d; d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes + + int32 eventIndex=createDeviceEvent(d); static float fx,fy; static int32 z; fx=xrel; fy=yrel; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4)=fx; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+4)=fy; - d->queued_events++; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes + setDeviceEventWheelValue(d,eventIndex,0,fx); + setDeviceEventWheelValue(d,eventIndex,1,fy); + commitDeviceEvent(d); + + eventIndex=createDeviceEvent(d); fx=0; fy=0; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4)=fx; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+4)=fy; - d->queued_events++; + setDeviceEventWheelValue(d,eventIndex,0,fx); + setDeviceEventWheelValue(d,eventIndex,1,fy); + commitDeviceEvent(d); + } }//core devices required } diff --git a/internal/c/parts/input/game_controller/src.c b/internal/c/parts/input/game_controller/src.c index 9f34cef36..f80a0e2e4 100644 --- a/internal/c/parts/input/game_controller/src.c +++ b/internal/c/parts/input/game_controller/src.c @@ -73,26 +73,10 @@ void onButtonDown(struct Gamepad_device * device, unsigned int buttonID, double } }//within supported range - uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+button)=1; - d->queued_events++; + int32 eventIndex=createDeviceEvent(d); + setDeviceEventButtonValue(d,eventIndex,button,1); + commitDeviceEvent(d); + //set STRIG_button_pressed for button if (button>=0&&button<=255){ d->STRIG_button_pressed[button]=1; @@ -120,26 +104,11 @@ void onButtonUp(struct Gamepad_device * device, unsigned int buttonID, double ti if (d->used==1){ if (d->type==1){ if (d->handle_int==device->deviceID){ - uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+button)=0; - d->queued_events++; + + int32 eventIndex=createDeviceEvent(d); + setDeviceEventButtonValue(d,eventIndex,button,0); + commitDeviceEvent(d); + }//js index }//type==1 }//used @@ -163,24 +132,7 @@ void onAxisMoved(struct Gamepad_device * device, unsigned int axisID, float valu if (d->used==1){ if (d->type==1){ if (d->handle_int==device->deviceID){ - uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes + float f; f=value; /* @@ -189,10 +141,11 @@ void onAxisMoved(struct Gamepad_device * device, unsigned int axisID, float valu */ if (f>1.0) f=1.0; if (f<-1.0) f=-1.0; - int32 o; - o=d->lastbutton+axis*4; - *(float*)(d->events+(d->queued_events*d->event_size)+o)=f; - d->queued_events++; + + int32 eventIndex=createDeviceEvent(d); + setDeviceEventAxisValue(d,eventIndex,axis,f); + commitDeviceEvent(d); + }//js index }//type==1 }//used @@ -248,7 +201,7 @@ if (i>device_max){ device_max*=2; } memset(&devices[i],0,sizeof(device_struct)); -devices[i].type=1; +devices[i].type=DEVICETYPE_CONTROLLER; devices[i].description=strdup(device->description); devices[i].handle_int=device->deviceID; devices[i].buttons=device->numButtons; @@ -265,15 +218,9 @@ if (devices[i].lastbutton) strcat (name,"[BUTTON]"); if (devices[i].lastaxis) strcat (name,"[AXIS]"); if (devices[i].lastwheel) strcat (name,"[WHEEL]"); devices[i].name=strdup(name); -//calculate queue message size -x=devices[i].lastbutton+(devices[i].lastaxis+devices[i].lastwheel)*4+8; -devices[i].event_size=x; -//create initial 'current' and 'previous' events -devices[i].events=(uint8*)calloc(2,x); -devices[i].max_events=2; -devices[i].queued_events=2; -devices[i].connected=1; -devices[i].used=1; + +setupDevice(&devices[i]); + device_last=i; } diff --git a/internal/c/qbx.cpp b/internal/c/qbx.cpp index 147788f0b..d6cfad84a 100644 --- a/internal/c/qbx.cpp +++ b/internal/c/qbx.cpp @@ -122,6 +122,9 @@ void requestKeyboardOverlayImage(int32 handle){ //extern functions +extern qbs *func__dir(qbs* context); + + extern int32 func__scaledwidth(); extern int32 func__scaledheight(); @@ -1398,6 +1401,64 @@ int32 device_last=0;//last used device int32 device_max=1000;//number of allocated indexes device_struct *devices=(device_struct*)calloc(1000+1,sizeof(device_struct)); +//device_struct helper functions +uint8 getDeviceEventButtonValue(device_struct *device, int32 eventIndex, int32 objectIndex){ + return *(device->events+eventIndex*device->event_size+device->lastaxis*4+device->lastwheel*4+objectIndex); +} +void setDeviceEventButtonValue(device_struct *device, int32 eventIndex, int32 objectIndex, uint8 value){ + *(device->events+eventIndex*device->event_size+device->lastaxis*4+device->lastwheel*4+objectIndex)=value; +} +float getDeviceEventAxisValue(device_struct *device, int32 eventIndex, int32 objectIndex){ + return *(float*)(device->events+eventIndex*device->event_size+objectIndex*4); +} +void setDeviceEventAxisValue(device_struct *device, int32 eventIndex, int32 objectIndex, float value){ + *(float*)(device->events+eventIndex*device->event_size+objectIndex*4)=value; +} +float getDeviceEventWheelValue(device_struct *device, int32 eventIndex, int32 objectIndex){ + return *(float*)(device->events+eventIndex*device->event_size+device->lastaxis*4+objectIndex*4); +} +void setDeviceEventWheelValue(device_struct *device, int32 eventIndex, int32 objectIndex, float value){ + *(float*)(device->events+eventIndex*device->event_size+device->lastaxis*4+objectIndex*4)=value; +} +void setupDevice(device_struct *device){ + int32 size=device->lastaxis*4+device->lastwheel*4+device->lastbutton; + size+=8;//for appended ordering index + size+=7; size=size-(size&7);//align to closest 8-byte boundary + device->event_size=size; + device->events=(uint8*)calloc(2,device->event_size);//create initial 'current' and 'previous' events + device->max_events=2; + device->queued_events=2; + device->connected=1; + device->used=1; +} +int32 createDeviceEvent(device_struct *device){ + uint8 *cp,*cp2; + if (device->queued_events==device->max_events){//expand/shift event buffer + if (device->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(device->events,device->events+device->event_size,(device->queued_events-1)*device->event_size); + device->queued_events--; + }else{ + cp=(uint8*)calloc(device->max_events*2,device->event_size);//create new buffer + memcpy(cp,device->events,device->queued_events*device->event_size);//copy events from old buffer into new buffer + cp2=device->events; + device->events=cp; + device->max_events*=2; + free(cp2); + } + } + //copy previous event data into new event + memmove(device->events+device->queued_events*device->event_size,device->events+(device->queued_events-1)*device->event_size,device->event_size); + *(int64*)(device->events+(device->queued_events*device->event_size)+(device->event_size-8))=device_event_index++;//set global event index + int32 eventIndex=device->queued_events; + return eventIndex; +} +void commitDeviceEvent(device_struct *device){ + device->queued_events++; +} + + + int32 func__devices(){ return device_last; } @@ -1458,7 +1519,7 @@ if (device_selected<1||device_selected>device_last){error(5); return 0;} static device_struct *d; d=&devices[device_selected]; if (!passed) i=1; if (i<1||i>d->lastbutton){error(5); return 0;} -if (*(d->events+d->event_size+(i-1))) return -1; +if (getDeviceEventButtonValue(d,1,i-1)) return -1; return 0; } @@ -1468,8 +1529,8 @@ static device_struct *d; d=&devices[device_selected]; if (!passed) i=1; if (i<1||i>d->lastbutton){error(5); return 0;} static int32 old_value,value; -value=*(d->events+d->event_size+(i-1)); -old_value=*(d->events+(i-1)); +value=getDeviceEventButtonValue(d,1,i-1); +old_value=getDeviceEventButtonValue(d,0,i-1); if (value>old_value) return -1; if (valuedevice_last){error(5); return 0;} static device_struct *d; d=&devices[device_selected]; if (!passed) i=1; if (i<1||i>d->lastaxis){error(5); return 0;} -return *(float*)(d->events+d->event_size+d->lastbutton+(i-1)*4); +return getDeviceEventAxisValue(d,1,i-1); } float func__wheel(int32 i,int32 passed){ @@ -1488,7 +1549,7 @@ if (device_selected<1||device_selected>device_last){error(5); return 0;} static device_struct *d; d=&devices[device_selected]; if (!passed) i=1; if (i<1||i>d->lastwheel){error(5); return 0;} -return *(float*)(d->events+d->event_size+d->lastbutton+d->lastaxis*4+(i-1)*4); +return getDeviceEventWheelValue(d,1,i-1); } int32 func__lastbutton(int32 di,int32 passed){ diff --git a/programs/android/template/untitled/app/src/main/AndroidManifest.xml b/programs/android/template/untitled/app/src/main/AndroidManifest.xml index 925598d60..cbce140ac 100644 --- a/programs/android/template/untitled/app/src/main/AndroidManifest.xml +++ b/programs/android/template/untitled/app/src/main/AndroidManifest.xml @@ -5,6 +5,9 @@ android:versionCode="1" android:versionName="1.0"> + + + diff --git a/programs/android/template/untitled/app/src/main/jni/Application.mk b/programs/android/template/untitled/app/src/main/jni/Application.mk index d3923e6c9..b35c97cf3 100644 --- a/programs/android/template/untitled/app/src/main/jni/Application.mk +++ b/programs/android/template/untitled/app/src/main/jni/Application.mk @@ -1,8 +1,12 @@ APP_PLATFORM := android-10 #APP_PLATFORM := android-9 -#APP_ABI := armeabi-v7a -APP_ABI := armeabi +#APP_ABI := armeabi +# Android 4+ (Ice Cream Sandwich) requires an ARMv7 processor. (Some custom versions of Android 4+ have been made for ARMv6) +# Therefore, there isn't much point producing armeabi binaries + +APP_ABI := armeabi-v7a +APP_ABI += x86 APP_STL := gnustl_static diff --git a/source/subs_functions/subs_functions.bas b/source/subs_functions/subs_functions.bas index a6296e193..9d5fdc6a8 100644 --- a/source/subs_functions/subs_functions.bas +++ b/source/subs_functions/subs_functions.bas @@ -2837,3 +2837,14 @@ id.subfunc = 1 id.callname = "func__startdir" id.ret = STRINGTYPE - ISPOINTER regid + +'Return a path that best represents the context provided e.g. _DIR$("DESKTOP") +clearid +id.n = "_DIR" +id.musthave = "$" +id.subfunc = 1 +id.callname = "func__dir" +id.args = 1 +id.arg = MKL$(STRINGTYPE - ISPOINTER) +id.ret = STRINGTYPE - ISPOINTER +regid