// Go check a Flash event queue for events SDL should be aware of! void FLASH_PumpEvents(_THIS) { if (!FLASH_EMPTY_PARAMS) FLASH_EMPTY_PARAMS = AS3_Array(""); // Event Vars AS3_Val mouseEvent, mouseEvents, mousePosition, keyboardEvent, keyboardEvents; int buttonState, rawKeyboardEvent, scanCode, keyState; SDL_keysym keysym; mousePosition = AS3_CallS( "pumpMousePosition", FLASH_EVENT_MANAGER_OBJECT, FLASH_EMPTY_PARAMS ); mouseEvents = AS3_CallS( "pumpMouseEvents", FLASH_EVENT_MANAGER_OBJECT, FLASH_EMPTY_PARAMS ); keyboardEvents = AS3_CallS( "pumpKeyEvents", FLASH_EVENT_MANAGER_OBJECT, FLASH_EMPTY_PARAMS ); // Mouse Position if (mousePosition) { AS3_ObjectValue( mousePosition, "x:IntType, y:IntType", &FLASH_mouseX, &FLASH_mouseY ); SDL_PrivateMouseMotion( 0, 0, FLASH_mouseX, FLASH_mouseY ); } // Mouse Click Events while( AS3_IntValue(AS3_GetS(mouseEvents, "size")) > 0 ) { mouseEvent = AS3_CallS( "dequeue", mouseEvents, FLASH_EMPTY_PARAMS ); buttonState = AS3_IntValue( mouseEvent )? SDL_PRESSED: SDL_RELEASED; SDL_PrivateMouseButton(buttonState, SDL_BUTTON_LEFT, FLASH_mouseX, FLASH_mouseY); } // Keyboard Events while( AS3_IntValue(AS3_GetS(keyboardEvents, "size")) > 0 ) { keyboardEvent = AS3_CallS( "dequeue", keyboardEvents, FLASH_EMPTY_PARAMS ); rawKeyboardEvent = AS3_IntValue( keyboardEvent ); scanCode = rawKeyboardEvent & 0xFF; // Packed event format: 9th bit for press/release, lower 8 bits for scan code keyState = rawKeyboardEvent >> 8; SDL_PrivateKeyboard(keyState, TranslateKey(scanCode, &keysym)); } }
/* * Function used as a callback for all Lua functions passed through * get_as3_value_from_lua_stack() */ AS3_Val as3_lua_callback(void * data, AS3_Val args) { /* WARNING: Panic alert! Use L*_FN checkers here! */ SPAM(("as3_lua_callback(): begin")); AS3_Val res; LuaFunctionCallbackData * func_data = (LuaFunctionCallbackData *) data; int nargs = 0; int status = 0; int results_base = 0; lua_State * L = func_data->L; if (L == NULL) { /* TODO: Should we crash here? fatal_error("state expired"); / * Does not return * / */ sztrace("as3_lua_callback: state expired"); return AS3_Undefined(); } { /* A new scope for LCALL to work (C89 conformance) */ LCALL(L, stack); /* TODO: Cache that with lua_ref, it is faster */ lua_getfield(L, LUA_REGISTRYINDEX, AS3LUA_CALLBACKS); /* TODO: Assert we have a table here */ lua_rawgeti(L, -1, func_data->ref); /* push stored function */ if (lua_istable(L, -1) == 0) /* Probably nil */ { lua_pop(L, 1); /* Pop bad callback table */ LCHECK_FN(L, stack, 0, fatal_error); fatal_error("function callback not found"); /* Does not return */ } lua_rawgeti(L, -1, AS3LUA_CBFNINDEX); /* push stored callback function */ #ifdef DO_SPAM { SPAM(("as3_lua_callback(): AS3 arguments")); AS3_Val a = AS3_CallS("join", args, AS3_Undefined()); AS3_Trace(a); SAFE_RELEASE(a); } #endif /* DO_SPAM */ /* TODO: Assert we have Lua function (or other callable object) on the top of the stack */ LCHECK_FN(L, stack, 2 + 1, fatal_error); nargs = push_as3_array_to_lua_stack(L, args); /* push arguments */ #ifdef DO_SPAM /* TODO: Remove */ lua_pushcfunction(L, as3_trace); dump_lua_stack(L, LBASE(L, stack) + 2 + 1); lua_pushliteral(L, "ARGUMENTS"); lua_pushnumber(L, nargs); lua_call(L, 3, 0); #endif /* DO_SPAM */ LCHECK_FN(L, stack, 2 + 1 + nargs, fatal_error); results_base = LBASE(L, stack) + 2; status = do_pcall_with_traceback(L, nargs, LUA_MULTRET); if (status != 0) { const char * msg = NULL; LCHECK_FN(L, stack, 2 + 1, fatal_error); /* Tables and error message */ lua_remove(L, -2); /* Remove AS3LUA_CALLBACKS table */ lua_remove(L, -2); /* Remove holder table */ LCHECK_FN(L, stack, 1, fatal_error); /* Only error message */ /* Error message is on stack */ /* NOTE: It is not necessary string! If we want to preserve its type, see lua_DoString. */ if (lua_tostring(L, -1) == NULL) { lua_pop(L, 1); lua_pushliteral(L, "(non-string)"); } LCHECK_FN(L, stack, 1, fatal_error); lua_pushliteral(L, "Error in Lua callback:\n"); lua_insert(L, -2); LCHECK_FN(L, stack, 2, fatal_error); lua_concat(L, 2); LCHECK_FN(L, stack, 1, fatal_error); sztrace((char *)lua_tostring(L, -1)); /* TODO: ?! */ /* lua_error(L); */ msg = lua_tostring(L, -1); lua_pop(L, 1); /* fatal_error(msg); / * Does not return * / */ } /* Process results */ #ifdef DO_SPAM /* TODO: Remove */ /* lua_pushcfunction(L, as3_trace); lua_pushliteral(L, "STACK"); dump_lua_stack(L, results_base); lua_call(L, 2, 0); */ #endif /* DO_SPAM */ res = create_as3_value_from_lua_stack(L, results_base + 1, LTOP(L, stack), TRUE); #ifdef DO_SPAM SPAM(("as3_lua_callback() result type")); AS3_Trace(AS3_Call(getQualifiedClassName_method, NULL, AS3_Array("AS3ValType", res))); #endif /* DO_SPAM */ lua_settop(L, LBASE(L, stack)); /* Cleanup results and two holder tables */ SPAM(("as3_lua_callback(): end")); return res; } /* Unreachable */ }