static driver_return_code_t cued_read_audio(rip_context_t *rip, lsn_t firstSector, long sectors, audio_buffer_t *pbuf, int retry) { mmc_read_cd_fn readfn; uint8_t *mbuf, *dbuf; int blockSize, subchannel, i; driver_return_code_t drc; qsc_file_buffer_t qsc; blockSize = sizeof(audio_buffer_t); if (ripGetIndices || rip->qSubChannelFileName) { if (ripUseFormattedQsc) { subchannel = 2; blockSize += sizeof(qsc_buffer_t); } else { blockSize += sizeof(mmc_raw_pwsc_t); if (ripUseEccQsc) { subchannel = 4; } else { subchannel = 1; } } } else { subchannel = 0; } // TODO: should check for ripRead* be both here and in cued_rip_to_file? // does paranoia present a problem? // if (ripReadPregap && firstSector < 0) { readfn = mmc_read_cd_msf; } else if (ripReadLeadout && firstSector + sectors > rip->endOfDiscSector) { if (firstSector >= rip->endOfDiscSector) { readfn = mmc_read_cd_leadout; } else { readfn = mmc_read_cd; cdio_warn("reading lead-out"); } } else if (subchannel || ripDapFixup) { readfn = mmc_read_cd; } else { readfn = NULL; } if (sectors > rip->allocatedSectors) { free(rip->mmcBuf); rip->mmcBuf = (uint8_t *) malloc(sectors * blockSize); if (rip->mmcBuf) { rip->allocatedSectors = sectors; } else { rip->allocatedSectors = 0; cdio2_abort("out of memory reading %ld sectors", sectors); } } do { if (readfn) { drc = readfn( rip->cdObj, (pbuf && !subchannel) ? (void *) pbuf : rip->mmcBuf, firstSector, // expected read_sector_type; could be CDIO_MMC_READ_TYPE_CDDA CDIO_MMC_READ_TYPE_ANY, // DAP (Digital Audio Play) ripDapFixup ? true : false, // return SYNC header false, // header codes 0, // must return user data according to mmc5 spec true, // no EDC or ECC is included with audio data false, // C2 error information is synthetic; it is not needed to get Q sub-channel, // even though it is an adjacent field according to the standard // false, subchannel, blockSize, sectors); if (DRIVER_OP_SUCCESS == drc) { if (subchannel) { mbuf = dbuf = rip->mmcBuf; for (i = 0; i < sectors; ++i) { if (pbuf) { memcpy(pbuf[i].buf, mbuf, sizeof(audio_buffer_t)); } else { //dbuf = rip->mmcBuf + i * sizeof(audio_buffer_t); if (dbuf != mbuf) { memmove(dbuf, mbuf, sizeof(audio_buffer_t)); } dbuf += sizeof(audio_buffer_t); } mbuf += sizeof(audio_buffer_t); // if (subchannel) { if (ripUseFormattedQsc) { memcpy(&qsc.buf, mbuf, sizeof(qsc_buffer_t)); mbuf += sizeof(qsc_buffer_t); } else { pwsc_get_qsc((mmc_raw_pwsc_t *) mbuf, &qsc.buf); mbuf += sizeof(mmc_raw_pwsc_t); } if (ripGetIndices) { cued_parse_qsc(&qsc.buf, rip); } if (!ripUseParanoia && rip->qSubChannelFileName) { qsc.requested = firstSector + i; if (1 != fwrite(&qsc, sizeof(qsc), 1, rip->qSubChannelFile)) { // probably out of disk space, which is bad, because most things rely on it cdio2_unix_error("fwrite", rip->qSubChannelFileName, 0); cdio2_abort("failed to write to file \"%s\"", rip->qSubChannelFileName); } } } } return drc; } } else { drc = cdio_read_audio_sectors(rip->cdObj, pbuf ? (void *) pbuf : rip->mmcBuf, firstSector, sectors); if (DRIVER_OP_SUCCESS == drc) { return drc; } } cdio2_driver_error(drc, "read of audio sector"); } while (retry--); cdio_error("skipping extraction of audio sectors %d through %ld in track %02d", firstSector, firstSector + sectors - 1, rip->currentTrack); return drc; }
// save game as a pdn file static void savegame (gameinfo * gi) { FILE *fp; char fn[64]; char date[32]; time_t nowp; struct tm *nows; CBmove cbmove; int i, n; coor tmpCoor; // date nowp = time (NULL); nows = localtime (&nowp); strftime (date, sizeof (date), "%Y.%m.%d", nows); // check gametype tmpCoor.x = 0; tmpCoor.y = 0; if (coortonumber (gi, tmpCoor) < 0) { perror ("Unknown game type, cannot save.\n"); return; } // read filename readfn (fn); strcat (fn, ".pdn"); // create file fp = fopen (fn, "w"); if (!fp) { perror ("Game not saved\n"); perror (fn); return; } // header fprintf (fp, "[Event \"Cliche SaveGame\"]\n"); fprintf (fp, "[Date \"%s\"]\n", date); fprintf (fp, "[Black \"%s\"]\n", gi->view == BLACK ? gi->player : gi->opponent); fprintf (fp, "[White \"%s\"]\n", gi->view == WHITE ? gi->player : gi->opponent); fprintf (fp, "[GameType \"%d\"]\n", gi->gametype); // moves for (n = 1; n <= gi->nummoves; n++) { cbmove = gi->cbmoves[n]; if (n % 2) fprintf (fp, "%d. ", n / 2 + 1); if (cbmove.jumps) { fprintf (fp, "%d", coortonumber (gi, cbmove.from)); for (i = 1; i <= cbmove.jumps; i++) fprintf (fp, "x%d", coortonumber (gi, cbmove.path[i])); fprintf (fp, " "); } else fprintf (fp, "%d-%d ", coortonumber (gi, cbmove.from), coortonumber (gi, cbmove.to)); } // result switch (gi->result) { case DRAW: case BLACK: case WHITE: case UNKNOWN: fprintf (fp, "*\n"); break; } fclose (fp); printf ("Wrote game to file %s\n", fn); }