Skip to content

Commit

Permalink
DeviceControl + Samsung Vibration: Implement vibration strength
Browse files Browse the repository at this point in the history
DeviceControl's vibration was implemented in its entirety here,
and since it also allows for setting vibration strength, it was a
good opportunity to fully implement Samsung's Vibration, which
also supports this, as well. Both libretro and SDL support setting
both vibration duration and intensity now. Tested and working in
Sonic 1 Part One for S40v1 (low-end 128x128).
  • Loading branch information
AShiningRay committed Dec 9, 2024
1 parent beebdd4 commit 3455b0c
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 15 deletions.
17 changes: 15 additions & 2 deletions src/com/nokia/mid/ui/DeviceControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,26 @@
*/
package com.nokia.mid.ui;

import org.recompile.mobile.Mobile;

public class DeviceControl
{
public static void flashLights(long duration) { }

public static void setLights(int num, int level) { }

public static void startVibra(int freq, long duration) { }
public static void startVibra(int freq, long duration)
{
if(freq == 0) { return; } // No need to vibrate if the strength will be zero.
if(freq < 0 || freq > 100) { throw new IllegalArgumentException("Cannot startVibra(), freq value is out of bounds"); }

Mobile.vibrationDuration = (int) duration;
Mobile.vibrationStrength = (int) ((freq / 100.0) * 0xFFFF); // Map from 0-100 to 0x0000-0xFFFF
}

public static void stopVibra() { }
public static void stopVibra()
{
Mobile.vibrationDuration = 0;
Mobile.vibrationStrength = 0xFFFF;
}
}
8 changes: 6 additions & 2 deletions src/com/samsung/util/Vibration.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ public static void start(int duration, int strength)
{
if(duration < 0 || strength < 1 || strength > 5) { throw new IllegalArgumentException("Samsung Vibration: Cannot start vibrating due to illegal argument"); }
Mobile.vibrationDuration = duration;
//Mobile.vibrationStrength = (byte) strength; // This doesn't seem to be important, and is ignored according to the documentation
Mobile.vibrationStrength = (int) ((strength / 5.0) * 0xFFFF); // Map from 1-5 to 0x3333-0xFFFF
}

public static void stop() { Mobile.vibrationDuration = 0; }
public static void stop()
{
Mobile.vibrationDuration = 0;
Mobile.vibrationStrength = 0xFFFF;
}
}
20 changes: 13 additions & 7 deletions src/libretro/freej2me_libretro.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ long joymouseClickedTime = 0; /* Countdown to show/hide the cursor in the clicke
bool joymouseAnalog = false; /* flag - using analog stick for mouse movement */
int mouseLpre = 0; /* old mouse button state */
int rumbleTime = 0; /* Rumble duration calculated based on data received from FreeJ2ME-lr.jar */
unsigned short rumbleStrength = 0xFFFF; /* Rumble strength calculated based on data received from FreeJ2ME-lr.jar */
bool uses_mouse = true;
bool uses_pointer = false;
bool booted = false;
Expand All @@ -132,7 +133,7 @@ unsigned int frameSize = MAX_WIDTH * MAX_HEIGHT;
unsigned int frameBufferSize = MAX_WIDTH * MAX_HEIGHT * 3;
unsigned int frame[MAX_WIDTH * MAX_HEIGHT];
unsigned char frameBuffer[MAX_WIDTH * MAX_HEIGHT * 3];
unsigned char frameHeader[9];
unsigned char frameHeader[13];
struct retro_game_info gameinfo;

bool frameRequested = false;
Expand Down Expand Up @@ -166,8 +167,8 @@ unsigned int spdHackNoAlpha = 0; // Boolean

/* Libretro exposed config variables END */

/* First byte is the identifier, next four are width and height, and next four are vibration */
unsigned char javaRequestFrame[9] = { 0xF, 0, 0, 0, 0, 0, 0, 0, 0 };
/* First byte is the identifier, next four are width and height */
unsigned char javaRequestFrame[5] = { 0xF, 0, 0, 0, 0 };

/* mouse cursor image */
unsigned int joymouseImage[408] =
Expand Down Expand Up @@ -773,8 +774,8 @@ void retro_run(void)
/* Process rumble events */
if (rumbleTime > 0 && rumble.set_rumble_state)
{
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, 0xFFFF);
rumble.set_rumble_state(0, RETRO_RUMBLE_WEAK, 0xFFFF);
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, rumbleStrength);
rumble.set_rumble_state(0, RETRO_RUMBLE_WEAK, rumbleStrength);
rumbleTime -= 1000 / DEFAULT_FPS;
}
else
Expand Down Expand Up @@ -935,7 +936,7 @@ void retro_run(void)
/* read frame header */
frameRequested = false;
framesDropped = 0;
status = read_from_pipe(pRead[0], frameHeader, 9);
status = read_from_pipe(pRead[0], frameHeader, 13);

if(status>0)
{
Expand All @@ -945,7 +946,12 @@ void retro_run(void)

/* Read vibration event */
int preRumbleTime = ( (frameHeader[5]<<24) | (frameHeader[6]<<16) | (frameHeader[7]<<8) | (frameHeader[8]));
if(preRumbleTime > 0) { log_fn(RETRO_LOG_INFO, "Received Vibration event of %d ms.\n", preRumbleTime); rumbleTime = preRumbleTime; }
rumbleStrength = ( (frameHeader[9]<<24) | (frameHeader[10]<<16) | (frameHeader[11]<<8) | (frameHeader[12]));
if(preRumbleTime > 0)
{
log_fn(RETRO_LOG_INFO, "Received Vibration event of %d ms. Strength is 0x%04X\n", preRumbleTime, rumbleStrength);
rumbleTime = preRumbleTime;
}

if(r!=0)
{
Expand Down
2 changes: 1 addition & 1 deletion src/org/recompile/freej2me/Anbu.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void run()
/* Check if vibration commands have to be handled */
if(Mobile.vibrationDuration != 0)
{
int vib = SDL_JoystickRumble(joy, (short) 0xFFFF, (short) 0xFFFF, Mobile.vibrationDuration);
int vib = SDL_JoystickRumble(joy, (short) (Mobile.vibrationStrength & 0xFFFF), (short) (Mobile.vibrationStrength & 0xFFFF), Mobile.vibrationDuration);
Mobile.vibrationDuration = 0;
}

Expand Down
11 changes: 8 additions & 3 deletions src/org/recompile/freej2me/Libretro.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class Libretro
private boolean[] pressedKeys = new boolean[128];

private byte[] frameBuffer = new byte[800*800*3];
private final byte[] frameHeader = new byte[]{(byte)0xFE, 0, 0, 0, 0, 0, 0, 0, 0, 0};
private final byte[] frameHeader = new byte[]{(byte)0xFE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

private int mousex;
private int mousey;
Expand Down Expand Up @@ -394,9 +394,14 @@ public void run()
frameHeader[7] = (byte)((Mobile.vibrationDuration>>16) & 0xFF);
frameHeader[8] = (byte)((Mobile.vibrationDuration>>8) & 0xFF);
frameHeader[9] = (byte)((Mobile.vibrationDuration) & 0xFF);
System.out.write(frameHeader, 0, 10);

/* Vibration duration should be set to zero to prevent constant sends of the same data, so update it here*/
frameHeader[10] = (byte)((Mobile.vibrationStrength>>24) & 0xFF);
frameHeader[11] = (byte)((Mobile.vibrationStrength>>16) & 0xFF);
frameHeader[12] = (byte)((Mobile.vibrationStrength>>8) & 0xFF);
frameHeader[13] = (byte)((Mobile.vibrationStrength) & 0xFF);
System.out.write(frameHeader, 0, 14);

/* Vibration duration should be set to zero to prevent constant sends of the same data, so update it here */
Mobile.vibrationDuration = 0;

final int[] data = ((DataBufferInt) Mobile.getPlatform().getLCD().getRaster().getDataBuffer()).getData();
Expand Down
1 change: 1 addition & 0 deletions src/org/recompile/mobile/Mobile.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public class Mobile

// Vibration support for Libretro and SDL
public static int vibrationDuration = 0;
public static int vibrationStrength = 0xFFFF;

// Support for explicit FPS limit on jars that require it to work properly
public static int limitFPS = 0;
Expand Down

0 comments on commit 3455b0c

Please sign in to comment.