mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	Fixed Bugs & Joypad in Android
================================ -resolved many graphical glitches with multiple lights in GLES2 render -fixes and WIP apk expansion -joystick support for Android by Ariel
This commit is contained in:
		
							parent
							
								
									77a15e2a3e
								
							
						
					
					
						commit
						e9da61411a
					
				
					 8 changed files with 359 additions and 14 deletions
				
			
		|  | @ -4239,9 +4239,10 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD | |||
| 			LightInstance *li=light_instance_owner.get( liptr[i] ); | ||||
| 			if (!li || li->last_pass!=scene_pass) //lit by light not in visible scene
 | ||||
| 				continue; | ||||
| 			uint8_t light_type=li->base->type; | ||||
| 			if (li->base->shadow_enabled) | ||||
| 			uint8_t light_type=li->base->type|0x40; //penalty to ensure directionals always go first
 | ||||
| 			if (li->base->shadow_enabled) { | ||||
| 				light_type|=0x8; | ||||
| 			} | ||||
| 			uint16_t sort_key =li->sort_key; | ||||
| 
 | ||||
| 			RenderList::Element *ec; | ||||
|  | @ -4598,7 +4599,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material | |||
| 		material_shader.set_uniform(MaterialShaderGLES2::FOG_COLOR_END,Vector3(col_end.r,col_end.g,col_end.b)); | ||||
| 	} | ||||
| 
 | ||||
| 	material_shader.set_uniform(MaterialShaderGLES2::CONST_LIGHT_MULT,p_no_const_light?0.0:1.0); | ||||
| 
 | ||||
| 	//material_shader.set_uniform(MaterialShaderGLES2::TIME,Math::fmod(last_time,300.0));
 | ||||
| 	//if uses TIME - draw_next_frame=true
 | ||||
| 
 | ||||
|  | @ -5668,7 +5669,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans | |||
| 					 case VS::MATERIAL_BLEND_MODE_ADD: { | ||||
| 
 | ||||
| 						glBlendEquation(GL_FUNC_ADD); | ||||
| 						glBlendFunc(GL_SRC_ALPHA,GL_ONE); | ||||
| 						glBlendFunc(p_alpha_pass?GL_SRC_ALPHA:GL_ONE,GL_ONE); | ||||
| 
 | ||||
| 					 } break; | ||||
| 					 case VS::MATERIAL_BLEND_MODE_SUB: { | ||||
|  | @ -5833,7 +5834,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans | |||
| 		} | ||||
| 
 | ||||
| 		material_shader.set_uniform(MaterialShaderGLES2::NORMAL_MULT, e->mirror?-1.0:1.0); | ||||
| 
 | ||||
| 		material_shader.set_uniform(MaterialShaderGLES2::CONST_LIGHT_MULT,additive?0.0:1.0); | ||||
| 
 | ||||
| 
 | ||||
| 		_render(e->geometry, material, skeleton,e->owner,e->instance->transform); | ||||
|  | @ -6097,6 +6098,9 @@ void RasterizerGLES2::_draw_tex_bg() { | |||
| 	glDepthMask(GL_TRUE); | ||||
| 	glEnable(GL_DEPTH_TEST); | ||||
| 	glDisable(GL_CULL_FACE); | ||||
| 	glDisable(GL_BLEND); | ||||
| 	glColorMask(1,1,1,1); | ||||
| 
 | ||||
| 
 | ||||
| 	RID texture; | ||||
| 
 | ||||
|  | @ -6132,6 +6136,7 @@ void RasterizerGLES2::_draw_tex_bg() { | |||
| 
 | ||||
| 	copy_shader.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA,true); | ||||
| 
 | ||||
| 
 | ||||
| 	copy_shader.bind(); | ||||
| 
 | ||||
| 	if (current_env->bg_mode==VS::ENV_BG_TEXTURE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) { | ||||
|  | @ -6350,6 +6355,7 @@ void RasterizerGLES2::end_scene() { | |||
| 	_render_list_forward(&opaque_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting); | ||||
| 
 | ||||
| 	if (draw_tex_background) { | ||||
| 
 | ||||
| 		//most 3D vendors recommend drawing a texture bg or skybox here,
 | ||||
| 		//after opaque geometry has been drawn
 | ||||
| 		//so the zbuffer can get rid of most pixels
 | ||||
|  |  | |||
|  | @ -1060,7 +1060,19 @@ LIGHT_SHADER_CODE | |||
| 			light+=specular * light_specular * pow( eye_light, specular_exp ); | ||||
| 		} | ||||
| #endif | ||||
| 		diffuse.rgb = ambient_light *diffuse.rgb + light * attenuation * shadow_attenuation; | ||||
| 		diffuse.rgb = const_light_mult * ambient_light *diffuse.rgb + light * attenuation * shadow_attenuation; | ||||
| 
 | ||||
| #ifdef USE_FOG | ||||
| 
 | ||||
| 		diffuse.rgb = mix(diffuse.rgb,fog_interp.rgb,fog_interp.a); | ||||
| 
 | ||||
| # if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) | ||||
| 		diffuse.rgb = mix(mix(vec3(0.0),diffuse.rgb,attenuation),diffuse.rgb,const_light_mult); | ||||
| # endif | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1084,9 +1096,10 @@ LIGHT_SHADER_CODE | |||
| 
 | ||||
| #ifdef USE_VERTEX_LIGHTING | ||||
| 
 | ||||
| 	vec3 ambient = ambient_light*diffuse.rgb; | ||||
| 	vec3 ambient = const_light_mult*ambient_light*diffuse.rgb; | ||||
| # if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) | ||||
| 	ambient*=diffuse_interp.a; //attenuation affects ambient too | ||||
| 
 | ||||
| # endif | ||||
| 
 | ||||
| //	diffuse.rgb=(diffuse.rgb * diffuse_interp.rgb + specular * specular_interp)*shadow_attenuation + ambient; | ||||
|  | @ -1094,6 +1107,16 @@ LIGHT_SHADER_CODE | |||
| 	diffuse.rgb=(diffuse.rgb * diffuse_interp.rgb + specular * specular_interp)*shadow_attenuation + ambient; | ||||
| 	diffuse.rgb+=emission * const_light_mult; | ||||
| 
 | ||||
| #ifdef USE_FOG | ||||
| 
 | ||||
| 	diffuse.rgb = mix(diffuse.rgb,fog_interp.rgb,fog_interp.a); | ||||
| 
 | ||||
| # if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) | ||||
| 	diffuse.rgb = mix(mix(vec3(0.0),diffuse.rgb,diffuse_interp.a),diffuse.rgb,const_light_mult); | ||||
| # endif | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1120,10 +1143,7 @@ LIGHT_SHADER_CODE | |||
| 
 | ||||
| #else | ||||
| 
 | ||||
| #ifdef USE_FOG | ||||
| 
 | ||||
| 	diffuse.rgb = mix(diffuse.rgb,fog_interp.rgb,fog_interp.a); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef USE_GLOW | ||||
| 
 | ||||
|  |  | |||
|  | @ -498,6 +498,7 @@ public class Godot extends Activity implements SensorEventListener | |||
| 
 | ||||
| 	@Override public void onBackPressed() { | ||||
| 
 | ||||
| 		System.out.printf("** BACK REQUEST!\n"); | ||||
| 		GodotLib.quit(); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -52,6 +52,8 @@ public class GodotLib { | |||
|      public static native void touch(int what,int pointer,int howmany, int[] arr); | ||||
|      public static native void accelerometer(float x, float y, float z); | ||||
| 	 public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed); | ||||
| 	 public static native void joybutton(int p_device, int p_but, boolean p_pressed); | ||||
| 	 public static native void joyaxis(int p_device, int p_axis, float p_value); | ||||
|      public static native void focusin(); | ||||
|      public static native void focusout(); | ||||
|      public static native void audio(); | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ import android.util.Log; | |||
| import android.view.KeyEvent; | ||||
| import android.view.MotionEvent; | ||||
| import android.content.ContextWrapper; | ||||
| import android.view.InputDevice; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import javax.microedition.khronos.egl.EGL10; | ||||
|  | @ -99,22 +100,251 @@ public class GodotView extends GLSurfaceView { | |||
| 		return activity.gotTouchEvent(event); | ||||
| 	}; | ||||
| 
 | ||||
| 	public int get_godot_button(int keyCode) { | ||||
| 
 | ||||
| 		int button = 0; | ||||
| 		switch (keyCode) { | ||||
| 			case KeyEvent.KEYCODE_BUTTON_A: // Android A is SNES B | ||||
| 				button = 0; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_B: | ||||
| 				button = 1; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_X: // Android X is SNES Y | ||||
| 				button = 2; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_Y: | ||||
| 				button = 3; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_L1: | ||||
| 				button = 4; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_L2: | ||||
| 				button = 6; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_R1: | ||||
| 				button = 5; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_R2: | ||||
| 				button = 7; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_SELECT: | ||||
| 				button = 10; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_START: | ||||
| 				button = 11; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_THUMBL: | ||||
| 				button = 8; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_BUTTON_THUMBR: | ||||
| 				button = 9; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_DPAD_UP: | ||||
| 				button = 12; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_DPAD_DOWN: | ||||
| 				button = 13; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_DPAD_LEFT: | ||||
| 				button = 14; | ||||
| 				break; | ||||
| 			case KeyEvent.KEYCODE_DPAD_RIGHT: | ||||
| 				button = 15; | ||||
| 				break; | ||||
| 
 | ||||
| 			default: | ||||
| 				button = keyCode - KeyEvent.KEYCODE_BUTTON_1; | ||||
| 				break; | ||||
| 		}; | ||||
| 
 | ||||
| 		return button; | ||||
| 	}; | ||||
| 
 | ||||
| 	@Override public boolean onKeyUp(int keyCode, KeyEvent event) { | ||||
| 		GodotLib.key(keyCode, event.getUnicodeChar(0), false); | ||||
| 
 | ||||
| 		if (keyCode == KeyEvent.KEYCODE_BACK) { | ||||
| 			return true; | ||||
| 		} | ||||
| 
 | ||||
| 		if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { | ||||
| 			return super.onKeyUp(keyCode, event); | ||||
| 		}; | ||||
| 
 | ||||
| 		int source = event.getSource(); | ||||
| 		if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { | ||||
| 
 | ||||
| 			int button = get_godot_button(keyCode); | ||||
| 			int device = event.getDeviceId(); | ||||
| 
 | ||||
| 			GodotLib.joybutton(device, button, false); | ||||
| 			return true; | ||||
| 		} else { | ||||
| 
 | ||||
| 			GodotLib.key(keyCode, event.getUnicodeChar(0), false); | ||||
| 		}; | ||||
| 		return super.onKeyUp(keyCode, event); | ||||
| 	}; | ||||
| 
 | ||||
| 	@Override public boolean onKeyDown(int keyCode, KeyEvent event) { | ||||
| 		GodotLib.key(keyCode, event.getUnicodeChar(0), true); | ||||
| 
 | ||||
| 		if (keyCode == KeyEvent.KEYCODE_BACK) { | ||||
| 			GodotLib.quit(); | ||||
| 			// press 'back' button should not terminate program | ||||
| 			//	normal handle 'back' event in game logic | ||||
| 			return true; | ||||
| 		} | ||||
| 
 | ||||
| 		if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { | ||||
| 			return super.onKeyDown(keyCode, event); | ||||
| 		}; | ||||
| 
 | ||||
| 		int source = event.getSource(); | ||||
| 		//Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD))); | ||||
| 
 | ||||
| 		if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { | ||||
| 
 | ||||
| 			if (event.getRepeatCount() > 0) // ignore key echo | ||||
| 				return true; | ||||
| 			int button = get_godot_button(keyCode); | ||||
| 			int device = event.getDeviceId(); | ||||
| 			//Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device)); | ||||
| 
 | ||||
| 			GodotLib.joybutton(device, button, true); | ||||
| 			return true; | ||||
| 
 | ||||
| 		} else { | ||||
| 			GodotLib.key(keyCode, event.getUnicodeChar(0), true); | ||||
| 		}; | ||||
| 		return super.onKeyDown(keyCode, event); | ||||
| 	} | ||||
| 
 | ||||
| 	private void init(boolean translucent, int depth, int stencil) { | ||||
| 	public float axis_value(MotionEvent p_event, InputDevice p_device, int p_axis, int p_pos) { | ||||
| 
 | ||||
| 		final InputDevice.MotionRange range = p_device.getMotionRange(p_axis, p_event.getSource()); | ||||
| 		if (range == null) | ||||
| 			return 0; | ||||
| 
 | ||||
| 		//Log.e(TAG, String.format("axis ranges %f, %f, %f", range.getRange(), range.getMin(), range.getMax())); | ||||
| 
 | ||||
| 		final float flat = range.getFlat(); | ||||
| 		final float value = | ||||
| 			p_pos < 0 ? p_event.getAxisValue(p_axis): | ||||
| 			p_event.getHistoricalAxisValue(p_axis, p_pos); | ||||
| 
 | ||||
| 		final float absval = Math.abs(value); | ||||
| 		if (absval <= flat) { | ||||
| 			return 0; | ||||
| 		}; | ||||
| 
 | ||||
| 		final float ret = (value - range.getMin()) / range.getRange() * 2 - 1.0f; | ||||
| 
 | ||||
| 		return ret; | ||||
| 	}; | ||||
| 
 | ||||
| 	float[] last_axis_values = { 0, 0, 0, 0, -1, -1 }; | ||||
| 	boolean[] last_axis_buttons = { false, false, false, false, false, false }; // dpad up down left right, ltrigger, rtrigger | ||||
| 
 | ||||
| 	public void process_axis_state(MotionEvent p_event, int p_pos) { | ||||
| 
 | ||||
| 		int device_id = p_event.getDeviceId(); | ||||
| 		InputDevice device = p_event.getDevice(); | ||||
| 		float val; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_X, p_pos); | ||||
| 		if (val != last_axis_values[0]) { | ||||
| 			last_axis_values[0] = val; | ||||
| 			//Log.e(TAG, String.format("axis moved! axis %d, value %f", 0, val)); | ||||
| 			GodotLib.joyaxis(device_id, 0, val); | ||||
| 		}; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_Y, p_pos); | ||||
| 		if (val != last_axis_values[1]) { | ||||
| 			last_axis_values[1] = val; | ||||
| 			//Log.e(TAG, String.format("axis moved! axis %d, value %f", 1, val)); | ||||
| 			GodotLib.joyaxis(device_id, 1, val); | ||||
| 		}; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_Z, p_pos); | ||||
| 		if (val != last_axis_values[2]) { | ||||
| 			last_axis_values[2] = val; | ||||
| 			//Log.e(TAG, String.format("axis moved! axis %d, value %f", 2, val)); | ||||
| 			GodotLib.joyaxis(device_id, 2, val); | ||||
| 		}; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_RZ, p_pos); | ||||
| 		if (val != last_axis_values[3]) { | ||||
| 			last_axis_values[3] = val; | ||||
| 			//Log.e(TAG, String.format("axis moved! axis %d, value %f", 3, val)); | ||||
| 			GodotLib.joyaxis(device_id, 3, val); | ||||
| 		}; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_LTRIGGER, p_pos); | ||||
| 		if (val != last_axis_values[4]) { | ||||
| 			last_axis_values[4] = val; | ||||
| 			if ((val != 0) != (last_axis_buttons[4])) { | ||||
| 				last_axis_buttons[4] = (val != 0); | ||||
| 				GodotLib.joybutton(device_id, 6, (val != 0)); | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_RTRIGGER, p_pos); | ||||
| 		if (val != last_axis_values[5]) { | ||||
| 			last_axis_values[5] = val; | ||||
| 			if ((val != 0) != (last_axis_buttons[5])) { | ||||
| 				last_axis_buttons[5] = (val != 0); | ||||
| 				GodotLib.joybutton(device_id, 7, (val != 0)); | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_HAT_Y, p_pos); | ||||
| 
 | ||||
| 		if (last_axis_buttons[0] != (val > 0)) { | ||||
| 			last_axis_buttons[0] = val > 0; | ||||
| 			GodotLib.joybutton(device_id, 12, val > 0); | ||||
| 		}; | ||||
| 		if (last_axis_buttons[1] != (val < 0)) { | ||||
| 			last_axis_buttons[1] = val < 0; | ||||
| 			GodotLib.joybutton(device_id, 13, val > 0); | ||||
| 		}; | ||||
| 
 | ||||
| 		val = axis_value(p_event, device, MotionEvent.AXIS_HAT_X, p_pos); | ||||
| 		if (last_axis_buttons[2] != (val < 0)) { | ||||
| 			last_axis_buttons[2] = val < 0; | ||||
| 			GodotLib.joybutton(device_id, 14, val < 0); | ||||
| 		}; | ||||
| 		if (last_axis_buttons[3] != (val > 0)) { | ||||
| 			last_axis_buttons[3] = val > 0; | ||||
| 			GodotLib.joybutton(device_id, 15, val > 0); | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 	@Override public boolean onGenericMotionEvent(MotionEvent event) { | ||||
| 
 | ||||
| 		if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { | ||||
| 
 | ||||
| 			// Process all historical movement samples in the batch | ||||
| 			final int historySize = event.getHistorySize(); | ||||
| 
 | ||||
| 			// Process the movements starting from the | ||||
| 			// earliest historical position in the batch | ||||
| 			for (int i = 0; i < historySize; i++) { | ||||
| 				// Process the event at historical position i | ||||
| 				process_axis_state(event, i); | ||||
| 			} | ||||
| 
 | ||||
| 			// Process the current movement sample in the batch (position -1) | ||||
| 			process_axis_state(event, -1); | ||||
| 			return true; | ||||
| 
 | ||||
| 
 | ||||
| 		}; | ||||
| 
 | ||||
| 		return super.onGenericMotionEvent(event); | ||||
| 	}; | ||||
| 
 | ||||
| 
 | ||||
|     private void init(boolean translucent, int depth, int stencil) { | ||||
| 
 | ||||
| 		this.setFocusableInTouchMode(true); | ||||
| 		/* By default, GLSurfaceView() creates a RGB_565 opaque surface. | ||||
|  |  | |||
|  | @ -581,6 +581,8 @@ static Vector3 accelerometer; | |||
| static HashMap<String,JNISingleton*> jni_singletons; | ||||
| static jobject godot_io; | ||||
| 
 | ||||
| static Vector<int> joy_device_ids; | ||||
| 
 | ||||
| typedef void (*GFXInitFunc)(void *ud,bool gl2); | ||||
| 
 | ||||
| static jmethodID _on_video_init=0; | ||||
|  | @ -1279,6 +1281,49 @@ static unsigned int android_get_keysym(unsigned int p_code) { | |||
| 	return KEY_UNKNOWN; | ||||
| } | ||||
| 
 | ||||
| static int find_device(int p_device) { | ||||
| 
 | ||||
| 	for (int i=0; i<joy_device_ids.size(); i++) { | ||||
| 
 | ||||
| 		if (joy_device_ids[i] == p_device) { | ||||
| 			//print_line("found device at "+String::num(i));
 | ||||
| 			return i; | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 	//print_line("adding a device at" + String::num(joy_device_ids.size()));
 | ||||
| 	joy_device_ids.push_back(p_device); | ||||
| 
 | ||||
| 	return joy_device_ids.size() - 1; | ||||
| }; | ||||
| 
 | ||||
| JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) { | ||||
| 
 | ||||
| 	InputEvent ievent; | ||||
| 	ievent.type = InputEvent::JOYSTICK_BUTTON; | ||||
| 	ievent.device = find_device(p_device); | ||||
| 	ievent.joy_button.button_index = p_button; | ||||
| 	ievent.joy_button.pressed = p_pressed; | ||||
| 
 | ||||
| 	input_mutex->lock(); | ||||
| 	key_events.push_back(ievent); | ||||
| 	input_mutex->unlock(); | ||||
| }; | ||||
| 
 | ||||
| JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { | ||||
| 
 | ||||
| 	InputEvent ievent; | ||||
| 	ievent.type = InputEvent::JOYSTICK_MOTION; | ||||
| 	ievent.device = find_device(p_device); | ||||
| 	ievent.joy_motion.axis = p_axis; | ||||
| 	ievent.joy_motion.axis_value = p_value; | ||||
| 
 | ||||
| 	input_mutex->lock(); | ||||
| 	key_events.push_back(ievent); | ||||
| 	input_mutex->unlock(); | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { | ||||
| 
 | ||||
| 	InputEvent ievent; | ||||
|  |  | |||
|  | @ -43,6 +43,8 @@ extern "C" { | |||
|     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_quit(JNIEnv * env, jobject obj); | ||||
|     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_touch(JNIEnv * env, jobject obj, jint ev,jint pointer, jint count, jintArray positions); | ||||
| 	JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed); | ||||
| 	JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed); | ||||
| 	JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value); | ||||
| 	JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_audio(JNIEnv * env, jobject obj); | ||||
|     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj,  jfloat x, jfloat y, jfloat z); | ||||
|     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_focusin(JNIEnv * env, jobject obj); | ||||
|  |  | |||
|  | @ -37,6 +37,12 @@ | |||
| #include "modules/FacebookScorer_ios/FacebookScorer.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef MODULE_GAME_ANALYTICS_ENABLED | ||||
| #import "modules/game_analytics/ios/MobileAppTracker.framework/Headers/MobileAppTracker.h" | ||||
| //#import "modules/game_analytics/ios/MobileAppTracker.h" | ||||
| #import <AdSupport/AdSupport.h> | ||||
| #endif | ||||
| 
 | ||||
| #define kFilteringFactor                        0.1 | ||||
| #define kRenderingFrequency						60 | ||||
| #define kAccelerometerFrequency         100.0 // Hz | ||||
|  | @ -210,7 +216,36 @@ static int frame_count = 0; | |||
| 	//OSIPhone::screen_width = rect.size.width - rect.origin.x; | ||||
| 	//OSIPhone::screen_height = rect.size.height - rect.origin.y; | ||||
| 	 | ||||
| 	mainViewController = view_controller;	 | ||||
| 	mainViewController = view_controller; | ||||
|      | ||||
| #ifdef MODULE_GAME_ANALYTICS_ENABLED | ||||
|     printf("********************* didFinishLaunchingWithOptions\n"); | ||||
|     if(!Globals::get_singleton()->has("mobileapptracker/advertiser_id")) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|     if(!Globals::get_singleton()->has("mobileapptracker/conversion_key")) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|          | ||||
|     String adid = GLOBAL_DEF("mobileapptracker/advertiser_id",""); | ||||
|     String convkey = GLOBAL_DEF("mobileapptracker/conversion_key",""); | ||||
|          | ||||
|     NSString * advertiser_id = [NSString stringWithUTF8String:adid.utf8().get_data()]; | ||||
|     NSString * conversion_key = [NSString stringWithUTF8String:convkey.utf8().get_data()]; | ||||
|          | ||||
|     // Account Configuration info - must be set | ||||
|     [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id | ||||
|                                     MATConversionKey:conversion_key]; | ||||
|          | ||||
|     // Used to pass us the IFA, enables highly accurate 1-to-1 attribution. | ||||
|     // Required for many advertising networks. | ||||
|     [MobileAppTracker setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager] advertisingIdentifier] | ||||
|         advertisingTrackingEnabled:[[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]]; | ||||
|          | ||||
| #endif | ||||
|      | ||||
| }; | ||||
| 
 | ||||
| - (void)applicationWillTerminate:(UIApplication*)application { | ||||
|  | @ -240,6 +275,10 @@ static int frame_count = 0; | |||
| - (void) applicationDidBecomeActive:(UIApplication *)application | ||||
| { | ||||
| 	printf("********************* did become active\n"); | ||||
| #ifdef MODULE_GAME_ANALYTICS_ENABLED | ||||
|     printf("********************* mobile app tracker found\n"); | ||||
| 	[MobileAppTracker measureSession]; | ||||
| #endif | ||||
| 	[view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Juan Linietsky
						Juan Linietsky