libsidplayfp  0.3.5
smm0.h
1 /***************************************************************************
2  smm0.h - sidusage file support
3  -------------------
4  begin : Tues Nov 19 2002
5  copyright : (C) 2002-2004 by Simon White
6  email : sidplay2@yahoo.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef _smm0_h_
19 #define _smm0_h_
20 
21 #include "sidplayfp/sidtypes.h"
22 #include "SidUsage.h"
23 
24 // IFF IDs
25 #define BUILD_ID(a, b, c, d) ((uint) a << 24 | \
26  (uint) b << 16 | \
27  (uint) c << 8 | \
28  (uint) d)
29 
30 #define FORM_ID BUILD_ID('F','O','R','M')
31 #define SMM0_ID BUILD_ID('S','M','M','0')
32 #define INF0_ID BUILD_ID('I','N','F','0')
33 #define ERR0_ID BUILD_ID('E','R','R','0')
34 #define TIME_ID BUILD_ID('T','I','M','E')
35 #define MD5_ID BUILD_ID('M','D','5',' ')
36 #define BODY_ID BUILD_ID('B','O','D','Y')
37 #define BXF_ID BUILD_ID('B','X','F',' ') /* Body extended flags */
38 
39 // Future Versions
40 #define SMM1_ID BUILD_ID('S','M','M','1')
41 #define SMM2_ID BUILD_ID('S','M','M','2')
42 #define SMM3_ID BUILD_ID('S','M','M','3')
43 #define SMM4_ID BUILD_ID('S','M','M','4')
44 #define SMM5_ID BUILD_ID('S','M','M','5')
45 #define SMM6_ID BUILD_ID('S','M','M','6')
46 #define SMM7_ID BUILD_ID('S','M','M','7')
47 #define SMM8_ID BUILD_ID('S','M','M','8')
48 #define SMM9_ID BUILD_ID('S','M','M','9')
49 #define SMM_EX_FLAGS (sizeof(sid_usage_t::memflags_t)-1)
50 
51 
52 class Chunk
53 {
54 private:
55  const uint_least32_t m_id;
56  const bool m_compulsory;
57  Chunk * const m_sub;
58  Chunk * const m_next;
59  bool m_used;
60 
61 private:
62  Chunk *match (uint_least32_t id);
63 
64 protected:
65  bool _read (FILE *file, uint8_t *data, uint_least32_t length, uint_least32_t &remaining);
66  bool _write (FILE *file, const uint8_t *data, uint_least32_t length, uint_least32_t &count);
67 
68  virtual void init (sid2_usage_t &usage) = 0;
69  virtual bool used (const sid2_usage_t &) { return true; }
70 
71 public:
72  Chunk(uint_least32_t id, bool compulsory, Chunk *next, Chunk *sub)
73  : m_id(id), m_compulsory(compulsory), m_sub(sub), m_next(next) {;}
74  virtual bool read (FILE *file, sid2_usage_t &usage, uint_least32_t length);
75  virtual bool write (FILE *file, const sid2_usage_t &usage, uint_least32_t &length);
76 };
77 
78 class Inf_v0: public Chunk
79 {
80 protected:
81  void init (sid2_usage_t &usage);
82 public:
83  Inf_v0(Chunk *next): Chunk(INF0_ID, true, next, 0) {;}
84  bool read (FILE *file, sid2_usage_t &usage, uint_least32_t length);
85  bool write (FILE *file, const sid2_usage_t &usage, uint_least32_t &length);
86 };
87 
88 class Err_v0: public Chunk
89 {
90 protected:
91  void init (sid2_usage_t &usage);
92 public:
93  Err_v0(Chunk *next): Chunk(ERR0_ID, false, next, 0) {;}
94  bool read (FILE *file, sid2_usage_t &usage, uint_least32_t length);
95  bool write (FILE *file, const sid2_usage_t &usage, uint_least32_t &length);
96  bool used (const sid2_usage_t &usage);
97 };
98 
99 class Md5: public Chunk
100 {
101 protected:
102  void init (sid2_usage_t &usage);
103 public:
104  Md5(Chunk *next): Chunk(MD5_ID, false, next, 0) {;}
105  bool read (FILE *file, sid2_usage_t &usage, uint_least32_t length);
106  bool write (FILE *file, const sid2_usage_t &usage, uint_least32_t &length);
107  bool used (const sid2_usage_t &usage);
108 };
109 
110 class Time: public Chunk
111 {
112 protected:
113  void init (sid2_usage_t &usage);
114 public:
115  Time(Chunk *next): Chunk(TIME_ID, false, next, 0) {;}
116  bool read (FILE *file, sid2_usage_t &usage, uint_least32_t length);
117  bool write (FILE *file, const sid2_usage_t &usage, uint_least32_t &length);
118  bool used (const sid2_usage_t &usage);
119 };
120 
121 class Body;
123 {
124 private:
125  Body &m_body;
126  uint8_t m_flags[0x100 * SMM_EX_FLAGS + 1];
127 
128 protected:
129  void init (sid2_usage_t &) {;}
130  bool recall (FILE *file, int &count, int &extension, uint_least32_t &length);
131  bool store (FILE *file, int count, int extension, uint_least32_t &length);
132 
133 public:
134  Body_extended_flags(Chunk *next, Body *body)
135  :Chunk(BXF_ID, false, next, 0),
136  m_body(*body) {;}
137  bool read (FILE *file, sid2_usage_t &usage, uint_least32_t length);
138  bool write (FILE *file, const sid2_usage_t &usage, uint_least32_t &length);
139  bool used (const sid2_usage_t &usage);
140 };
141 
142 class Body: public Chunk
143 {
144  friend class Body_extended_flags;
145 
146 private:
147  Body_extended_flags m_exflags;
148 
149  uint8_t m_pages;
150  struct usage_t
151  {
152  uint8_t page;
153  uint8_t flags[256];
154  bool extended;
155  } m_usage[256];
156 
157 protected:
158  void init (sid2_usage_t &usage);
159 
160 public:
161  Body (Chunk *next)
162  :Chunk(BODY_ID, true, next, &m_exflags),
163  m_exflags(0, this), m_pages(0) {;}
164  bool read (FILE *file, sid2_usage_t &usage, uint_least32_t length);
165  bool write (FILE *file, const sid2_usage_t &usage, uint_least32_t &length);
166 };
167 
168 // SMM0 chunk description
169 class Smm_v0: public Chunk
170 {
171 private:
172  Inf_v0 m_info;
173  Err_v0 m_error;
174  Md5 m_md5;
175  Time m_time;
176  Body m_body;
177 
178  void init (sid2_usage_t &) {;}
179 
180 public:
181  Smm_v0 (Chunk *next)
182  :Chunk(SMM0_ID, true, next, &m_info),
183  m_info(&m_error),
184  m_error(&m_md5),
185  m_md5(&m_time),
186  m_time(&m_body),
187  m_body(0) {;}
188 };
189 
190 #endif // _smm0_h_