PC-98 (PC-9821 / PC98)

Discuss other PoP1 related things here.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

David wrote: March 12th, 2022, 7:49 pmIt happens no matter how do I enter, but only the first time.
A running jump that starts to the left of the gab in the previous room, doesn't stop me. Even simple running doesn't stop me the first time entering, was my experience. I guess given your comment, I'd have to retest. I probably will once I have easy playtesting in place.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

Progress. Nothing mind blowing, mostly GUI stuff.
Guards are now shown, the events and room links screens mostly work.
Attachments
PC-98.zip
(1.13 MiB) Downloaded 89 times
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PC-98 (PC-9821 / PC98)

Post by David »

With Dev-C++ I get warnings like this:

Code: Select all

PC-98.c:3138:2: warning: implicit declaration of function 'floor' [-Wimplicit-function-declaration]
PC-98.c:3138:20: warning: incompatible implicit declaration of built-in function 'floor'
PC-98.c:4134:2: warning: implicit declaration of function 'round' [-Wimplicit-function-declaration]
PC-98.c:4134:17: warning: incompatible implicit declaration of built-in function 'round'
This already happened in the March 02 version, I just forgot to say this back then.

Adding #include <math.h> fixes the warnings.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

Progress. Saving is now half-way implemented. Unlike previous alphas, all files are now extracted+decompressed into the files/ directory. Saving a level overwrites its decompressed file. The program still lacks code to put the files back into the image. A partial tiles screen was added.
Attachments
PC-98.zip
(1.22 MiB) Downloaded 98 times
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

From my post above:
Norbert wrote: March 31st, 2022, 5:13 pmThe program still lacks code to put the files back into the image.
From that alpha's PC-98.c:

Code: Select all

  // TODO
  // Use files[] and CompressFile() to put together DISKA.
  // This includes a new directory with updated first sectors, and
  // the file allocation table.
From the current "PC-98 format" wiki page:
TODO: How to make an empty disk. How to add a file.
David, any chance you can help with this...
If I struggle and trial and error long enough, I'll probably figure out how to create the directory.
But the file allocation table particularly makes my head spin.
There is no hurry; no rush. (I have several mod ideas I can work on.)
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PC-98 (PC-9821 / PC98)

Post by David »

Norbert wrote: April 1st, 2022, 1:02 pm
TODO: How to make an empty disk. How to add a file.
David, any chance you can help with this...
If I struggle and trial and error long enough, I'll probably figure out how to create the directory.
But the file allocation table particularly makes my head spin.
There is no hurry; no rush. (I have several mod ideas I can work on.)
I extended to the format page with how to make a disk image: https://www.princed.org/wiki/PC-98_form ... from_files
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

David wrote: April 12th, 2022, 7:49 pmI extended to the format page with how to make a disk image: https://www.princed.org/wiki/PC-98_form ... from_files
Thanks a lot, I hope I'll be able to understand everything. ;)
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

I think I implemented it properly, but because of weak compression, the file allocation table exceeds 0x600 entries, overwriting the first directory entries. I'm still using the CompressFile() as included in the last alpha I attached in this topic, which has just the 0x00 head byte 'fallback'. I'll try to add 0x01 compression... Regardless, I'll post a new alpha before next weekend.
[Edit: I had to add a lot more than 0x01 compression, but I'm getting there.]
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

Norbert wrote: April 19th, 2022, 8:35 pm I think I implemented it properly, but because of weak compression, the file allocation table exceeds 0x600 entries, overwriting the first directory entries. I'm still using the CompressFile() as included in the last alpha I attached in this topic, which has just the 0x00 head byte 'fallback'. I'll try to add 0x01 compression... Regardless, I'll post a new alpha before next weekend.
[Edit: I had to add a lot more than 0x01 compression, but I'm getting there.]
Here is the new alpha. Saving now also replaces the ("A") disk image. I used David's documentation, plus an expanded CompressFile(). Also, the program can now launch the emulator, and modifies the ("A") disk image for easier playtesting. However... neither saving nor playtesting works properly. While saving creates a disk image that can be re-opened in the editor, the image no longer works in the emulator. And even without saving a custom level, the ModifyForPlaytest() modifications impact playtesting only in that the gameplay keyboard keys seem broken. I still think this alpha brings improvements, because it moves the code/program in the right direction. So, I'm happy where things are going.
Attachments
PC-98.zip
(2.32 MiB) Downloaded 105 times
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PC-98 (PC-9821 / PC98)

Post by David »

Norbert wrote: April 21st, 2022, 3:35 pm And even without saving a custom level, the ModifyForPlaytest() modifications impact playtesting only in that the gameplay keyboard keys seem broken.
In ModifyForPlaytest() and ModifyBack(), the offsets are for headered FDI images, but LSeek adds the size of the header once more.

So for example this:

Code: Select all

	LSeek (iFdA, 0x4C5F);
should be changed to this:

Code: Select all

	LSeek (iFdA, 0x4C5F - 0x1000);

Another problem I found is that np21w can't open DISK_A.FDI while the editor is running.
Maybe it's because the editor keeps the file open. As I see, iFdA is closed only when quitting.

It's annoying that the emulator gives no error message, it just doesn't put the file name of the disk image into its title bar.

Norbert wrote: April 21st, 2022, 3:35 pm While saving creates a disk image that can be re-opened in the editor, the image no longer works in the emulator.
The saved disk image is bigger than the original: 1'528'832 bytes instead of 1'265'664 bytes.
It seems np21w just won't open such oversized images. Again, there is no error message.
Additionally, the file allocation table exceeds 0x4D0 entries, which is the number of sectors on the disk.

EDIT:
A quick check reveals that all compressed files saved by the editor are bigger than the originals.
CompressFile() still needs improvement.
Alternately, you could just keep the original compressed data of all files which don't change.


EDIT: I found another bug: Files smaller than one sector will use two sectors with your code. (example: PALET.DAT)
In AddToImageFile(), the do-while loop should be a while loop.

This change will make the saved disk image 1'507'328 bytes. That's smaller than before, but still too big.
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PC-98 (PC-9821 / PC98)

Post by David »

All recompressed LEV*.CHR files begin with these bytes:
0x01, 0x81 × 4, 0xF7 × 27.
Which means:
* Repeat the last 4 bytes of the output.
* Repeat the penultimate 4 bytes of the output. × 4
* 00 00 00 00 × 27

The first two of these try to reuse bytes from before the beginning of the data.
In CompressFile(), 0x01 should only be used if (iLoopByte >= 4), and 0x81 should only be used if (iLoopByte >= 8).

I wonder why did the code choose to use 0x01 first, then 0x81, then finally 0xF7.


Also in CompressFile(), the condition of the for is: iLoopByte <= iSizeDecom.
I think it should be just "<", because sFileDecom[iSizeDecom] is already after the last used byte.


Then there are these lines:

Code: Select all

		cLastB5 = sFileCom[iSizeCom - 8];
		cLastB6 = sFileCom[iSizeCom - 7];
		cLastB7 = sFileCom[iSizeCom - 6];
		cLastB8 = sFileCom[iSizeCom - 5];
		cLastB1 = sFileCom[iSizeCom - 4];
		cLastB2 = sFileCom[iSizeCom - 3];
		cLastB3 = sFileCom[iSizeCom - 4]; // should be 2!
		cLastB4 = sFileCom[iSizeCom - 1];
They should use sFileDecom and iLoopByte, because we should compare the upcoming input bytes to the previous input bytes, not the output bytes.


After case 0x91:, the lines marked as "maybe move into for()" should indeed be moved there.


Another thing which I forgot to say yesterday:
After #include <windows.h>, I had to add #undef CopyFile, otherwise I get a compile error.
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PC-98 (PC-9821 / PC98)

Post by David »

Here is PC-98.c with all bugfixes from my previous posts.

While at it, I also added support for all compression head bytes to CompressFile().
Now all recompressed files are *smaller* than the originals!

This also means that the game finally works in the emulator after a save in the editor.
Attachments
PC-98_fixed_2022-04-24.zip
(32.22 KiB) Downloaded 96 times
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

This is really great, David! :D
I still have to read up on everything you wrote.
But there's so much progress; it's very motivating.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5745
Joined: April 9th, 2009, 10:58 pm

Re: PC-98 (PC-9821 / PC98)

Post by Norbert »

Norbert wrote: April 24th, 2022, 8:00 pm This is really great, David! :D
I still have to read up on everything you wrote.
But there's so much progress; it's very motivating.
Again, thank you. Obviously, if this ever becomes a useful program, its README will credit your wiki work and code contributions; phrased as you prefer.
David wrote: April 23rd, 2022, 10:50 pmIn ModifyForPlaytest() and ModifyBack(), the offsets are for headered FDI images, [...]
Oh, right. It's a combination of me having the file system (table) in mind, and me having overlooked your mention of TFD images, therefore misassuming all offsets mentioned in the wiki article are for headerless files.
David wrote: April 24th, 2022, 5:44 pmI wonder why did the code choose to use 0x01 first, then 0x81, then finally 0xF7.
You do? :) I simply went with a numerical order, because I have difficulty assessing exactly which compression is most effective.
David wrote: April 24th, 2022, 5:44 pmcLastB3 = sFileCom[iSizeCom - 4]; // should be 2!
Ouch (again).
David wrote: April 24th, 2022, 5:44 pmAfter case 0x91:, the lines marked as "maybe move into for()" should indeed be moved there.
May I ask whether the same goes for similar occurrences in DecompressFile() for 0x11 and 0x21?

When I modify a single tile, using the custom tile functionality on the tiles screen, levels seem to no longer save correctly. (Not just in-game, but also in-editor after restarting the program.) I've had instances that it still works, but mostly it no longer does. Perhaps your added code contains a minor bug somewhere?
Modifying 0x11 and 0x21 compression as suggested above doesn't fix it. Which, I guess, makes sense given that in-editor saving worked okay before.
Also, perhaps my CompressFile()'s "iLoopByte+=4" unjustifiedly assumes iSizeDecom is always a multiple of four. There could be spare bytes, perhaps?
I'll start by trying to understand the code you've added. Probably I'll understand most of it, and maybe I'll find a typo. [Edit: I (fully) understand everything except 0x11, 0x21 and 0x91. What I understand seems correct to me.]
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PC-98 (PC-9821 / PC98)

Post by David »

Norbert wrote: April 26th, 2022, 5:43 pm
David wrote: April 24th, 2022, 5:44 pmI wonder why did the code choose to use 0x01 first, then 0x81, then finally 0xF7.
You do? :) I simply went with a numerical order, because I have difficulty assessing exactly which compression is most effective.
I meant why did the code chose to compress the first group of four zero bytes with 0x01, the next four groups with 0x81, then the rest with 0xF7?

If I recall correctly, this fix changed it:
David wrote: April 24th, 2022, 5:44 pm They should use sFileDecom and iLoopByte, because we should compare the upcoming input bytes to the previous input bytes, not the output bytes.
With that in mind, I think I understand what the code did before that fix.
(Any bytes before the start of output are assumed to be zeroes.)
  • When the code was looking at the first group of four zeroes, it matched the last four bytes before the (empty) output. (0x01)
  • For the next four groups of zeroes, the last four bytes of the output were not four zeroes anymore, but the four bytes *before* that were four zeroes. (0x81)
  • When the output reached 5 bytes, even the penultimate four bytes were not all zeroes anymore. So the only choice was the "four zeroes" head byte. (0xF7)

Norbert wrote: April 26th, 2022, 5:43 pm
David wrote: April 24th, 2022, 5:44 pmAfter case 0x91:, the lines marked as "maybe move into for()" should indeed be moved there.
May I ask whether the same goes for similar occurrences in DecompressFile() for 0x11 and 0x21?
It does not matter there.
Since these two methods repeat the last four bytes, the last four bytes will be the same before the for loop and within it.

It matters for 0x91, because it copies from 8 bytes before, and those bytes will change in every loop.
(The copied bytes will alternate between two groups of 4 bytes.)

Norbert wrote: April 26th, 2022, 5:43 pm Also, perhaps my CompressFile()'s "iLoopByte+=4" unjustifiedly assumes iSizeDecom is always a multiple of four. There could be spare bytes, perhaps?
I think there can't be any spare bytes in the unchanged files, since their decompression resulted in a multiple of four bytes.
As of now, the only compressed files which change files are levels, and their (uncompressed) size is fixed and divisible by four.

Norbert wrote: April 26th, 2022, 5:43 pm When I modify a single tile, using the custom tile functionality on the tiles screen, levels seem to no longer save correctly.
I tried it.

I could add two floors just fine:
edited_level.png
I used the editor source I attached in my previous post, without any further changes.
Post Reply