head 1.2; access; symbols pkgsrc-2026Q1:1.2.0.178 pkgsrc-2026Q1-base:1.2 pkgsrc-2025Q4:1.2.0.176 pkgsrc-2025Q4-base:1.2 pkgsrc-2025Q3:1.2.0.174 pkgsrc-2025Q3-base:1.2 pkgsrc-2025Q2:1.2.0.172 pkgsrc-2025Q2-base:1.2 pkgsrc-2025Q1:1.2.0.170 pkgsrc-2025Q1-base:1.2 pkgsrc-2024Q4:1.2.0.168 pkgsrc-2024Q4-base:1.2 pkgsrc-2024Q3:1.2.0.166 pkgsrc-2024Q3-base:1.2 pkgsrc-2024Q2:1.2.0.164 pkgsrc-2024Q2-base:1.2 pkgsrc-2024Q1:1.2.0.162 pkgsrc-2024Q1-base:1.2 pkgsrc-2023Q4:1.2.0.160 pkgsrc-2023Q4-base:1.2 pkgsrc-2023Q3:1.2.0.158 pkgsrc-2023Q3-base:1.2 pkgsrc-2023Q2:1.2.0.156 pkgsrc-2023Q2-base:1.2 pkgsrc-2023Q1:1.2.0.154 pkgsrc-2023Q1-base:1.2 pkgsrc-2022Q4:1.2.0.152 pkgsrc-2022Q4-base:1.2 pkgsrc-2022Q3:1.2.0.150 pkgsrc-2022Q3-base:1.2 pkgsrc-2022Q2:1.2.0.148 pkgsrc-2022Q2-base:1.2 pkgsrc-2022Q1:1.2.0.146 pkgsrc-2022Q1-base:1.2 pkgsrc-2021Q4:1.2.0.144 pkgsrc-2021Q4-base:1.2 pkgsrc-2021Q3:1.2.0.142 pkgsrc-2021Q3-base:1.2 pkgsrc-2021Q2:1.2.0.140 pkgsrc-2021Q2-base:1.2 pkgsrc-2021Q1:1.2.0.138 pkgsrc-2021Q1-base:1.2 pkgsrc-2020Q4:1.2.0.136 pkgsrc-2020Q4-base:1.2 pkgsrc-2020Q3:1.2.0.134 pkgsrc-2020Q3-base:1.2 pkgsrc-2020Q2:1.2.0.130 pkgsrc-2020Q2-base:1.2 pkgsrc-2020Q1:1.2.0.110 pkgsrc-2020Q1-base:1.2 pkgsrc-2019Q4:1.2.0.132 pkgsrc-2019Q4-base:1.2 pkgsrc-2019Q3:1.2.0.128 pkgsrc-2019Q3-base:1.2 pkgsrc-2019Q2:1.2.0.126 pkgsrc-2019Q2-base:1.2 pkgsrc-2019Q1:1.2.0.124 pkgsrc-2019Q1-base:1.2 pkgsrc-2018Q4:1.2.0.122 pkgsrc-2018Q4-base:1.2 pkgsrc-2018Q3:1.2.0.120 pkgsrc-2018Q3-base:1.2 pkgsrc-2018Q2:1.2.0.118 pkgsrc-2018Q2-base:1.2 pkgsrc-2018Q1:1.2.0.116 pkgsrc-2018Q1-base:1.2 pkgsrc-2017Q4:1.2.0.114 pkgsrc-2017Q4-base:1.2 pkgsrc-2017Q3:1.2.0.112 pkgsrc-2017Q3-base:1.2 pkgsrc-2017Q2:1.2.0.108 pkgsrc-2017Q2-base:1.2 pkgsrc-2017Q1:1.2.0.106 pkgsrc-2017Q1-base:1.2 pkgsrc-2016Q4:1.2.0.104 pkgsrc-2016Q4-base:1.2 pkgsrc-2016Q3:1.2.0.102 pkgsrc-2016Q3-base:1.2 pkgsrc-2016Q2:1.2.0.100 pkgsrc-2016Q2-base:1.2 pkgsrc-2016Q1:1.2.0.98 pkgsrc-2016Q1-base:1.2 pkgsrc-2015Q4:1.2.0.96 pkgsrc-2015Q4-base:1.2 pkgsrc-2015Q3:1.2.0.94 pkgsrc-2015Q3-base:1.2 pkgsrc-2015Q2:1.2.0.92 pkgsrc-2015Q2-base:1.2 pkgsrc-2015Q1:1.2.0.90 pkgsrc-2015Q1-base:1.2 pkgsrc-2014Q4:1.2.0.88 pkgsrc-2014Q4-base:1.2 pkgsrc-2014Q3:1.2.0.86 pkgsrc-2014Q3-base:1.2 pkgsrc-2014Q2:1.2.0.84 pkgsrc-2014Q2-base:1.2 pkgsrc-2014Q1:1.2.0.82 pkgsrc-2014Q1-base:1.2 pkgsrc-2013Q4:1.2.0.80 pkgsrc-2013Q4-base:1.2 pkgsrc-2013Q3:1.2.0.78 pkgsrc-2013Q3-base:1.2 pkgsrc-2013Q2:1.2.0.76 pkgsrc-2013Q2-base:1.2 pkgsrc-2013Q1:1.2.0.74 pkgsrc-2013Q1-base:1.2 pkgsrc-2012Q4:1.2.0.72 pkgsrc-2012Q4-base:1.2 pkgsrc-2012Q3:1.2.0.70 pkgsrc-2012Q3-base:1.2 pkgsrc-2012Q2:1.2.0.68 pkgsrc-2012Q2-base:1.2 pkgsrc-2012Q1:1.2.0.66 pkgsrc-2012Q1-base:1.2 pkgsrc-2011Q4:1.2.0.64 pkgsrc-2011Q4-base:1.2 pkgsrc-2011Q3:1.2.0.62 pkgsrc-2011Q3-base:1.2 pkgsrc-2011Q2:1.2.0.60 pkgsrc-2011Q2-base:1.2 pkgsrc-2011Q1:1.2.0.58 pkgsrc-2011Q1-base:1.2 pkgsrc-2010Q4:1.2.0.56 pkgsrc-2010Q4-base:1.2 pkgsrc-2010Q3:1.2.0.54 pkgsrc-2010Q3-base:1.2 pkgsrc-2010Q2:1.2.0.52 pkgsrc-2010Q2-base:1.2 pkgsrc-2010Q1:1.2.0.50 pkgsrc-2010Q1-base:1.2 pkgsrc-2009Q4:1.2.0.48 pkgsrc-2009Q4-base:1.2 pkgsrc-2009Q3:1.2.0.46 pkgsrc-2009Q3-base:1.2 pkgsrc-2009Q2:1.2.0.44 pkgsrc-2009Q2-base:1.2 pkgsrc-2009Q1:1.2.0.42 pkgsrc-2009Q1-base:1.2 pkgsrc-2008Q4:1.2.0.40 pkgsrc-2008Q4-base:1.2 pkgsrc-2008Q3:1.2.0.38 pkgsrc-2008Q3-base:1.2 cube-native-xorg:1.2.0.36 cube-native-xorg-base:1.2 pkgsrc-2008Q2:1.2.0.34 pkgsrc-2008Q2-base:1.2 cwrapper:1.2.0.32 pkgsrc-2008Q1:1.2.0.30 pkgsrc-2008Q1-base:1.2 pkgsrc-2007Q4:1.2.0.28 pkgsrc-2007Q4-base:1.2 pkgsrc-2007Q3:1.2.0.26 pkgsrc-2007Q3-base:1.2 pkgsrc-2007Q2:1.2.0.24 pkgsrc-2007Q2-base:1.2 pkgsrc-2007Q1:1.2.0.22 pkgsrc-2007Q1-base:1.2 pkgsrc-2006Q4:1.2.0.20 pkgsrc-2006Q4-base:1.2 pkgsrc-2006Q3:1.2.0.18 pkgsrc-2006Q3-base:1.2 pkgsrc-2006Q2:1.2.0.16 pkgsrc-2006Q2-base:1.2 pkgsrc-2006Q1:1.2.0.14 pkgsrc-2006Q1-base:1.2 pkgsrc-2005Q4:1.2.0.12 pkgsrc-2005Q4-base:1.2 pkgsrc-2005Q3:1.2.0.10 pkgsrc-2005Q3-base:1.2 pkgsrc-2005Q2:1.2.0.8 pkgsrc-2005Q2-base:1.2 pkgsrc-2005Q1:1.2.0.6 pkgsrc-2005Q1-base:1.2 pkgsrc-2004Q4:1.2.0.4 pkgsrc-2004Q4-base:1.2 pkgsrc-2004Q3:1.2.0.2 pkgsrc-2004Q3-base:1.2 pkgsrc-base:1.1.1.1 TNF:1.1.1; locks; strict; comment @# @; 1.2 date 2004.08.15.12.13.53; author dillo; state Exp; branches; next 1.1; 1.1 date 2004.07.26.18.23.25; author dillo; state Exp; branches 1.1.1.1; next ; 1.1.1.1 date 2004.07.26.18.23.25; author dillo; state Exp; branches; next ; desc @@ 1.2 log @Add support for playing back gmv movies (recording of previously played game), based on http://bisqwit.iki.fi/src/Gens212a-moviepatch-jyzero,bisqwit.gz adapted to rc3 and cleaned up by me. More information and movies can be found at http://bisqwit.iki.fi/jutut/nesvideos/FrontPage.html Bump PKGREVISION. @ text @$NetBSD$ --- src/gens/util/chd.c.orig 2004-08-15 11:35:14.000000000 +0200 +++ src/gens/util/chd.c @@@@ -0,0 +1,400 @@@@ +/* + NiH: chd.c,v 1.6 2004/06/25 23:31:08 dillo Exp + + chd.c -- accessing chd files + Copyright (C) 2004 Dieter Baron and Thomas Klausner + + This file is part of ckmame, a program to check rom sets for MAME. + The authors can be contacted at + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#include +#include +#include +#include + +#include "chd.h" + + + +#define MAX_HEADERLEN 120 /* maximum header length */ +#define TAG "MComprHD" +#define TAG_LEN 8 /* length of tag */ +#define TAG_AND_LEN 12 /* length of tag + header length */ + +#define MAP_ENTRY_SIZE_V12 8 /* size of map entry, versions 1 & 2 */ +#define MAP_ENTRY_SIZE_V3 16 /* size of map entry, version 3 */ + +#define GET_LONG(b) (b+=4,((b)[-4]<<24)|((b)[-3]<<16)|((b)[-2]<<8)|(b)[-1]) +#define GET_QUAD(b) (b+=8,((uint64_t)(b)[-8]<<56)|((uint64_t)(b)[-7]<<48) \ + |((uint64_t)(b)[-6]<<40)|((uint64_t)(b)[-5]<<32) \ + |((uint64_t)(b)[-4]<<24)|((uint64_t)(b)[-3]<<16) \ + |((uint64_t)(b)[-2]<<8)|((uint64_t)(b)[-1])) +#define GET_SHORT(b) (b+=2,((b)[-2]<<8)|(b)[-1]) + +static int read_header(struct chd *); +static int read_map(struct chd *); + + + +void +chd_close(struct chd *chd) +{ + fclose(chd->f); + free(chd->name); + free(chd->map); + free(chd->buf); + free(chd->hbuf); + free(chd); +} + + + +struct chd * +chd_open(const char *name, int *errp) +{ + struct chd *chd; + FILE *f; + + if ((f=fopen(name, "rb")) == NULL) { + if (errp) + *errp = CHD_ERR_OPEN; + return NULL; + } + + if ((chd=malloc(sizeof(*chd))) == NULL) { + if (errp) + *errp = CHD_ERR_NOMEM; + return NULL; + } + chd->f = f; + if ((chd->name=strdup(name)) == NULL) { + if (errp) + *errp = CHD_ERR_NOMEM; + chd_close(chd); + return NULL; + } + chd->error = 0; + chd->map = NULL; + chd->buf = NULL; + chd->hno = -1; + chd->hbuf = NULL; + + if (read_header(chd) < 0) { + if (errp) + *errp = chd->error; + chd_close(chd); + return NULL; + } + + return chd; +} + + + +int +chd_read_hunk(struct chd *chd, int idx, char *b) +{ + int i, n, err; + + if (idx < 0 || idx > chd->total_hunks) { + chd->error = CHD_ERR_INVAL; + return -1; + } + + if (chd->map == NULL) { + if (read_map(chd) < 0) + return -1; + } + + if (chd->map[idx].length > chd->hunk_len) { + chd->error = CHD_ERR_NOTSUP; + return -1; + } + + switch (chd->map[idx].flags & CHD_MAP_TYPE_MASK) { + case CHD_MAP_TYPE_COMPRESSED: + /* XXX: CHD_COMP_NONE? */ + if (chd->compression != CHD_COMP_ZLIB + && chd->compression != CHD_COMP_ZLIB_PLUS) { + chd->error = CHD_ERR_NOTSUP; + return -1; + } + + if (chd->buf == NULL) { + if ((chd->buf=malloc(chd->hunk_len)) == NULL) { + chd->error = CHD_ERR_NOMEM; + return -1; + } + chd->z.avail_in = 0; + chd->z.zalloc = Z_NULL; + chd->z.zfree = Z_NULL; + chd->z.opaque = NULL; + err = inflateInit2(&chd->z, -MAX_WBITS); + } + else + err = inflateReset(&chd->z); + if (err != Z_OK) { + chd->error = CHD_ERR_ZLIB; + return -1; + } + + if (fseek(chd->f, chd->map[idx].offset, SEEK_SET) == -1) { + chd->error = CHD_ERR_SEEK; + return -1; + } + if ((n=fread(chd->buf, 1, chd->map[idx].length, chd->f)) < 0) { + chd->error = CHD_ERR_READ; + return -1; + } + + chd->z.next_in = chd->buf; + chd->z.avail_in = n; + chd->z.next_out = b; + chd->z.avail_out = chd->hunk_len; + /* XXX: should use Z_FINISH, but that returns Z_BUF_ERROR */ + if ((err=inflate(&chd->z, 0)) != Z_OK && err != Z_STREAM_END) { + chd->error = CHD_ERR_ZLIB; + return -1; + } + /* XXX: chd->z.avail_out should be 0 */ + n = chd->hunk_len - chd->z.avail_out; + break; + + case CHD_MAP_TYPE_UNCOMPRESSED: + if (fseek(chd->f, chd->map[idx].offset, SEEK_SET) == -1) { + chd->error = CHD_ERR_SEEK; + return -1; + } + /* XXX: use chd->hunk_len instead? */ + if ((n=fread(b, 1, chd->map[idx].length, chd->f)) < 0) { + chd->error = CHD_ERR_READ; + return -1; + } + break; + + case CHD_MAP_TYPE_MINI: + b[0] = (chd->map[idx].offset >> 56) & 0xff; + b[1] = (chd->map[idx].offset >> 48) & 0xff; + b[2] = (chd->map[idx].offset >> 40) & 0xff; + b[3] = (chd->map[idx].offset >> 32) & 0xff; + b[4] = (chd->map[idx].offset >> 24) & 0xff; + b[5] = (chd->map[idx].offset >> 16) & 0xff; + b[6] = (chd->map[idx].offset >> 8) & 0xff; + b[7] = chd->map[idx].offset & 0xff; + n = chd->hunk_len; + for (i=8; imap[idx].offset, b); + + case CHD_MAP_TYPE_PARENT_HUNK: + chd->error = CHD_ERR_NOTSUP; + return -1; + + default: + chd->error = CHD_ERR_NOTSUP; /* XXX: wrong error */ + return -1; + } + + if ((chd->map[idx].flags & CHD_MAP_FL_NOCRC) == 0) { + if (crc32(0, b, n) != chd->map[idx].crc) { + chd->error = CHD_ERR_CRC; + return -1; + } + } + + return n; +} + + + +int +chd_read_range(struct chd *chd, char *b, int off, int len) +{ + int i, s, n; + int copied, o2, l2; + + /* XXX: error handling */ + + s = off/chd->hunk_len; + n = (off+len+chd->hunk_len-1)/chd->hunk_len - s; + + copied = 0; + o2 = off % chd->hunk_len; + l2 = chd->hunk_len - o2; + + for (i=0; ihunk_len; + } + if (i == n-1) { + if (l2 > len-copied) + l2 = len-copied; + } + if (o2 == 0 && l2 == chd->hunk_len && s+i != chd->hno) { + if (chd_read_hunk(chd, s+i, b+copied) < 0) + return -1; + copied += chd->hunk_len; + } + else { + if (chd->hbuf == NULL) + if ((chd->hbuf=malloc(chd->hunk_len)) == NULL) { + chd->error = CHD_ERR_NOMEM; + return -1; + } + if (s+i != chd->hno) { + if (chd_read_hunk(chd, s+i, chd->hbuf) < 0) + return -1; + chd->hno = s+i; + } + memcpy(b+copied, chd->hbuf+o2, l2); + copied += l2; + } + } + + return len; +} + + + +static int +read_header(struct chd *chd) +{ + uint32_t len; + + unsigned char b[MAX_HEADERLEN], *p; + + if (fread(b, TAG_AND_LEN, 1, chd->f) != 1) { + chd->error = CHD_ERR_READ; + return -1; + } + + if (memcmp(b, TAG, TAG_LEN) != 0) { + chd->error = CHD_ERR_NO_CHD; + return -1; + } + + p = b+TAG_LEN; + len = GET_LONG(p); + if (len > MAX_HEADERLEN) { + chd->error = CHD_ERR_NO_CHD; + return -1; + } + if (fread(p, len-TAG_AND_LEN, 1, chd->f) != 1) { + chd->error = CHD_ERR_READ; + return -1; + } + + chd->hdr_length = len; + chd->version = GET_LONG(p); + chd->flags = GET_LONG(p); + chd->compression = GET_LONG(p); + + if (chd->version > 3) { + chd->error = CHD_ERR_VERSION; + return -1; + } + /* XXX: check chd->hdr_length against expected value for version */ + + if (chd->version < 3) { + chd->hunk_len = GET_LONG(p); + chd->total_hunks = GET_LONG(p); + p += 12; /* skip c/h/s */ + memcpy(chd->md5, p, sizeof(chd->md5)); + p += sizeof(chd->md5); + memcpy(chd->parent_md5, p, sizeof(chd->parent_md5)); + p += sizeof(chd->parent_md5); + + if (chd->version == 1) + chd->hunk_len *= 512; + else + chd->hunk_len *= GET_LONG(p); + chd->total_len = chd->hunk_len * chd->total_hunks; + chd->meta_offset = 0; + memset(chd->sha1, 0, sizeof(chd->sha1)); + memset(chd->parent_sha1, 0, sizeof(chd->parent_sha1)); + } + else { + chd->total_hunks = GET_LONG(p); + chd->total_len = GET_QUAD(p); + chd->meta_offset = GET_QUAD(p); + memcpy(chd->md5, p, sizeof(chd->md5)); + p += sizeof(chd->md5); + memcpy(chd->parent_md5, p, sizeof(chd->parent_md5)); + p += sizeof(chd->parent_md5); + chd->hunk_len = GET_LONG(p); + memcpy(chd->sha1, p, sizeof(chd->sha1)); + p += sizeof(chd->sha1); + } + + return 0; +} + + + +static int +read_map(struct chd *chd) +{ + unsigned char b[MAP_ENTRY_SIZE_V3], *p; + int i, len; + uint64_t v; + + if ((chd->map=malloc(sizeof(*chd->map)*chd->total_hunks)) == NULL) { + chd->error = CHD_ERR_NOMEM; + return -1; + } + + if (chd->version < 3) + len = MAP_ENTRY_SIZE_V12; + else + len = MAP_ENTRY_SIZE_V3; + + for (i=0; itotal_hunks; i++) { + if (fread(b, len, 1, chd->f) != 1) { + chd->error = CHD_ERR_READ; + return -1; + } + p = b; + + if (i == 1832) + chd->version = 3; + + if (chd->version < 3) { + v = GET_QUAD(p); + chd->map[i].offset = v & 0xFFFFFFFFFFFLL; + chd->map[i].crc = 0; + chd->map[i].length = v >> 44; + chd->map[i].flags = CHD_MAP_FL_NOCRC + | (chd->map[i].length == chd->hunk_len + ? CHD_MAP_TYPE_UNCOMPRESSED : CHD_MAP_TYPE_COMPRESSED); + } + else { + chd->map[i].offset = GET_QUAD(p); + chd->map[i].crc = GET_LONG(p); + chd->map[i].length = GET_SHORT(p); + chd->map[i].flags = GET_SHORT(p); + } + } + + return 0; +} @ 1.1 log @Initial revision @ text @d3 1 a3 1 --- src/gens/util/chd.c.orig 2004-06-25 19:55:16.000000000 +0200 @ 1.1.1.1 log @import gens 2.12rc3 from pkgsrc-wip: Gens is an emulator of Sega's 16 bit consoles: Genesis (a.k.a Megadrive) and Sega CD (a.k.a Mega CD). For Sega CD, you will need BIOS ROM images. @ text @@