From: Alexander L. <moo...@gm...> - 2021-03-10 11:45:37
|
Hi Fredrick, Thanks for your reply! The answers are inline (and while I was answering, I realized how it's supposed to work, so in the end of this message there's a description). On 10 Mar 2021, at 07:50, Alexander Lyashuk <moo...@gm...> wrote: > > There is libspectrum_rzx_playback_frame() which seems to want to update > some pointer to a snapshot (why?), > > > Some RZX files (those that have used the RZX autosaves feature for > example) have embedded snapshots inside the file at various points. > Yeah I know that, it was a bit unexpected to see "snapshot" and "frame" in one function name. RZX file is a sequence of blocks, which can be (among other auxiliary blocks): - A snapshot block. - An input recording block. An input recording block itself is a sequence of frames, where every frame contains: - a number of instructions - a number of inputs in the frame (i.e. how many of instructions were "IN" instructions), and those inputs themselves. > and libspectrum_rzx_playback() which gets a pointer to the > libspectrum_byte, so maybe it would be able to write the inputs?.. But from > which frame/block and how does it know the size.. > > > You might find reading the RZX specs helpful if you haven’t already. > > https://web.archive.org/web/20080705124004/http://www.ramsoft.bbk.org/rzxform.html > I've seen that document indeed. I hoped to avoid needing to write a parser from the spec (although it's quite an easy format), but I believe now it's the easiest way to proceed. > I think the inputs array for a frame has libspectrum_rzx_instructions() > number of values. > It returns the total number of instructions in the frame, not the number of the IN instructions. > There is also a way to iterate over blocks, but doesn't seem to be any way > to extract any information except snapshots from the blocks.. > > > The data is probably in the array pointed to by the libspectrum_byte > pointer above. > Ok, now I've reread the rzx.c from the libspectrum, and seem to understand what's going on. For the case someone will want to do the same, here is how to use it: 1. The following function reads blocks starting from the beginning of the file, until it finds the @which'th input recording block, and then stops. If the previous block happens to be a snapshot block, it writes a pointer to that snapshot to @snap parameter. libspectrum_rzx_start_playback( libspectrum_rzx *rzx, int which, libspectrum_snap **snap ) 2. To fetch input values of the current frame, call libspectrum_rzx_playback( libspectrum_rzx *rzx, libspectrum_byte *byte ) repeatedly until it returns LIBSPECTRUM_ERROR_CORRUPT (and prints error message to console). With every call, it will output a single value of input at @byte pointer. 3. To go to the next input frame (which may happen to be in the different block), use libspectrum_rzx_playback_frame( libspectrum_rzx *rzx, int *finished, libspectrum_snap **snap ) If you've called libspectrum_rzx_playback wrong number of times for the previous frame, this function doesn't do anything and returns LIBSPECTRUM_ERROR_CORRUPT. Also if it happened to read a snapshot block while transitioning between input blocks, @snap parameter is also populated. While it's in my opinion a much less nicer API than other parts of libspectrum, it's possible to fetch the information I need. When I have enough time/enthusiasm, I'll send a patch with the following changes: 1. Add function libspectrum_rzx_inputs() to {return rzx->data_frame->count;} (so that there's no need to call libspectrum_rzx_playback until LIBSPECTRUM_ERROR_CORRUPT) 2. Move corruption detection logic from libspectrum to fuse itself, as it relies on the z80 emulation rather than purely on file format 3. Add a bit more documentation for those functions. 4. I'd like to rename functions or change API completely, but that would break other tools that depend on rzx, so I won't do that. Please suggest if you think those changes would make sense. Thanks! |