aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/sid_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/sid_extractor.c')
-rw-r--r--src/plugins/sid_extractor.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/src/plugins/sid_extractor.c b/src/plugins/sid_extractor.c
new file mode 100644
index 0000000..2465982
--- /dev/null
+++ b/src/plugins/sid_extractor.c
@@ -0,0 +1,191 @@
1/*
2 * This file is part of libextractor.
3 * (C) 2006, 2007 Toni Ruottu
4 *
5 * libextractor is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 2, or (at your
8 * option) any later version.
9 *
10 * libextractor is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with libextractor; see the file COPYING. If not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 */
21#include "platform.h"
22#include "extractor.h"
23
24
25#define SID1_HEADER_SIZE 0x76
26#define SID2_HEADER_SIZE 0x7c
27
28/* flags */
29
30#define MUSPLAYER_FLAG 0x01
31#define PLAYSID_FLAG 0x02
32#define PAL_FLAG 0x04
33#define NTSC_FLAG 0x08
34#define MOS6581_FLAG 0x10
35#define MOS8580_FLAG 0x20
36
37typedef char sidwrd[2];
38typedef char sidlongwrd[4];
39
40struct header
41{
42 char magicid[4];
43 sidwrd sidversion;
44 sidwrd dataoffset;
45 sidwrd loadaddr;
46 sidwrd initaddr;
47 sidwrd playaddr;
48 sidwrd songs;
49 sidwrd firstsong;
50 sidlongwrd speed;
51 char title[32];
52 char artist[32];
53 char copyright[32];
54 sidwrd flags; /* version 2 specific fields start */
55 char startpage;
56 char pagelength;
57 sidwrd reserved;
58};
59
60static int
61sidword (const sidwrd data)
62{
63 int value = (unsigned char) data[0] * 0x100 + (unsigned char) data[1];
64 return value;
65
66}
67
68#define ADD(s,t) do { if (0 != proc (proc_cls, "sid", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1)) return 1; } while (0)
69
70/* "extract" keyword from a SID file
71 *
72 * This plugin is based on the nsf extractor
73 *
74 */
75
76int
77EXTRACTOR_sid_extract (const char *data,
78 size_t size,
79 EXTRACTOR_MetaDataProcessor proc,
80 void *proc_cls,
81 const char *options)
82{
83 unsigned int flags;
84 int version;
85 char album[33];
86 char artist[33];
87 char copyright[33];
88 char songs[32];
89 char startingsong[32];
90 char sidversion[32];
91 const struct header *head;
92
93 /* Check header size */
94
95 if (size < SID1_HEADER_SIZE)
96 return 0;
97 head = (const struct header *) data;
98
99 /* Check "magic" id bytes */
100 if (memcmp (head->magicid, "PSID", 4) &&
101 memcmp (head->magicid, "RSID", 4))
102 return 0;
103
104 /* Mime-type */
105 ADD ("audio/prs.sid", EXTRACTOR_METATYPE_MIMETYPE);
106
107 /* Version of SID format */
108 version = sidword (head->sidversion);
109 snprintf (sidversion,
110 sizeof(sidversion),
111 "%d",
112 version);
113 ADD (sidversion, EXTRACTOR_METATYPE_FORMAT_VERSION);
114
115 /* Get song count */
116 snprintf (songs,
117 sizeof(songs),
118 "%d", sidword (head->songs));
119 ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT);
120
121 /* Get number of the first song to be played */
122 snprintf (startingsong,
123 sizeof(startingsong),
124 "%d",
125 sidword (head->firstsong));
126 ADD (startingsong, EXTRACTOR_METATYPE_STARTING_SONG);
127
128
129 /* name, artist, copyright fields */
130 memcpy (&album, head->title, 32);
131 album[32] = '\0';
132 ADD (album, EXTRACTOR_METATYPE_ALBUM);
133
134 memcpy (&artist, head->artist, 32);
135 artist[32] = '\0';
136 ADD (artist, EXTRACTOR_METATYPE_ARTIST);
137
138 memcpy (&copyright, head->copyright, 32);
139 copyright[32] = '\0';
140 ADD (copyright, EXTRACTOR_METATYPE_COPYRIGHT);
141
142
143 if ( (version < 2) || (size < SID2_HEADER_SIZE))
144 return 0;
145
146 /* Version 2 specific options follow
147 *
148 * Note: Had some troubles understanding specification
149 * on the flags in version 2. I hope this is correct.
150 */
151 flags = sidword (head->flags);
152 /* MUS data */
153 if (flags & MUSPLAYER_FLAG)
154 ADD ("Compute!'s Sidplayer", EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE);
155
156 /* PlaySID data */
157 if (flags & PLAYSID_FLAG)
158 ADD ("PlaySID", EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE);
159
160
161 /* PAL or NTSC */
162
163 if (flags & PAL_FLAG)
164 {
165 if (flags & NTSC_FLAG)
166 ADD ("PAL/NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
167 else
168 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
169 }
170 else
171 {
172 if (flags & NTSC_FLAG)
173 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
174 }
175
176 /* Detect SID Chips suitable for play the files */
177 if (flags & MOS6581_FLAG)
178 {
179 if (flags & MOS8580_FLAG)
180 ADD ("MOS6581/MOS8580", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
181 else
182 ADD ("MOS6581", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
183 }
184 else
185 {
186 if (flags & MOS8580_FLAG)
187 ADD ("MOS8580", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
188 }
189
190 return 0;
191}