Skip to content

Commit

Permalink
Introduce a compatibility setting for Fantasy Zone 128x128
Browse files Browse the repository at this point in the history
Its requirement of issuing a clipRect() call instead of setClip()
whenever the graphics object is reset for screen rendering breaks
a lot of other games, so turn this into a compat setting as i can't
think of another game that needs this. Fixes #64, and is also related
to #10 (of course it is, that issue is massive).
  • Loading branch information
AShiningRay committed Mar 3, 2025
1 parent 20f808a commit 4ace187
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 18 deletions.
28 changes: 19 additions & 9 deletions src/libretro/freej2me_libretro.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ unsigned int spdHackNoAlpha = 0; // Boolean

/* Compatibility Settings section */
unsigned int compatNonFatalNullImages = 0; // Boolean
unsigned int compatClipRectOnGfxReset = 0; // Boolean

/* Libretro exposed config variables END */

Expand Down Expand Up @@ -481,11 +482,18 @@ static void check_variables(bool first_time_startup)
else if (!strcmp(var.value, "on")) { compatNonFatalNullImages = 1; }
}

var.key = "freej2me_compatcliprectongfxreset";
if (Environ(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "off")) { compatClipRectOnGfxReset = 0; }
else if (!strcmp(var.value, "on")) { compatClipRectOnGfxReset = 1; }
}


/* Prepare a string to pass those core options to the Java app */
options_update = malloc(sizeof(char) * PIPE_MAX_LEN);

snprintf(options_update, PIPE_MAX_LEN, "FJ2ME_LR_OPTS:|%lux%lu|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d", screenRes[0], screenRes[1], rotateScreen, phoneType, gameFPS, soundEnabled, customMidi, dumpAudioStreams, loggingLevel, spdHackNoAlpha, backlightColor, compatNonFatalNullImages);
snprintf(options_update, PIPE_MAX_LEN, "FJ2ME_LR_OPTS:|%lux%lu|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d", screenRes[0], screenRes[1], rotateScreen, phoneType, gameFPS, soundEnabled, customMidi, dumpAudioStreams, loggingLevel, spdHackNoAlpha, backlightColor, compatNonFatalNullImages, compatClipRectOnGfxReset);
optstrlen = strlen(options_update);

/* 0xD = 13, which is the special case where the java app will receive the updated configs */
Expand Down Expand Up @@ -535,7 +543,7 @@ void retro_init(void)

/* Check variables and set parameters */
check_variables(true);
char resArg[2][4], rotateArg[2], phoneArg[2], fpsArg[3], soundArg[2], midiArg[2], dumpAudioArg[2], logLevelArg[2], spdHackNoAlphaArg[2], backlightArg[2], compatNonFatalNullImagesArg[2];
char resArg[2][4], rotateArg[2], phoneArg[2], fpsArg[3], soundArg[2], midiArg[2], dumpAudioArg[2], logLevelArg[2], spdHackNoAlphaArg[2], backlightArg[2], compatNonFatalNullImagesArg[2], compatClipRectOnGfxResetArg[2];
sprintf(resArg[0], "%lu", screenRes[0]);
sprintf(resArg[1], "%lu", screenRes[1]);
sprintf(rotateArg, "%d", rotateScreen);
Expand All @@ -548,6 +556,7 @@ void retro_init(void)
sprintf(spdHackNoAlphaArg, "%d", spdHackNoAlpha);
sprintf(backlightArg, "%d", backlightColor);
sprintf(compatNonFatalNullImagesArg, "%d", compatNonFatalNullImages);
sprintf(compatClipRectOnGfxResetArg, "%d", compatClipRectOnGfxReset);

/* We need to clean up any argument memory from the previous launch arguments in order to load up updated ones */
if (restarting)
Expand All @@ -566,7 +575,7 @@ void retro_init(void)
}

/* Allocate memory for launch arguments */
params = (char**)malloc(sizeof(char*) * 16);
params = (char**)malloc(sizeof(char*) * 17);
params[0] = strdup("java");
params[1] = strdup("-jar");
params[2] = strdup("freej2me-lr.jar");
Expand All @@ -582,7 +591,8 @@ void retro_init(void)
params[12] = strdup(spdHackNoAlphaArg);
params[13] = strdup(backlightArg);
params[14] = strdup(compatNonFatalNullImagesArg);
params[15] = NULL; // Null-terminate the array
params[15] = strdup(compatClipRectOnGfxResetArg);
params[16] = NULL; // Null-terminate the array

log_fn(RETRO_LOG_INFO, "Preparing to open FreeJ2ME-Plus' Java app.\n");

Expand Down Expand Up @@ -1175,8 +1185,8 @@ int javaOpen(char *cmd, char **params)
log_fn(RETRO_LOG_INFO, "Setting up java app's process and pipes...\n");

log_fn(RETRO_LOG_INFO, "Opening: %s %s %s ...\n", *(params+0), *(params+1), *(params+2));
log_fn(RETRO_LOG_INFO, "Params: %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s\n", *(params+3),
*(params+4), *(params+5), *(params+6), *(params+7), *(params+8), *(params+9), *(params+10), *(params+11), *(params+12), *(params+13), *(params+14));
log_fn(RETRO_LOG_INFO, "Params: %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s\n", *(params+3),
*(params+4), *(params+5), *(params+6), *(params+7), *(params+8), *(params+9), *(params+10), *(params+11), *(params+12), *(params+13), *(params+14), *(params+15));
}
else { log_fn(RETRO_LOG_INFO, "Restarting FreeJ2ME.\n"); restarting = false; }

Expand Down Expand Up @@ -1286,7 +1296,7 @@ int javaOpen(char *cmd, char **params)
sprintf(cmdWin, "javaw -jar %s", cmd);

log_fn(RETRO_LOG_INFO, "Opening: %s \n", cmdWin);
for (int i = 3; i < 15; i++)
for (int i = 3; i < 16; i++)
{
//log_fn(RETRO_LOG_INFO, "Processing arg %d: %s \n", i, *(params+i));
sprintf(cmdWin, "%s %s", cmdWin, *(params+i));
Expand All @@ -1299,8 +1309,8 @@ int javaOpen(char *cmd, char **params)
log_fn(RETRO_LOG_INFO, "Setting up java app's process and pipes...\n");

log_fn(RETRO_LOG_INFO, "Opening: %s ...\n", cmdWin);
log_fn(RETRO_LOG_INFO, "Params: %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s\n", *(params+3),
*(params+4), *(params+5), *(params+6), *(params+7), *(params+8), *(params+9), *(params+10), *(params+11), *(params+12), *(params+13), *(params+14));
log_fn(RETRO_LOG_INFO, "Params: %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s\n", *(params+3),
*(params+4), *(params+5), *(params+6), *(params+7), *(params+8), *(params+9), *(params+10), *(params+11), *(params+12), *(params+13), *(params+14), *(params+15));
}
else { log_fn(RETRO_LOG_INFO, "Restarting FreeJ2ME.\n"); restarting = false; }

Expand Down
29 changes: 29 additions & 0 deletions src/libretro/freej2me_libretro.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,20 @@ struct retro_core_option_v2_definition core_options[] =
},
"off"
},
{
"freej2me_compatcliprectongfxreset",
"Compatibility Settings > Do clipRect instead of setClip on gfx reset",
"Do clipRect instead of setClip on gfx reset",
"Fantasy Zone's 128x128 version relies on a clipRect() call being issued whenever a fullscreen draw is made instead of setClip(). So far, it seems to be the only jar in the compatibility list that needs this, and enabling it will break quite a few others.",
"Fantasy Zone's 128x128 version relies on a clipRect() call being issued whenever a fullscreen draw is made instead of setClip(). So far, it seems to be the only jar in the compatibility list that needs this, and enabling it will break quite a few others.",
"compat_settings",
{
{ "on", "Enabled" },
{ "off", "Disabled (Default)" },
{ NULL, NULL },
},
"off"
},
{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
};

Expand Down Expand Up @@ -711,6 +725,17 @@ struct retro_core_option_definition core_options_v1 [] =
},
"off"
},
{
"freej2me_compatcliprectongfxreset",
"Do clipRect instead of setClip on gfx reset",
"Fantasy Zone's 128x128 version relies on a clipRect() call being issued whenever a fullscreen draw is made instead of setClip(). So far, it seems to be the only jar in the compatibility list that needs this, and enabling it will break quite a few others.",
{
{ "on", "Enabled" },
{ "off", "Disabled (Default)" },
{ NULL, NULL },
},
"off"
},
{ NULL, NULL, NULL, {{0}}, NULL },
};

Expand Down Expand Up @@ -792,5 +817,9 @@ static const struct retro_variable vars[] =
"freej2me_compatnonfatalnullimages",
"Don't throw Exception on null images; off|on",
},
{ /* No Alpha on Blank Images compat setting */
"freej2me_compatcliprectongfxreset",
"Do clipRect instead of setClip on gfx reset; off|on",
},
{ NULL, NULL },
};
17 changes: 17 additions & 0 deletions src/org/recompile/freej2me/AWTGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ public final class AWTGUI

// Compatibility settings
final CheckboxMenuItem NonFatalNullImages = new CheckboxMenuItem("Don't throw Exception on null images");
final CheckboxMenuItem doClipRectOnGfxReset = new CheckboxMenuItem("Do clipRect instead of setClip on gfx reset");

final CheckboxMenuItem dumpAudioData = new CheckboxMenuItem("Dump Audio Streams");
final CheckboxMenuItem dumpGraphicsData = new CheckboxMenuItem("Dump Graphics Objects");
Expand Down Expand Up @@ -487,6 +488,19 @@ public void itemStateChanged(ItemEvent e)
}
});

// Compatibility settings
doClipRectOnGfxReset.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if(doClipRectOnGfxReset.getState()){ config.updateCompatClipRectOnGfxReset("on"); hasPendingChange = true; }
else{ config.updateCompatClipRectOnGfxReset("off"); hasPendingChange = true; }

awtDialogs[3].setLocationRelativeTo(main);
awtDialogs[3].setVisible(true);
}
});

// Layout options
for(byte i = 0; i < layoutOptions.length; i++)
{
Expand Down Expand Up @@ -665,6 +679,7 @@ private void buildMenuBar()
speedHackMenu.add(noAlphaOnBlankImages);

compatSettingsMenu.add(NonFatalNullImages);
compatSettingsMenu.add(doClipRectOnGfxReset);

// add menus to menubar
menuBar.add(fileMenu);
Expand Down Expand Up @@ -694,6 +709,8 @@ public void updateOptions()

NonFatalNullImages.setState(config.settings.get("compatnonfatalnullimage").equals("on"));

doClipRectOnGfxReset.setState(config.settings.get("compatcliprectongfxreset").equals("on"));

resChoice.select(""+ Integer.parseInt(config.settings.get("width")) + "x" + ""+ Integer.parseInt(config.settings.get("height")));

/* We only need to do this call once, when the jar first loads */
Expand Down
11 changes: 10 additions & 1 deletion src/org/recompile/freej2me/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public void init()
settings.put("soundfont", "Default");
settings.put("spdhacknoalpha", "off");
settings.put("compatnonfatalnullimage", "off");
settings.put("compatcliprectongfxreset", "off");
saveConfig();
}
}
Expand Down Expand Up @@ -138,7 +139,7 @@ public void init()
if(!settings.containsKey("soundfont")) { settings.put("soundfont", "Default"); }
if(!settings.containsKey("spdhacknoalpha")) { settings.put("spdhacknoalpha", "off"); }
if(!settings.containsKey("compatnonfatalnullimage")) { settings.put("compatnonfatalnullimage", "off"); }

if(!settings.containsKey("compatcliprectongfxreset")) { settings.put("compatcliprectongfxreset", "off"); }
}
catch (Exception e)
{
Expand Down Expand Up @@ -235,6 +236,14 @@ public void updateCompatNonFatalNullImage(String value)
onChange.run();
}

public void updateCompatClipRectOnGfxReset(String value)
{
Mobile.log(Mobile.LOG_DEBUG, Config.class.getPackage().getName() + "." + Config.class.getSimpleName() + ": " + "Config: compatcliprectongfxreset "+value);
settings.put("compatcliprectongfxreset", value);
saveConfig();
onChange.run();
}

public void updateBacklight(String value)
{
Mobile.log(Mobile.LOG_DEBUG, Config.class.getPackage().getName() + "." + Config.class.getSimpleName() + ": " + "Config: backlightcolor "+value);
Expand Down
20 changes: 15 additions & 5 deletions src/org/recompile/freej2me/Libretro.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,14 @@ public Libretro(String args[])
/* LCD Backlight Mask color index. */
Mobile.maskIndex = Integer.parseInt(args[10]);

/* The Non-Fatal Null Images compat setting is also a per-game config */
/* Compat settings are all handled as per-game configs */
if(Integer.parseInt(args[11]) == 0) { Mobile.compatNonFatalNullImages = false; }
else { Mobile.compatNonFatalNullImages = true; }

if(Integer.parseInt(args[12]) == 0) { Mobile.compatClipRectOnGfxReset = false; }
else { Mobile.compatClipRectOnGfxReset = true; }


/* Once it finishes parsing all arguments, it's time to set up freej2me-lr */

Mobile.setPlatform(new MobilePlatform(lcdWidth, lcdHeight));
Expand Down Expand Up @@ -291,6 +295,9 @@ public void run()
if(!Mobile.compatNonFatalNullImages) { Mobile.config.settings.put("compatnonfatalnullimage", "off"); }
else { Mobile.config.settings.put("compatnonfatalnullimage", "on"); }

if(!Mobile.compatClipRectOnGfxReset) { Mobile.config.settings.put("compatcliprectongfxreset", "off"); }
else { Mobile.config.settings.put("compatcliprectongfxreset", "on"); }

Mobile.config.saveConfig();
settingsChanged();

Expand Down Expand Up @@ -354,8 +361,8 @@ public void run()
if(Integer.parseInt(cfgtokens[9])==0) { Mobile.logging = false; }
else { Mobile.logging = true; Mobile.minLogLevel = (byte) (Integer.parseInt(cfgtokens[9])-1); }

if(Integer.parseInt(cfgtokens[10])==0) { Mobile.noAlphaOnBlankImages = false; }
else { Mobile.noAlphaOnBlankImages = true; }
if(Integer.parseInt(cfgtokens[10])==0) { Mobile.config.settings.put("spdhacknoalpha", "off"); }
else { Mobile.config.settings.put("spdhacknoalpha", "on"); }

if(Integer.parseInt(cfgtokens[11])==0) { Mobile.config.settings.put("backlightcolor", "Disabled"); }
if(Integer.parseInt(cfgtokens[11])==1) { Mobile.config.settings.put("backlightcolor", "Green"); }
Expand All @@ -364,8 +371,11 @@ public void run()
if(Integer.parseInt(cfgtokens[11])==4) { Mobile.config.settings.put("backlightcolor", "Violet"); }
if(Integer.parseInt(cfgtokens[11])==5) { Mobile.config.settings.put("backlightcolor", "Red"); }

if(Integer.parseInt(cfgtokens[12])==0) { Mobile.compatNonFatalNullImages = false; }
else { Mobile.compatNonFatalNullImages = true; }
if(Integer.parseInt(cfgtokens[12])==0) { Mobile.config.settings.put("compatnonfatalnullimage", "off"); }
else { Mobile.config.settings.put("compatnonfatalnullimage", "on"); }

if(Integer.parseInt(cfgtokens[13])==0) { Mobile.config.settings.put("compatcliprectongfxreset", "off"); }
else { Mobile.config.settings.put("compatcliprectongfxreset", "on"); }

Mobile.config.saveConfig();
settingsChanged();
Expand Down
7 changes: 6 additions & 1 deletion src/org/recompile/mobile/Mobile.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ public class Mobile
public static byte funLightRegionSize = 8;

// Compatibility settings
public static boolean compatNonFatalNullImages = false;
public static boolean compatNonFatalNullImages = false; // Fixes some version of House M.D
public static boolean compatClipRectOnGfxReset = false; // Fixes Fantasy Zone 128x128

// Keycode modifiers
public static boolean lg = false;
Expand Down Expand Up @@ -649,6 +650,10 @@ public static boolean updateSettings()
if(nonFatalNullImage.equals("on")) { compatNonFatalNullImages = true; }
else if (nonFatalNullImage.equals("off")) { compatNonFatalNullImages = false; };

String clipRectOnGfxReset = config.settings.get("compatcliprectongfxreset");
if(clipRectOnGfxReset.equals("on")) { compatClipRectOnGfxReset = true; }
else if (clipRectOnGfxReset.equals("off")) { compatClipRectOnGfxReset = false; };


// Rotation is left at the end since it governs this method's return value
String rotate = config.settings.get("rotate");
Expand Down
7 changes: 5 additions & 2 deletions src/org/recompile/mobile/PlatformGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public PlatformGraphics(PlatformImage image)

canvasData = ((DataBufferInt) canvas.getRaster().getDataBuffer()).getData();

clipRect(0, 0, canvas.getWidth(), canvas.getHeight());
setClip(0, 0, canvas.getWidth(), canvas.getHeight());

setColor(0,0,0);
setStrokeStyle(SOLID);
Expand All @@ -97,7 +97,9 @@ public PlatformGraphics(PlatformImage image)
public void reset() //Internal use method, resets the Graphics object to its inital values
{
translate(-1 * translateX, -1 * translateY);
clipRect(0, 0, canvas.getWidth(), canvas.getHeight());

if(Mobile.compatClipRectOnGfxReset) { clipRect(0, 0, canvas.getWidth(), canvas.getHeight()); }
else { setClip(0, 0, canvas.getWidth(), canvas.getHeight()); }
setColor(0,0,0);
setFont(Font.getDefaultFont());
setStrokeStyle(SOLID);
Expand Down Expand Up @@ -523,6 +525,7 @@ public void setFont(Font font)
public void setClip(int x, int y, int width, int height)
{
gc.setClip(x, y, width, height);
gc.clipRect(x, y, width, height);
gc.getClipBounds(rect);
}

Expand Down

0 comments on commit 4ace187

Please sign in to comment.