Skip to content

Commit

Permalink
v1.05 (beta) rev4052 (14 Mar 2021)
Browse files Browse the repository at this point in the history
- Support for Panekit - Infinitive Crafting Toy Case videos
- Support for Star Wars - Rebel Assault II - The Hidden Empire videos
- New video detection framework should identify even more unique video variations
- Added new full frame replace option: size-limit="original non-zero"
  (see manual for details)
  (Github issue #32 "Resident Evil 2 Video bug" by gledson999)
- Renamed command-line "-replacexa" option to "-replaceaudio"
  (see manual for details)
- Support for replacing audio streams used in several SquareSoft games
  (Github issue #35 "How to replace modified video w audio in Chrono Cross?"
   by saifhashmi210)
- Tiny quality improvement to video frame encoding
Bug fixes:
- Header frame number in image sequence file names is incorrect
  • Loading branch information
m35 committed Mar 14, 2021
1 parent b1c3787 commit bd3575d
Show file tree
Hide file tree
Showing 329 changed files with 6,511 additions and 4,433 deletions.
6 changes: 3 additions & 3 deletions jpsxdec/PSXListOFGames.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1455,8 +1455,8 @@ Status
[ ] SLUS-00884 Star Wars - Episode I - The Phantom Menace
[ ] SLUS-80884 Star Wars - Episode I - The Phantom Menance [Demo - Trade]
[ ] SLUS-00562 Star Wars - Masters of Teras Kasi
[!] SLUS-00381 Star Wars - Rebel Assault II [Disc1of2]
[!] SLUS-00386 Star Wars - Rebel Assault II [Disc2of2]
[+] SLUS-00381 Star Wars - Rebel Assault II [Disc1of2]
[+] SLUS-00386 Star Wars - Rebel Assault II [Disc2of2]
[+] SLUS-00057 Starblade Alpha
[ ] SLUS-01302 Starfighter Sanvein
[ ] SLUS-00094 Starwinder - The Ultimate Space Race
Expand Down Expand Up @@ -7590,7 +7590,7 @@ Status
[ ] SLPM-87018 Palm Town [MajorWave 1500 Series]
[ ] SLPM-80030 Pandora Project
[ ] SLPS-00347 Pandora Project - The Logic Master
[ ] SCPS-10096 Panekit - Infinitive Crafting Case
[+] SCPS-10096 Panekit - Infinitive Crafting Toy Case
[ ] SLPS-01162 Panel Quiz Attack 25
[ ] SLPM-86276 Pangaea [SuperLite 1500 Series]
[ ] SLPS-00899 Panzer Bandit
Expand Down
152 changes: 77 additions & 75 deletions jpsxdec/PlayStation1_STR_format.txt

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions jpsxdec/TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ New features
============

Games to investigate
* Star Wars - Rebel Assault II
* Discworld 2
* BrainDead 13
* Love Games - Wai Wai Tennis [Service Price] [SLPS-01647] INTRO.STR
* Fear Effect
* Magic the Gathering
* Aconcagua ending video
* Sentient
* Panekit - Infinitive Crafting Toy Case
// Star Wars - Rebel Assault II
// Panekit - Infinitive Crafting Toy Case
// Love Games - Wai Wai Tennis [Service Price] [SLPS-01647] INTRO.STR - broken video (2336 sector as a file)

Replace
with a prompt before applying changes
Expand Down
2 changes: 1 addition & 1 deletion jpsxdec/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<!-- ====== global build properties ====== -->

<property name="jpsxdec.ver" value="v1-04_rev3987"/>
<property name="jpsxdec.ver" value="v1-05-beta"/>

<!-- sources -->
<property name="src.dir.rel" location="src" relative="true"/>
Expand Down
15 changes: 15 additions & 0 deletions jpsxdec/doc/CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
v1.05 (beta) rev4052 (14 Mar 2021)
- Support for Panekit - Infinitive Crafting Toy Case videos
- Support for Star Wars - Rebel Assault II - The Hidden Empire videos
- New video detection framework should identify even more unique video variations
- Added new full frame replace option: size-limit="original non-zero"
(see manual for details)
(Github issue #32 "Resident Evil 2 Video bug" by gledson999)
- Renamed command-line "-replacexa" option to "-replaceaudio"
(see manual for details)
- Support for replacing audio streams used in several SquareSoft games
(Github issue #35 "How to replace modified video w audio in Chrono Cross?"
by saifhashmi210)
- Tiny quality improvement to video frame encoding
Bug fixes:
- Header frame number in image sequence file names is incorrect
v1.04 rev3987 (10 Aug 2020)
- More robust XA audio detection
- Support for saving images as TIFF in Java 9+
Expand Down
2 changes: 1 addition & 1 deletion jpsxdec/doc/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

jPSXdec: PlayStation 1 Media Decoder/Converter in Java
Copyright (C) 2007-2020 Michael Sabin
Copyright (C) 2007-2021 Michael Sabin
All rights reserved.

jPSXdec is licensed as a whole under this non-commercial license:
Expand Down
Binary file modified jpsxdec/doc/jPSXdec-manual.odt
Binary file not shown.
22 changes: 15 additions & 7 deletions jpsxdec/jPSXdec-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ so it's probably the best. I personally rarely refer to the program by name,
and often informally shorten it to just "jPSX"* or "PlayStation converter"
when talking to others about it.

* Note: The name "jpsx" is already taken by the Java only PS1 emulator.
* Note: The name "jpsx" is already taken by the PS1 emulator written entirely in Java.

## Java 6

Expand All @@ -55,9 +55,14 @@ I've found only a few compelling features that jPSXdec would really benefit from
So there's really no point in upgrading.
And maybe someone still running Windows XP will want to use jPSXdec...

The project has also been developed entirely in Netbeans
because it was the best thing since IntelliJ, still sometimes better.
## Development environment

The Ant build script is necessary for easy building, regardless of IDE used.
But for developing, it's easier to ignore the Ant script and simply import all the code into a basic
Java project in the IDE of your choice.

However several of the UI forms were designed using Netbeans forms designer.
Netbeans would be required to modify those forms.

## Code styleguide

Expand All @@ -66,18 +71,21 @@ because it was the best thing since IntelliJ, still sometimes better.
* Use `final` on all fields if at all possible.
* If it's not possible, consider making a new inner class that CAN use final fields.
* Code and comments are written to mostly minimize vertical size,
so more lines of content can be visible on screen.
so more lines of content can be visible on screen.
* Once lines are a little more than 80 characters long, consider looking for a place to split it (if you feel like it).
* Put the opening brace on the line that starts a block, unless you need to
wrap the line, then put the brace on its own line.
* Align wrapped lines with the prior opening section.
* Wrapped lines should usually be indented at least 8 characters.
* Interface classes usually begin with `I`.
* Use `@NonNull` and `@CheckForNull` for every argument, return type, and field that is an object.
A few places where that isn't is necessary:
A few places where that may not be necessary:
* When it is a `final` field that is initialized at declaration.
* When the possibility of a variable being null is too complicated, so the flag would just be a useless warning.

* When the possibility of a variable being null is too complicated, so the flag would just be a useless warning (should be very rare).
* `toString()` method return type
* Parameters for an empty method implementing an interface
* Keep the length of files less than 1000 lines-of-code (including header), but also more than 50 (excluding header) (i.e. put tiny classes in related files if it makes sense)
* Try to design the code such that there is only one reasonable way to do something

### Naming conventions

Expand Down
5 changes: 3 additions & 2 deletions jpsxdec/src/jpsxdec/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,11 @@ public static void main(final String[] asArgs) {
blnShowGui = true;
} else if (asArgs.length == 1) {
blnShowGui = !ap.hasHelp();
}
}

if (blnShowGui) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Gui gui = new Gui();
if (asArgs.length > 0)
Expand Down
2 changes: 1 addition & 1 deletion jpsxdec/src/jpsxdec/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

public class Version {

public final static String Version = "1.04 (beta)";
public final static String Version = "1.05 (beta)";
public final static String IndexHeader = "[jPSXdec v"+Version+"]";

}
2 changes: 1 addition & 1 deletion jpsxdec/src/jpsxdec/adpcm/AdpcmContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ public double getPreviousPCMSample2() {
return _dblPreviousPCMSample2;
}

}
}
3 changes: 2 additions & 1 deletion jpsxdec/src/jpsxdec/adpcm/AudioShortReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
/** Wraps {@link AudioInputStream} to read mono or stereo 16-bit
* {@link AudioFormat.Encoding.PCM_SIGNED} samples as arrays of shorts. */
public class AudioShortReader implements Closeable {

@Nonnull
private final AudioInputStream _sourceAudio;

Expand Down Expand Up @@ -78,6 +78,7 @@ public boolean isEof() {
}

/** Closes the underlying audio stream. */
@Override
public void close() throws IOException {
_sourceAudio.close();
}
Expand Down
14 changes: 7 additions & 7 deletions jpsxdec/src/jpsxdec/adpcm/PSoundPpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public static class Entry {
/** Standard Windows MAX_PATH length. */
private static final int FILE_NAME_BUFFER_SIZE = 260;

private Entry(@Nonnull InputStream is, int iIndex)
private Entry(@Nonnull InputStream is, int iIndex)
throws EOFException, IOException, BinaryDataNotRecognized
{
// buffer to store the item name and file name
Expand All @@ -130,21 +130,21 @@ private Entry(@Nonnull InputStream is, int iIndex)
throw new BinaryDataNotRecognized();
IO.readByteArray(is, abItemNameAndFileName, 0, iItemNameLength);
// add null terminator (not really necessary since Java arrays are 0)
abItemNameAndFileName[iItemNameLength] = 0;
abItemNameAndFileName[iItemNameLength] = 0;

int iFileNameLength = IO.readUInt8(is);
if (iFileNameLength == 0)
throw new BinaryDataNotRecognized();
IO.readByteArray(is, abItemNameAndFileName, ITEM_NAME_BUFFER_SIZE, iFileNameLength);
// add null terminator (not really necessary since Java arrays are 0)
abItemNameAndFileName[ITEM_NAME_BUFFER_SIZE+iFileNameLength] = 0;

// extract the strings
_sItemName = Misc.asciiToString(abItemNameAndFileName, 0, iItemNameLength);
_sSourceFilePath = Misc.asciiToString(abItemNameAndFileName, ITEM_NAME_BUFFER_SIZE, iFileNameLength);

_lngEncryptedOffset = IO.readUInt32LE(is);

// the 5 unknown zero bytes appear to be used for something
// but need to see an example file with non-zero values
// to get a lead as to what
Expand Down Expand Up @@ -180,7 +180,7 @@ Now to decrypt the source file offset (i.e. what kind of crap is this?)
sub eax, [ebp-0Ch] ; substract the index of the entry
mov [ebp-10h], eax ; store the unencrypted value
*/

// stack
int bitsToRotate = iItemNameLength + iFileNameLength;
int temp;
Expand All @@ -189,7 +189,7 @@ Now to decrypt the source file offset (i.e. what kind of crap is this?)
int eax;
int cl;
int ecx;

eax = iFileNameLength;
eax = IO.readSInt32LE(abItemNameAndFileName, ITEM_NAME_BUFFER_SIZE + eax - 5);
temp = eax;
Expand Down
2 changes: 1 addition & 1 deletion jpsxdec/src/jpsxdec/adpcm/SoundUnitDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void decodeSoundUnit(@Nonnull AdpcmContext context,
telemetry.adblPrev2Samples[i] = context.getPreviousPCMSample2();
telemetry.adblDecodedPcmSamples[i] = dblDecodedPcm;
}

// let the context scale, round, and clamp
short siPcmSample = context.saveScaleRoundClampPCMSample(dblDecodedPcm);
// finally return the polished sample
Expand Down
12 changes: 7 additions & 5 deletions jpsxdec/src/jpsxdec/adpcm/SoundUnitEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ public static class EncodedUnit {
public final int iRange;
/** If at least 1 ADPCM sample had to be clamped to fit. */
public final boolean blnHadToClamp;

/** Encoded ADPCM data samples.
* 8 bits/sample uses the whole byte.
* 4 bits/sample uses the least significant nibble. */
@Nonnull
public final byte[] abEncodedAdpcm;

private EncodedUnit(int iFilterIndex, int iRange, boolean blnHadToClamp,
private EncodedUnit(int iFilterIndex, int iRange, boolean blnHadToClamp,
@Nonnull byte[] abEncodedAdpcm)
{
this.iFilterIndex = iFilterIndex;
Expand Down Expand Up @@ -257,7 +257,7 @@ private class FilterRangeEncoder {
/** Encoded data goes here. */
private final byte[] _abEncodedAdpcm = new byte[SoundUnitDecoder.SAMPLES_PER_SOUND_UNIT];

/** If at least 1 ADPCM sample had to be clamped to fit.
/** If at least 1 ADPCM sample had to be clamped to fit.
* Try to avoid this this {@link FilterRangeEncoder} if clamping occurred. */
private boolean _blnHadToClamp = false;

Expand All @@ -277,7 +277,9 @@ private FilterRangeEncoder(int iFilterIndex, int iRange,
}

/** Checks if this sound unit provides better encoding than the supplied
* sound unit. The decider. */
* sound unit.
* TODO: This may not be the best way to decide the winning encoded sound unit,
* but it should be a reasonable choice. */
public boolean isBetterThan(@Nonnull FilterRangeEncoder other) {
return _dblMaxDelta < other._dblMaxDelta;
}
Expand Down Expand Up @@ -372,7 +374,7 @@ else if (lngRanged > _iEncodeMax)
return _blnHadToClamp;
}
}

// =========================================================================
// static

Expand Down
13 changes: 7 additions & 6 deletions jpsxdec/src/jpsxdec/adpcm/SpuAdpcmDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
import javax.sound.sampled.AudioFormat;
import jpsxdec.util.IO;

/** PlayStation
/** PlayStation
* Sound Processing Unit (SPU)
* Adaptive Differential Pulse Code Modulation (ADPCM)
* decoder.
Expand Down Expand Up @@ -100,7 +100,7 @@ public static int calculatePcmBytesGenerated(int iInputBytes) {

// =========================================================================
// instance

@Nonnull
protected final SpuSoundUnitDecoder _leftOrMonoSoundUnitDecoder;

Expand All @@ -124,6 +124,7 @@ public LogContext() {
blnHadCorruption = false;
}

@Override
public @Nonnull LogContext copy() {
LogContext cpy = new LogContext();
cpy.iSoundUnitsDecoded = iSoundUnitsDecoded;
Expand Down Expand Up @@ -195,7 +196,7 @@ public Mono(double dblVolume) {
public int getBytesPerSampleFrame() {
return 2;
}

/** Decodes a requested amount of sound units from the input stream
* and writes it to the output stream. To know the amount of data that
* will be written to the output stream, use
Expand Down Expand Up @@ -234,7 +235,7 @@ public int decode(@Nonnull SpuAdpcmSoundUnit soundUnit, @Nonnull OutputStream ou
{
IO.writeInt16LE(out, _leftOrMonoSoundUnitDecoder.getDecodedPcmSample(iSampleIdx));
}

_logContext.iChannel = -1;
return SoundUnitDecoder.SAMPLES_PER_SOUND_UNIT;
}
Expand Down Expand Up @@ -294,7 +295,7 @@ public int decode(@Nonnull SpuAdpcmSoundUnit leftSoundUnit,

_logContext.iChannel = -1;

for (int iSampleIdx = 0;
for (int iSampleIdx = 0;
iSampleIdx < SoundUnitDecoder.SAMPLES_PER_SOUND_UNIT;
iSampleIdx++, _logContext.lngSampleFramesWritten++)
{
Expand All @@ -305,7 +306,7 @@ public int decode(@Nonnull SpuAdpcmSoundUnit leftSoundUnit,
}
}


protected static class SpuSoundUnitDecoder {
private final SoundUnitDecoder _decoder = new SoundUnitDecoder(K0K1Filter.SPU);
@Nonnull
Expand Down
8 changes: 6 additions & 2 deletions jpsxdec/src/jpsxdec/adpcm/SpuAdpcmEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public static class LogContext implements IContextCopier {

private LogContext() {}

@Override
public @Nonnull LogContext copy() {
LogContext cpy = new LogContext();
cpy.lngSampleFramesReadEncoded = lngSampleFramesReadEncoded;
Expand Down Expand Up @@ -105,14 +106,15 @@ public boolean isEof() {
return _audioShortReader.isEof();
}

@Override
public void close() throws IOException {
_audioShortReader.close();
}

public long getSampleFramesReadAndEncoded() {
return _logContext.lngSampleFramesReadEncoded;
}

/** Manually provide the filter and range parameters for every Sound Unit
* via a stream of bytes. Primarily for development/testing purposes. */
public void setPresetParameters(@CheckForNull InputStream presetParameters) {
Expand All @@ -128,6 +130,7 @@ public Mono(@Nonnull AudioInputStream input) throws IncompatibleException {
throw new IncompatibleException();
}

@Override
public boolean isStereo() {
return false;
}
Expand All @@ -141,7 +144,7 @@ public boolean encode1SoundUnit(byte bFlagBits, @Nonnull OutputStream spuOutputS
short[][] aasiPcmSoundUnitChannelSamples =
_audioShortReader.readSoundUnitSamples(SoundUnitDecoder.SAMPLES_PER_SOUND_UNIT);

encode1SoundUnitChannel(_leftOrMonoEncoder, aasiPcmSoundUnitChannelSamples[0],
encode1SoundUnitChannel(_leftOrMonoEncoder, aasiPcmSoundUnitChannelSamples[0],
bFlagBits, spuOutputStream);
return true;
}
Expand All @@ -163,6 +166,7 @@ public Stereo(@Nonnull AudioInputStream input) throws IncompatibleException {
_rightChannel = new SoundUnitEncoder(4, K0K1Filter.SPU);
}

@Override
public boolean isStereo() {
return true;
}
Expand Down
Loading

0 comments on commit bd3575d

Please sign in to comment.