diff --git a/misc/dreamcast/VertexClip2.S b/misc/dreamcast/VertexClip2.S index db6222774..ee04dc6c6 100644 --- a/misc/dreamcast/VertexClip2.S +++ b/misc/dreamcast/VertexClip2.S @@ -61,11 +61,11 @@ _ClipEdge: mov IN1, TM1 ! MT, tmp = &v1 fldi0 fr4 ! LS, fr4 = 0 add #12, TM1 ! EX, tmp = &v1->z - fmov.s @r1, fr2 ! LS, fr2 = v1->z + fmov.s @TM1, fr2 ! LS, fr2 = v1->z mov IN2, TM1 ! MT, tmp = &v2 fldi0 fr5 ! LS, fr5 = 0 add #12, TM1 ! EX, tmp = &v2->z - fmov.s @r1,fr11 ! LS, fr11 = v2->z + fmov.s @TM1,fr11 ! LS, fr11 = v2->z fsub fr2,fr11 ! FE, fr11 = v2->z - v1->z fldi0 fr8 ! LS, fr8 = 0 fmul fr11,fr11 ! FE, fr11 = (v2->z - v1->z) * (v2->z * v1->z) @@ -120,11 +120,11 @@ _ClipEdge: fmov.s fr3,@OUT ! LS, OUT->w = lerp add #-4, OUT ! EX, OUT -= 4 - mov.l @IN1+,CL1 ! LS, ACOLOR = v1->bgra + mov.l @IN1,CL1 ! LS, ACOLOR = v1->bgra extu.b CL1,TM1 ! EX, val = ACOLOR.b lds TM1,fpul ! CO, FPUL = val float fpul,fr2 ! EX, fr2 = float(FPUL) - mov.l @IN2+,CL2 ! LS, BCOLOR = v2->bgra + mov.l @IN2,CL2 ! LS, BCOLOR = v2->bgra extu.b CL2,TM1 ! EX, val = BCOLOR.b lds TM1,fpul ! CO, FPUL = val float fpul,fr3 ! EX, fr3 = float(FPUL) diff --git a/src/Camera.c b/src/Camera.c index 9e613ffc6..829b63560 100644 --- a/src/Camera.c +++ b/src/Camera.c @@ -17,21 +17,27 @@ struct _CameraData Camera; static struct RayTracer cameraClipPos; static Vec2 cam_rotOffset; static cc_bool cam_isForwardThird; -static float cam_deltaX, cam_deltaY; -static void Camera_OnRawMovement(float deltaX, float deltaY) { - cam_deltaX += deltaX; cam_deltaY += deltaY; +static struct CameraState { + float deltaX, deltaY; +} states[MAX_LOCAL_PLAYERS]; + +static void Camera_OnRawMovement(float deltaX, float deltaY, int deviceIndex) { + int i = Game_MapState(deviceIndex); + states[i].deltaX += deltaX; + states[i].deltaY += deltaY; } void Camera_KeyLookUpdate(float delta) { if (Gui.InputGrab) return; /* divide by 25 to have reasonable sensitivity for default mouse sens */ float amount = (Camera.Sensitivity / 25.0f) * (1000 * delta); + int i = Game.CurrentState; - if (Bind_IsTriggered[BIND_LOOK_UP]) cam_deltaY -= amount; - if (Bind_IsTriggered[BIND_LOOK_DOWN]) cam_deltaY += amount; - if (Bind_IsTriggered[BIND_LOOK_LEFT]) cam_deltaX -= amount; - if (Bind_IsTriggered[BIND_LOOK_RIGHT]) cam_deltaX += amount; + if (Bind_IsTriggered[BIND_LOOK_UP]) states[i].deltaY -= amount; + if (Bind_IsTriggered[BIND_LOOK_DOWN]) states[i].deltaY += amount; + if (Bind_IsTriggered[BIND_LOOK_LEFT]) states[i].deltaX -= amount; + if (Bind_IsTriggered[BIND_LOOK_RIGHT]) states[i].deltaX += amount; } /*########################################################################################################################* @@ -64,11 +70,12 @@ static void PerspectiveCamera_GetPickedBlock(struct RayTracer* t) { static Vec2 PerspectiveCamera_GetMouseDelta(float delta) { float sensitivity = CAMERA_SENSI_FACTOR * Camera.Sensitivity; static float speedX, speedY, newSpeedX, newSpeedY, accelX, accelY; + int i = Game.CurrentState; Vec2 v; if (Camera.Smooth) { - accelX = (cam_deltaX - speedX) * 35 / Camera.Mass; - accelY = (cam_deltaY - speedY) * 35 / Camera.Mass; + accelX = (states[i].deltaX - speedX) * 35 / Camera.Mass; + accelY = (states[i].deltaY - speedY) * 35 / Camera.Mass; newSpeedX = accelX * delta + speedX; newSpeedY = accelY * delta + speedY; @@ -79,11 +86,12 @@ static Vec2 PerspectiveCamera_GetMouseDelta(float delta) { if (newSpeedY * speedY < 0) speedY = 0; else speedY = newSpeedY; } else { - speedX = cam_deltaX; - speedY = cam_deltaY; + speedX = states[i].deltaX; + speedY = states[i].deltaY; } - v.x = speedX * sensitivity; v.y = speedY * sensitivity; + v.x = speedX * sensitivity; + v.y = speedY * sensitivity; if (Camera.Invert) v.y = -v.y; return v; } @@ -94,7 +102,8 @@ static void PerspectiveCamera_UpdateMouseRotation(struct LocalPlayer* p, float d Vec2 rot = PerspectiveCamera_GetMouseDelta(delta); if (Input_IsAltPressed() && Camera.Active->isThirdPerson) { - cam_rotOffset.x += rot.x; cam_rotOffset.y += rot.y; + cam_rotOffset.x += rot.x; + cam_rotOffset.y += rot.y; return; } @@ -111,17 +120,19 @@ static void PerspectiveCamera_UpdateMouseRotation(struct LocalPlayer* p, float d } static void PerspectiveCamera_UpdateMouse(struct LocalPlayer* p, float delta) { + int i = Game.CurrentState; if (!Gui.InputGrab && Window_Main.Focused) Window_UpdateRawMouse(); PerspectiveCamera_UpdateMouseRotation(p, delta); - cam_deltaX = 0; cam_deltaY = 0; + states[i].deltaX = 0; + states[i].deltaY = 0; } static void PerspectiveCamera_CalcViewBobbing(struct LocalPlayer* p, float t, float velTiltScale) { struct Entity* e = &p->Base; - struct Matrix tiltY, velX; float vel, fall; + if (!Game_ViewBobbing) { Camera.TiltM = Matrix_Identity; Camera.TiltPitch = 0.0f; @@ -153,7 +164,7 @@ static Vec2 FirstPersonCamera_GetOrientation(void) { struct LocalPlayer* p = Entities.CurPlayer; struct Entity* e = &p->Base; - Vec2 v; + Vec2 v; v.x = e->Yaw * MATH_DEG2RAD; v.y = e->Pitch * MATH_DEG2RAD; return v; @@ -261,14 +272,14 @@ static struct Camera cam_ForwardThird = { *-----------------------------------------------------General camera------------------------------------------------------* *#########################################################################################################################*/ static void OnRawMovement(void* obj, float deltaX, float deltaY) { - Camera.Active->OnRawMovement(deltaX, deltaY); + Camera.Active->OnRawMovement(deltaX, deltaY, 0); } static void OnAxisUpdate(void* obj, int port, int axis, float x, float y) { if (!Input.RawMode) return; if (Gamepad_AxisBehaviour[axis] != AXIS_BEHAVIOUR_CAMERA) return; - Camera.Active->OnRawMovement(x, y); + Camera.Active->OnRawMovement(x, y, port); } static void OnHacksChanged(void* obj) { diff --git a/src/Camera.h b/src/Camera.h index e4c17a2d9..0afef30ef 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -57,7 +57,7 @@ struct Camera { /* Typically, this is used to adjust yaw/pitch based on accumulated mouse movement. */ void (*UpdateMouse)(struct LocalPlayer* p, float delta); /* Called when mouse/pointer has moved. */ - void (*OnRawMovement)(float deltaX, float deltaY); + void (*OnRawMovement)(float deltaX, float deltaY, int deviceIndex); /* Called when user closes all menus, and is interacting with camera again. */ void (*AcquireFocus)(void); /* Called when user is no longer interacting with camera. (e.g. opened menu) */ diff --git a/src/Entity.c b/src/Entity.c index 29d987fb7..148a913d4 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -775,7 +775,7 @@ static void LocalPlayer_Reset(struct LocalPlayer* p) { static void LocalPlayers_Reset(void) { int i; - for (i = 0; i < Game_NumLocalPlayers; i++) + for (i = 0; i < Game_NumStates; i++) { LocalPlayer_Reset(&LocalPlayer_Instances[i]); } @@ -793,18 +793,14 @@ static void LocalPlayer_OnNewMap(struct LocalPlayer* p) { static void LocalPlayers_OnNewMap(void) { int i; - for (i = 0; i < Game_NumLocalPlayers; i++) + for (i = 0; i < Game_NumStates; i++) { LocalPlayer_OnNewMap(&LocalPlayer_Instances[i]); } } static struct LocalPlayer* LocalPlayer_Get(int deviceIndex) { - if (Game_NumLocalPlayers >= 4 && deviceIndex == 3) return &LocalPlayer_Instances[3]; - if (Game_NumLocalPlayers >= 3 && deviceIndex == 2) return &LocalPlayer_Instances[2]; - if (Game_NumLocalPlayers >= 2 && deviceIndex == 1) return &LocalPlayer_Instances[1]; - - return &LocalPlayer_Instances[0]; + return &LocalPlayer_Instances[Game_MapState(deviceIndex)]; } static cc_bool LocalPlayer_IsSolidCollide(BlockID b) { return Blocks.Collide[b] == COLLIDE_SOLID; } @@ -1036,7 +1032,7 @@ void LocalPlayers_MoveToSpawn(struct LocationUpdate* update) { struct LocalPlayer* p; int i; - for (i = 0; i < Game_NumLocalPlayers; i++) + for (i = 0; i < Game_NumStates; i++) { p = &LocalPlayer_Instances[i]; p->Base.VTABLE->SetLocation(&p->Base, update); @@ -1128,7 +1124,7 @@ static void Entities_Init(void) { ShadowMode_Names, Array_Elems(ShadowMode_Names)); if (Game_ClassicMode) Entities.ShadowsMode = SHADOW_MODE_NONE; - for (i = 0; i < Game_NumLocalPlayers; i++) + for (i = 0; i < Game_NumStates; i++) { LocalPlayer_Init(&LocalPlayer_Instances[i], i); Entities.List[MAX_NET_PLAYERS + i] = &LocalPlayer_Instances[i].Base; diff --git a/src/Game.c b/src/Game.c index 37ae59c0f..36df74ba2 100644 --- a/src/Game.c +++ b/src/Game.c @@ -71,7 +71,7 @@ static char mppassBuffer[STRING_SIZE]; cc_string Game_Username = String_FromArray(usernameBuffer); cc_string Game_Mppass = String_FromArray(mppassBuffer); #ifdef CC_BUILD_SPLITSCREEN -int Game_NumLocalPlayers = 1; +int Game_NumStates = 1; #endif const char* const FpsLimit_Names[FPS_LIMIT_COUNT] = { @@ -697,6 +697,7 @@ static CC_INLINE void Game_DrawFrame(float delta, float t) { static void DrawSplitscreen(float delta, float t, int i, int x, int y, int w, int h) { Gfx_SetViewport(x, y, w, h); Gfx_SetScissor( x, y, w, h); + Game.CurrentState = i; Entities.CurPlayer = &LocalPlayer_Instances[i]; LocalPlayer_SetInterpPosition(Entities.CurPlayer, t); @@ -704,6 +705,14 @@ static void DrawSplitscreen(float delta, float t, int i, int x, int y, int w, in Game_DrawFrame(delta, t); } + +int Game_MapState(int deviceIndex) { + if (Game_NumStates >= 4 && deviceIndex == 3) return 3; + if (Game_NumStates >= 3 && deviceIndex == 2) return 2; + if (Game_NumStates >= 2 && deviceIndex == 1) return 1; + + return 0; +} #endif static CC_INLINE void Game_RenderFrame(void) { @@ -763,7 +772,7 @@ static CC_INLINE void Game_RenderFrame(void) { Gfx_ClearBuffers(GFX_BUFFER_COLOR | GFX_BUFFER_DEPTH); #ifdef CC_BUILD_SPLITSCREEN - switch (Game_NumLocalPlayers) { + switch (Game_NumStates) { case 1: Game_DrawFrame(delta, t); break; case 2: @@ -855,6 +864,7 @@ void Game_Run(int width, int height, const cc_string* title) { Window_SetTitle(title); Window_Show(); gameRunning = true; + Game.CurrentState = 0; Game_Load(); Event_RaiseVoid(&WindowEvents.Resized); diff --git a/src/Game.h b/src/Game.h index 170e07ecb..83a9c39e3 100644 --- a/src/Game.h +++ b/src/Game.h @@ -14,6 +14,8 @@ CC_VAR extern struct _GameData { double Time; /* Number of chunks updated within last second. Resets to 0 after every second. */ int ChunkUpdates; + /* Index of current game state being used (for splitscreen multiplayer) */ + int CurrentState; } Game; extern struct RayTracer Game_SelectedPos; @@ -25,9 +27,11 @@ typedef void (*Game_Draw2DHook)(void); extern Game_Draw2DHook Game_Draw2DHooks[4]; #ifdef CC_BUILD_SPLITSCREEN -extern int Game_NumLocalPlayers; + int Game_MapState(int deviceIndex); + extern int Game_NumStates; #else -#define Game_NumLocalPlayers 1 + static CC_INLINE int Game_MapState(int deviceIndex) { return 0; } + #define Game_NumStates 1 #endif #if defined CC_BUILD_N64 diff --git a/src/InputHandler.c b/src/InputHandler.c index 463244d10..361c5ef31 100644 --- a/src/InputHandler.c +++ b/src/InputHandler.c @@ -58,7 +58,7 @@ static void PlayerInputGamepad(struct LocalPlayer* p, float* xMoving, float* zMo for (port = 0; port < INPUT_MAX_GAMEPADS; port++) { /* In splitscreen mode, tie a controller to a specific player*/ - if (Game_NumLocalPlayers > 1 && p->index != port) continue; + if (Game_NumStates > 1 && p->index != port) continue; PlayerInputPad(port, PAD_AXIS_LEFT, p, xMoving, zMoving); PlayerInputPad(port, PAD_AXIS_RIGHT, p, xMoving, zMoving); @@ -928,7 +928,7 @@ static void Player_ReleaseDown(int key, struct InputDevice* device) { static void PlayerInputNormal(struct LocalPlayer* p, float* xMoving, float* zMoving) { int flags = 0, port; - if (Game_NumLocalPlayers == 1) { + if (Game_NumStates == 1) { for (port = 0; port < INPUT_MAX_GAMEPADS; port++) flags |= moveFlags[port]; } else { diff --git a/src/LScreens.c b/src/LScreens.c index 5084fa8d0..cb03278a0 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -650,7 +650,7 @@ LAYOUTS sps_btnBack[] = { { ANCHOR_CENTRE, 0 }, { ANCHOR_CENTRE, 170 } }; static void SplitScreen_Start(int players) { static const cc_string user = String_FromConst(DEFAULT_USERNAME); - Game_NumLocalPlayers = players; + Game_NumStates = players; Launcher_StartGame(&user, &String_Empty, &String_Empty, &String_Empty, &String_Empty); } diff --git a/src/Window_Android.c b/src/Window_Android.c index 385ee71f4..1341d8a2f 100644 --- a/src/Window_Android.c +++ b/src/Window_Android.c @@ -112,7 +112,7 @@ static void JNICALL java_processKeyDown(JNIEnv* env, jobject o, jint code) { Input.Sources |= INPUT_SOURCE_GAMEPAD; int port = Gamepad_Connect(0xAD01D, PadBind_Defaults); - Gamepad_SetButton(port, key); + Gamepad_SetButton(port, key, true); } else { if (key) Input_SetPressed(key); } @@ -121,7 +121,15 @@ static void JNICALL java_processKeyDown(JNIEnv* env, jobject o, jint code) { static void JNICALL java_processKeyUp(JNIEnv* env, jobject o, jint code) { int key = MapNativeKey(code); Platform_Log2("KEY - UP %i,%i", &code, &key); - if (key) Input_SetReleased(key); + + if (Input_IsPadButton(key)) { + Input.Sources |= INPUT_SOURCE_GAMEPAD; + + int port = Gamepad_Connect(0xAD01D, PadBind_Defaults); + Gamepad_SetButton(port, key, false); + } else { + if (key) Input_SetReleased(key); + } } static void JNICALL java_processKeyChar(JNIEnv* env, jobject o, jint code) { diff --git a/src/Window_PSP.c b/src/Window_PSP.c index 3d2edcc2b..ee14c96ff 100644 --- a/src/Window_PSP.c +++ b/src/Window_PSP.c @@ -126,7 +126,7 @@ static void ProcessCircleInput(int port, SceCtrlData* pad, float delta) { } void Gamepads_Process(float delta) { - int port = Gamepad_Connect(0x5O3, PadBind_Defaults); + int port = Gamepad_Connect(0x503, PadBind_Defaults); SceCtrlData pad; /* TODO implement */ diff --git a/src/Window_PSVita.c b/src/Window_PSVita.c index 1ff54e405..05041bd3f 100644 --- a/src/Window_PSVita.c +++ b/src/Window_PSVita.c @@ -176,7 +176,7 @@ static void ProcessCircleInput(int port, int axis, int x, int y, float delta) { } static void ProcessPadInput(float delta) { - int port = Gamepad_Connect(0x5O3, PadBind_Defaults); + int port = Gamepad_Connect(0x503, PadBind_Defaults); SceCtrlData pad; // sceCtrlReadBufferPositive is blocking (seems to block until vblank), and don't want that diff --git a/src/Window_Win.c b/src/Window_Win.c index c1ef41818..39cabed2e 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -49,7 +49,6 @@ static UINT (WINAPI *_GetRawInputData)(HRAWINPUT hRawInput, UINT cmd, void* data static BOOL (WINAPI* _SetProcessDPIAware)(void); static HINSTANCE win_instance; -static HWND win_handle; static HDC win_DC; static cc_bool suppress_resize; static cc_bool is_ansiWindow, grabCursor;