Skip to content

Commit

Permalink
fix: scene glitches
Browse files Browse the repository at this point in the history
Render scene to scratch buffer, this fixes leftover garbage when using
background surface directly. Fill last line correctly, this fixes
garbage on bottom of the original intro.

Fix 23
  • Loading branch information
carstene1ns committed Sep 20, 2024
1 parent 1e7ab56 commit 2812de5
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 160 deletions.
48 changes: 27 additions & 21 deletions src/io/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,49 +311,54 @@ unsigned char * File::loadBlock (int length) {
* Load a block of RLE compressed data from the file.
*
* @param length The length of the uncompressed block
* @param checkSize Whether or not the RLE block is terminated
*
* @return Buffer containing the uncompressed data
*/
unsigned char* File::loadRLE (int length) {
unsigned char* File::loadRLE (int length, bool checkSize) {
int start = 0, size = 0;

// Determine the offset that follows the block
int next = fgetc(file);
next += fgetc(file) << 8;
next += ftell(file);
if (checkSize) {
// Determine the offset that follows the block
size = loadShort();
start = tell();
}

unsigned char* buffer = new unsigned char[length];

int pos = 0;

while (pos < length) {

int rle = fgetc(file);
int rle = loadChar();

if (rle & 128) {

int byte = fgetc(file);

for (int i = 0; i < (rle & 127); i++) {
int byte = loadChar();
int amount = rle & 127;

buffer[pos++] = byte;
if (pos >= length) break;
if (pos + amount >= length) break;

}
memset(buffer + pos, byte, amount);
pos += amount;

} else if (rle) {

for (int i = 0; i < rle; i++) {
if (pos + rle >= length) break;

buffer[pos++] = fgetc(file);
if (pos >= length) break;
fread(buffer + pos, 1, rle, file);

}
pos += rle;

} else buffer[pos++] = fgetc(file);
} else buffer[pos++] = loadChar();

}

fseek(file, next, SEEK_SET);
if (checkSize) {
if (tell() != start + size)
LOG_DEBUG("RLE block has incorrect size: %d vs. %d", tell() - start, size);

seek(start + size, true);
}

return buffer;

Expand Down Expand Up @@ -478,15 +483,16 @@ char * File::loadString (int length) {
*
* @param width The width of the image to load
* @param height The height of the image to load
* @param checkSize Whether or not the RLE block is terminated
*
* @return SDL surface containing the loaded image
*/
SDL_Surface* File::loadSurface (int width, int height) {
SDL_Surface* File::loadSurface (int width, int height, bool checkSize) {

SDL_Surface* surface;
unsigned char* pixels;

pixels = loadRLE(width * height);
pixels = loadRLE(width * height, checkSize);

surface = createSurface(pixels, width, height);

Expand Down
9 changes: 6 additions & 3 deletions src/io/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

#include <SDL.h>
#include <stdio.h>

#include <memory>

// Classes

Expand Down Expand Up @@ -54,18 +54,21 @@ class File {
signed int loadInt ();
void storeInt (signed int val);
unsigned char* loadBlock (int length);
unsigned char* loadRLE (int length);
unsigned char* loadRLE (int length, bool checkSize = true);
void skipRLE ();
unsigned char* loadLZ (int compressedLength, int length);
char* loadString ();
char* loadString (int length);
SDL_Surface* loadSurface (int width, int height);
SDL_Surface* loadSurface (int width, int height, bool checkSize = true);
unsigned char* loadPixels (int length);
unsigned char* loadPixels (int length, int key);
void loadPalette (SDL_Color* palette, bool rle = true);

};

using FilePtr = std::unique_ptr<File>;


/// Directory path

enum path_type {
Expand Down
4 changes: 1 addition & 3 deletions src/jj1/save/jj1save.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include "util.h"
#include "io/log.h"

#include <memory>

/* This algorithm has been found out by CYBERDEViL by analysing the Assembly in
* DoxBox-X. For more information see: https://codeberg.org/CYBERDEV/JJSave/
*/
Expand Down Expand Up @@ -78,7 +76,7 @@ static unsigned short dataOffset(unsigned short key, bool skipGarbage = false) {
JJ1Save::JJ1Save (const char* fileName) :
valid(false) {

std::unique_ptr<File> file;
FilePtr file;
LOG_TRACE("Save: %s", fileName);

try {
Expand Down
33 changes: 17 additions & 16 deletions src/jj1/scene/jj1scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ JJ1SceneAnimation::JJ1SceneAnimation (JJ1SceneAnimation* newNext) {

next = newNext;
background = NULL;
scratch = createSurface(NULL, SW, SH);
lastFrame = sceneFrames = NULL;
frames = reverseAnimation = 0;
id = -1;
Expand Down Expand Up @@ -131,6 +132,7 @@ JJ1SceneAnimation::~JJ1SceneAnimation () {
}

if (background) SDL_FreeSurface(background);
if (scratch) SDL_FreeSurface(scratch);

}

Expand Down Expand Up @@ -249,13 +251,13 @@ JJ1ScenePage::~JJ1ScenePage() {
*/
JJ1Scene::JJ1Scene (const char * fileName) {

File *file;
FilePtr file;
nFonts = 0;
LOG_TRACE("Scene: %s", fileName);

try {

file = new File(fileName, PATH_TYPE_GAME);
file = std::make_unique<File>(fileName, PATH_TYPE_GAME);

} catch (int e) {

Expand All @@ -268,7 +270,7 @@ JJ1Scene::JJ1Scene (const char * fileName) {
animations = NULL;

file->seek(0x13, true); // Skip Digital Dimensions header
signed long int dataOffset = file->loadInt(); //get offset pointer to first data block
signed long int dataOffset = file->loadInt(); // Get offset pointer to first data block

scriptItems = file->loadShort(); // Get number of script items
scriptStarts = new signed long int[scriptItems];
Expand All @@ -278,8 +280,8 @@ JJ1Scene::JJ1Scene (const char * fileName) {

for (int i = 0; i < scriptItems; i++) {

scriptStarts[i] = file->loadInt();// Load offset to script
LOG_TRACE("scriptStart: %ld", scriptStarts[i]);
scriptStarts[i] = file->loadInt(); // Load offset to script
LOG_MAX("scriptStart: %ld", scriptStarts[i]);

}

Expand All @@ -291,18 +293,16 @@ JJ1Scene::JJ1Scene (const char * fileName) {

for (int i = 0; i < dataItems; i++) {

dataOffsets[i] = file->loadInt();// Load offset to script
LOG_TRACE("dataOffsets: %ld", dataOffsets[i]);
dataOffsets[i] = file->loadInt(); // Load offset to script
LOG_MAX("dataOffsets: %ld", dataOffsets[i]);

}

loadData(file);
loadScripts(file);
loadData(file.get());
loadScripts(file.get());

delete[] scriptStarts;
delete[] dataOffsets;
delete file;

}


Expand Down Expand Up @@ -478,6 +478,7 @@ int JJ1Scene::play () {
dst.y = (canvasH - SH) >> 1;
frameDelay = 1000 / (pages[sceneIndex].animSpeed >> 8);
SDL_BlitSurface(animation->background, NULL, canvas, &dst);
SDL_BlitSurface(animation->background, NULL, animation->scratch, NULL);
currentFrame = animation->sceneFrames;
SDL_Delay(frameDelay);

Expand All @@ -486,19 +487,19 @@ int JJ1Scene::play () {
} else {

// Upload pixel data to the surface
if (SDL_MUSTLOCK(animation->background)) SDL_LockSurface(animation->background);
if (SDL_MUSTLOCK(animation->scratch)) SDL_LockSurface(animation->scratch);

switch (currentFrame->frameType) {

case ESquareAniHeader:

loadCompactedMem(currentFrame->frameSize, currentFrame->frameData, static_cast<unsigned char*>(animation->background->pixels));
loadCompactedMem(currentFrame->frameSize, currentFrame->frameData, static_cast<unsigned char*>(animation->scratch->pixels));

break;

case EFFAniHeader:

loadFFMem(currentFrame->frameSize, currentFrame->frameData, static_cast<unsigned char*>(animation->background->pixels));
loadFFMem(currentFrame->frameSize, currentFrame->frameData, static_cast<unsigned char*>(animation->scratch->pixels));

break;

Expand All @@ -510,11 +511,11 @@ int JJ1Scene::play () {

}

if (SDL_MUSTLOCK(animation->background)) SDL_UnlockSurface(animation->background);
if (SDL_MUSTLOCK(animation->scratch)) SDL_UnlockSurface(animation->scratch);

dst.x = (canvasW - SW) >> 1;
dst.y = (canvasH - SH) >> 1;
SDL_BlitSurface(animation->background, NULL, canvas, &dst);
SDL_BlitSurface(animation->scratch, NULL, canvas, &dst);

playSound(currentFrame->soundId);

Expand Down
3 changes: 2 additions & 1 deletion src/jj1/scene/jj1scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ class JJ1SceneAnimation {
JJ1SceneFrame* sceneFrames;
JJ1SceneFrame* lastFrame;

SDL_Surface* background;
SDL_Surface* background;
SDL_Surface* scratch;
int id;
int frames;
int reverseAnimation;
Expand Down
Loading

0 comments on commit 2812de5

Please sign in to comment.