├── COPYING ├── Doxyfile ├── Makefile ├── README.md ├── UNIF_current.txt ├── ines_convert.c ├── ines_convert.h ├── lib_ines.c ├── lib_ines.h ├── lib_unif.c ├── lib_unif.h ├── load_ines.c ├── load_ines.h ├── load_unif.c ├── load_unif.h ├── main.c ├── std_func.c ├── std_func.h ├── unif_crc32.c ├── unif_crc32.h └── unif_types.h /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Doxyfile: -------------------------------------------------------------------------------- 1 | # Doxyfile 1.7.2 2 | 3 | # This file describes the settings to be used by the documentation system 4 | # doxygen (www.doxygen.org) for a project 5 | # 6 | # All text after a hash (#) is considered a comment and will be ignored 7 | # The format is: 8 | # TAG = value [value, ...] 9 | # For lists items can also be appended using: 10 | # TAG += value [value, ...] 11 | # Values that contain spaces should be placed between quotes (" ") 12 | 13 | #--------------------------------------------------------------------------- 14 | # Project related configuration options 15 | #--------------------------------------------------------------------------- 16 | 17 | # This tag specifies the encoding used for all characters in the config file 18 | # that follow. The default is UTF-8 which is also the encoding used for all 19 | # text before the first occurrence of this tag. Doxygen uses libiconv (or the 20 | # iconv built into libc) for the transcoding. See 21 | # http://www.gnu.org/software/libiconv for the list of possible encodings. 22 | 23 | DOXYFILE_ENCODING = UTF-8 24 | 25 | # The PROJECT_NAME tag is a single word (or a sequence of words surrounded 26 | # by quotes) that should identify the project. 27 | 28 | PROJECT_NAME = libunif 29 | 30 | # The PROJECT_NUMBER tag can be used to enter a project or revision number. 31 | # This could be handy for archiving the generated documentation or 32 | # if some version control system is used. 33 | 34 | PROJECT_NUMBER = 2.1.0 35 | 36 | # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 37 | # base path where the generated documentation will be put. 38 | # If a relative path is entered, it will be relative to the location 39 | # where doxygen was started. If left blank the current directory will be used. 40 | 41 | OUTPUT_DIRECTORY = . 42 | 43 | # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 44 | # 4096 sub-directories (in 2 levels) under the output directory of each output 45 | # format and will distribute the generated files over these directories. 46 | # Enabling this option can be useful when feeding doxygen a huge amount of 47 | # source files, where putting all generated files in the same directory would 48 | # otherwise cause performance problems for the file system. 49 | 50 | CREATE_SUBDIRS = NO 51 | 52 | # The OUTPUT_LANGUAGE tag is used to specify the language in which all 53 | # documentation generated by doxygen is written. Doxygen will use this 54 | # information to generate all constant output in the proper language. 55 | # The default language is English, other supported languages are: 56 | # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 57 | # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 58 | # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 59 | # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 60 | # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, 61 | # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. 62 | 63 | OUTPUT_LANGUAGE = English 64 | 65 | # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 66 | # include brief member descriptions after the members that are listed in 67 | # the file and class documentation (similar to JavaDoc). 68 | # Set to NO to disable this. 69 | 70 | BRIEF_MEMBER_DESC = YES 71 | 72 | # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 73 | # the brief description of a member or function before the detailed description. 74 | # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 75 | # brief descriptions will be completely suppressed. 76 | 77 | REPEAT_BRIEF = YES 78 | 79 | # This tag implements a quasi-intelligent brief description abbreviator 80 | # that is used to form the text in various listings. Each string 81 | # in this list, if found as the leading text of the brief description, will be 82 | # stripped from the text and the result after processing the whole list, is 83 | # used as the annotated text. Otherwise, the brief description is used as-is. 84 | # If left blank, the following values are used ("$name" is automatically 85 | # replaced with the name of the entity): "The $name class" "The $name widget" 86 | # "The $name file" "is" "provides" "specifies" "contains" 87 | # "represents" "a" "an" "the" 88 | 89 | ABBREVIATE_BRIEF = "The $name class" \ 90 | "The $name widget" \ 91 | "The $name file" \ 92 | is \ 93 | provides \ 94 | specifies \ 95 | contains \ 96 | represents \ 97 | a \ 98 | an \ 99 | the 100 | 101 | # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 102 | # Doxygen will generate a detailed section even if there is only a brief 103 | # description. 104 | 105 | ALWAYS_DETAILED_SEC = NO 106 | 107 | # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 108 | # inherited members of a class in the documentation of that class as if those 109 | # members were ordinary class members. Constructors, destructors and assignment 110 | # operators of the base classes will not be shown. 111 | 112 | INLINE_INHERITED_MEMB = NO 113 | 114 | # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 115 | # path before files name in the file list and in the header files. If set 116 | # to NO the shortest path that makes the file name unique will be used. 117 | 118 | FULL_PATH_NAMES = NO 119 | 120 | # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 121 | # can be used to strip a user-defined part of the path. Stripping is 122 | # only done if one of the specified strings matches the left-hand part of 123 | # the path. The tag can be used to show relative paths in the file list. 124 | # If left blank the directory from which doxygen is run is used as the 125 | # path to strip. 126 | 127 | STRIP_FROM_PATH = 128 | 129 | # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 130 | # the path mentioned in the documentation of a class, which tells 131 | # the reader which header file to include in order to use a class. 132 | # If left blank only the name of the header file containing the class 133 | # definition is used. Otherwise one should specify the include paths that 134 | # are normally passed to the compiler using the -I flag. 135 | 136 | STRIP_FROM_INC_PATH = 137 | 138 | # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 139 | # (but less readable) file names. This can be useful if your file system 140 | # doesn't support long names like on DOS, Mac, or CD-ROM. 141 | 142 | SHORT_NAMES = NO 143 | 144 | # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 145 | # will interpret the first line (until the first dot) of a JavaDoc-style 146 | # comment as the brief description. If set to NO, the JavaDoc 147 | # comments will behave just like regular Qt-style comments 148 | # (thus requiring an explicit @brief command for a brief description.) 149 | 150 | JAVADOC_AUTOBRIEF = NO 151 | 152 | # If the QT_AUTOBRIEF tag is set to YES then Doxygen will 153 | # interpret the first line (until the first dot) of a Qt-style 154 | # comment as the brief description. If set to NO, the comments 155 | # will behave just like regular Qt-style comments (thus requiring 156 | # an explicit \brief command for a brief description.) 157 | 158 | QT_AUTOBRIEF = NO 159 | 160 | # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 161 | # treat a multi-line C++ special comment block (i.e. a block of //! or /// 162 | # comments) as a brief description. This used to be the default behaviour. 163 | # The new default is to treat a multi-line C++ comment block as a detailed 164 | # description. Set this tag to YES if you prefer the old behaviour instead. 165 | 166 | MULTILINE_CPP_IS_BRIEF = NO 167 | 168 | # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 169 | # member inherits the documentation from any documented member that it 170 | # re-implements. 171 | 172 | INHERIT_DOCS = YES 173 | 174 | # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 175 | # a new page for each member. If set to NO, the documentation of a member will 176 | # be part of the file/class/namespace that contains it. 177 | 178 | SEPARATE_MEMBER_PAGES = NO 179 | 180 | # The TAB_SIZE tag can be used to set the number of spaces in a tab. 181 | # Doxygen uses this value to replace tabs by spaces in code fragments. 182 | 183 | TAB_SIZE = 16 184 | 185 | # This tag can be used to specify a number of aliases that acts 186 | # as commands in the documentation. An alias has the form "name=value". 187 | # For example adding "sideeffect=\par Side Effects:\n" will allow you to 188 | # put the command \sideeffect (or @sideeffect) in the documentation, which 189 | # will result in a user-defined paragraph with heading "Side Effects:". 190 | # You can put \n's in the value part of an alias to insert newlines. 191 | 192 | ALIASES = 193 | 194 | # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 195 | # sources only. Doxygen will then generate output that is more tailored for C. 196 | # For instance, some of the names that are used will be different. The list 197 | # of all members will be omitted, etc. 198 | 199 | OPTIMIZE_OUTPUT_FOR_C = YES 200 | 201 | # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 202 | # sources only. Doxygen will then generate output that is more tailored for 203 | # Java. For instance, namespaces will be presented as packages, qualified 204 | # scopes will look different, etc. 205 | 206 | OPTIMIZE_OUTPUT_JAVA = NO 207 | 208 | # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 209 | # sources only. Doxygen will then generate output that is more tailored for 210 | # Fortran. 211 | 212 | OPTIMIZE_FOR_FORTRAN = NO 213 | 214 | # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 215 | # sources. Doxygen will then generate output that is tailored for 216 | # VHDL. 217 | 218 | OPTIMIZE_OUTPUT_VHDL = NO 219 | 220 | # Doxygen selects the parser to use depending on the extension of the files it 221 | # parses. With this tag you can assign which parser to use for a given extension. 222 | # Doxygen has a built-in mapping, but you can override or extend it using this 223 | # tag. The format is ext=language, where ext is a file extension, and language 224 | # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 225 | # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 226 | # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 227 | # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 228 | # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. 229 | 230 | EXTENSION_MAPPING = 231 | 232 | # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 233 | # to include (a tag file for) the STL sources as input, then you should 234 | # set this tag to YES in order to let doxygen match functions declarations and 235 | # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 236 | # func(std::string) {}). This also makes the inheritance and collaboration 237 | # diagrams that involve STL classes more complete and accurate. 238 | 239 | BUILTIN_STL_SUPPORT = NO 240 | 241 | # If you use Microsoft's C++/CLI language, you should set this option to YES to 242 | # enable parsing support. 243 | 244 | CPP_CLI_SUPPORT = NO 245 | 246 | # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 247 | # Doxygen will parse them like normal C++ but will assume all classes use public 248 | # instead of private inheritance when no explicit protection keyword is present. 249 | 250 | SIP_SUPPORT = NO 251 | 252 | # For Microsoft's IDL there are propget and propput attributes to indicate getter 253 | # and setter methods for a property. Setting this option to YES (the default) 254 | # will make doxygen replace the get and set methods by a property in the 255 | # documentation. This will only work if the methods are indeed getting or 256 | # setting a simple type. If this is not the case, or you want to show the 257 | # methods anyway, you should set this option to NO. 258 | 259 | IDL_PROPERTY_SUPPORT = YES 260 | 261 | # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 262 | # tag is set to YES, then doxygen will reuse the documentation of the first 263 | # member in the group (if any) for the other members of the group. By default 264 | # all members of a group must be documented explicitly. 265 | 266 | DISTRIBUTE_GROUP_DOC = NO 267 | 268 | # Set the SUBGROUPING tag to YES (the default) to allow class member groups of 269 | # the same type (for instance a group of public functions) to be put as a 270 | # subgroup of that type (e.g. under the Public Functions section). Set it to 271 | # NO to prevent subgrouping. Alternatively, this can be done per class using 272 | # the \nosubgrouping command. 273 | 274 | SUBGROUPING = YES 275 | 276 | # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 277 | # is documented as struct, union, or enum with the name of the typedef. So 278 | # typedef struct TypeS {} TypeT, will appear in the documentation as a struct 279 | # with name TypeT. When disabled the typedef will appear as a member of a file, 280 | # namespace, or class. And the struct will be named TypeS. This can typically 281 | # be useful for C code in case the coding convention dictates that all compound 282 | # types are typedef'ed and only the typedef is referenced, never the tag name. 283 | 284 | TYPEDEF_HIDES_STRUCT = NO 285 | 286 | # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 287 | # determine which symbols to keep in memory and which to flush to disk. 288 | # When the cache is full, less often used symbols will be written to disk. 289 | # For small to medium size projects (<1000 input files) the default value is 290 | # probably good enough. For larger projects a too small cache size can cause 291 | # doxygen to be busy swapping symbols to and from disk most of the time 292 | # causing a significant performance penality. 293 | # If the system has enough physical memory increasing the cache will improve the 294 | # performance by keeping more symbols in memory. Note that the value works on 295 | # a logarithmic scale so increasing the size by one will roughly double the 296 | # memory usage. The cache size is given by this formula: 297 | # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 298 | # corresponding to a cache size of 2^16 = 65536 symbols 299 | 300 | SYMBOL_CACHE_SIZE = 0 301 | 302 | #--------------------------------------------------------------------------- 303 | # Build related configuration options 304 | #--------------------------------------------------------------------------- 305 | 306 | # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 307 | # documentation are documented, even if no documentation was available. 308 | # Private class members and static file members will be hidden unless 309 | # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES 310 | 311 | EXTRACT_ALL = YES 312 | 313 | # If the EXTRACT_PRIVATE tag is set to YES all private members of a class 314 | # will be included in the documentation. 315 | 316 | EXTRACT_PRIVATE = NO 317 | 318 | # If the EXTRACT_STATIC tag is set to YES all static members of a file 319 | # will be included in the documentation. 320 | 321 | EXTRACT_STATIC = NO 322 | 323 | # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 324 | # defined locally in source files will be included in the documentation. 325 | # If set to NO only classes defined in header files are included. 326 | 327 | EXTRACT_LOCAL_CLASSES = YES 328 | 329 | # This flag is only useful for Objective-C code. When set to YES local 330 | # methods, which are defined in the implementation section but not in 331 | # the interface are included in the documentation. 332 | # If set to NO (the default) only methods in the interface are included. 333 | 334 | EXTRACT_LOCAL_METHODS = NO 335 | 336 | # If this flag is set to YES, the members of anonymous namespaces will be 337 | # extracted and appear in the documentation as a namespace called 338 | # 'anonymous_namespace{file}', where file will be replaced with the base 339 | # name of the file that contains the anonymous namespace. By default 340 | # anonymous namespaces are hidden. 341 | 342 | EXTRACT_ANON_NSPACES = NO 343 | 344 | # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 345 | # undocumented members of documented classes, files or namespaces. 346 | # If set to NO (the default) these members will be included in the 347 | # various overviews, but no documentation section is generated. 348 | # This option has no effect if EXTRACT_ALL is enabled. 349 | 350 | HIDE_UNDOC_MEMBERS = NO 351 | 352 | # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 353 | # undocumented classes that are normally visible in the class hierarchy. 354 | # If set to NO (the default) these classes will be included in the various 355 | # overviews. This option has no effect if EXTRACT_ALL is enabled. 356 | 357 | HIDE_UNDOC_CLASSES = NO 358 | 359 | # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 360 | # friend (class|struct|union) declarations. 361 | # If set to NO (the default) these declarations will be included in the 362 | # documentation. 363 | 364 | HIDE_FRIEND_COMPOUNDS = NO 365 | 366 | # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 367 | # documentation blocks found inside the body of a function. 368 | # If set to NO (the default) these blocks will be appended to the 369 | # function's detailed documentation block. 370 | 371 | HIDE_IN_BODY_DOCS = NO 372 | 373 | # The INTERNAL_DOCS tag determines if documentation 374 | # that is typed after a \internal command is included. If the tag is set 375 | # to NO (the default) then the documentation will be excluded. 376 | # Set it to YES to include the internal documentation. 377 | 378 | INTERNAL_DOCS = NO 379 | 380 | # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 381 | # file names in lower-case letters. If set to YES upper-case letters are also 382 | # allowed. This is useful if you have classes or files whose names only differ 383 | # in case and if your file system supports case sensitive file names. Windows 384 | # and Mac users are advised to set this option to NO. 385 | 386 | CASE_SENSE_NAMES = NO 387 | 388 | # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 389 | # will show members with their full class and namespace scopes in the 390 | # documentation. If set to YES the scope will be hidden. 391 | 392 | HIDE_SCOPE_NAMES = YES 393 | 394 | # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 395 | # will put a list of the files that are included by a file in the documentation 396 | # of that file. 397 | 398 | SHOW_INCLUDE_FILES = YES 399 | 400 | # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 401 | # will list include files with double quotes in the documentation 402 | # rather than with sharp brackets. 403 | 404 | FORCE_LOCAL_INCLUDES = NO 405 | 406 | # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 407 | # is inserted in the documentation for inline members. 408 | 409 | INLINE_INFO = YES 410 | 411 | # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 412 | # will sort the (detailed) documentation of file and class members 413 | # alphabetically by member name. If set to NO the members will appear in 414 | # declaration order. 415 | 416 | SORT_MEMBER_DOCS = YES 417 | 418 | # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 419 | # brief documentation of file, namespace and class members alphabetically 420 | # by member name. If set to NO (the default) the members will appear in 421 | # declaration order. 422 | 423 | SORT_BRIEF_DOCS = NO 424 | 425 | # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 426 | # will sort the (brief and detailed) documentation of class members so that 427 | # constructors and destructors are listed first. If set to NO (the default) 428 | # the constructors will appear in the respective orders defined by 429 | # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 430 | # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 431 | # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. 432 | 433 | SORT_MEMBERS_CTORS_1ST = NO 434 | 435 | # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 436 | # hierarchy of group names into alphabetical order. If set to NO (the default) 437 | # the group names will appear in their defined order. 438 | 439 | SORT_GROUP_NAMES = NO 440 | 441 | # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 442 | # sorted by fully-qualified names, including namespaces. If set to 443 | # NO (the default), the class list will be sorted only by class name, 444 | # not including the namespace part. 445 | # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 446 | # Note: This option applies only to the class list, not to the 447 | # alphabetical list. 448 | 449 | SORT_BY_SCOPE_NAME = NO 450 | 451 | # The GENERATE_TODOLIST tag can be used to enable (YES) or 452 | # disable (NO) the todo list. This list is created by putting \todo 453 | # commands in the documentation. 454 | 455 | GENERATE_TODOLIST = YES 456 | 457 | # The GENERATE_TESTLIST tag can be used to enable (YES) or 458 | # disable (NO) the test list. This list is created by putting \test 459 | # commands in the documentation. 460 | 461 | GENERATE_TESTLIST = YES 462 | 463 | # The GENERATE_BUGLIST tag can be used to enable (YES) or 464 | # disable (NO) the bug list. This list is created by putting \bug 465 | # commands in the documentation. 466 | 467 | GENERATE_BUGLIST = YES 468 | 469 | # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 470 | # disable (NO) the deprecated list. This list is created by putting 471 | # \deprecated commands in the documentation. 472 | 473 | GENERATE_DEPRECATEDLIST= YES 474 | 475 | # The ENABLED_SECTIONS tag can be used to enable conditional 476 | # documentation sections, marked by \if sectionname ... \endif. 477 | 478 | ENABLED_SECTIONS = 479 | 480 | # The MAX_INITIALIZER_LINES tag determines the maximum number of lines 481 | # the initial value of a variable or macro consists of for it to appear in 482 | # the documentation. If the initializer consists of more lines than specified 483 | # here it will be hidden. Use a value of 0 to hide initializers completely. 484 | # The appearance of the initializer of individual variables and macros in the 485 | # documentation can be controlled using \showinitializer or \hideinitializer 486 | # command in the documentation regardless of this setting. 487 | 488 | MAX_INITIALIZER_LINES = 30 489 | 490 | # Set the SHOW_USED_FILES tag to NO to disable the list of files generated 491 | # at the bottom of the documentation of classes and structs. If set to YES the 492 | # list will mention the files that were used to generate the documentation. 493 | 494 | SHOW_USED_FILES = YES 495 | 496 | # If the sources in your project are distributed over multiple directories 497 | # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 498 | # in the documentation. The default is NO. 499 | 500 | SHOW_DIRECTORIES = NO 501 | 502 | # Set the SHOW_FILES tag to NO to disable the generation of the Files page. 503 | # This will remove the Files entry from the Quick Index and from the 504 | # Folder Tree View (if specified). The default is YES. 505 | 506 | SHOW_FILES = YES 507 | 508 | # Set the SHOW_NAMESPACES tag to NO to disable the generation of the 509 | # Namespaces page. This will remove the Namespaces entry from the Quick Index 510 | # and from the Folder Tree View (if specified). The default is YES. 511 | 512 | SHOW_NAMESPACES = YES 513 | 514 | # The FILE_VERSION_FILTER tag can be used to specify a program or script that 515 | # doxygen should invoke to get the current version for each file (typically from 516 | # the version control system). Doxygen will invoke the program by executing (via 517 | # popen()) the command , where is the value of 518 | # the FILE_VERSION_FILTER tag, and is the name of an input file 519 | # provided by doxygen. Whatever the program writes to standard output 520 | # is used as the file version. See the manual for examples. 521 | 522 | FILE_VERSION_FILTER = 523 | 524 | # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 525 | # by doxygen. The layout file controls the global structure of the generated 526 | # output files in an output format independent way. The create the layout file 527 | # that represents doxygen's defaults, run doxygen with the -l option. 528 | # You can optionally specify a file name after the option, if omitted 529 | # DoxygenLayout.xml will be used as the name of the layout file. 530 | 531 | LAYOUT_FILE = 532 | 533 | #--------------------------------------------------------------------------- 534 | # configuration options related to warning and progress messages 535 | #--------------------------------------------------------------------------- 536 | 537 | # The QUIET tag can be used to turn on/off the messages that are generated 538 | # by doxygen. Possible values are YES and NO. If left blank NO is used. 539 | 540 | QUIET = NO 541 | 542 | # The WARNINGS tag can be used to turn on/off the warning messages that are 543 | # generated by doxygen. Possible values are YES and NO. If left blank 544 | # NO is used. 545 | 546 | WARNINGS = YES 547 | 548 | # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 549 | # for undocumented members. If EXTRACT_ALL is set to YES then this flag will 550 | # automatically be disabled. 551 | 552 | WARN_IF_UNDOCUMENTED = YES 553 | 554 | # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 555 | # potential errors in the documentation, such as not documenting some 556 | # parameters in a documented function, or documenting parameters that 557 | # don't exist or using markup commands wrongly. 558 | 559 | WARN_IF_DOC_ERROR = YES 560 | 561 | # The WARN_NO_PARAMDOC option can be enabled to get warnings for 562 | # functions that are documented, but have no documentation for their parameters 563 | # or return value. If set to NO (the default) doxygen will only warn about 564 | # wrong or incomplete parameter documentation, but not about the absence of 565 | # documentation. 566 | 567 | WARN_NO_PARAMDOC = NO 568 | 569 | # The WARN_FORMAT tag determines the format of the warning messages that 570 | # doxygen can produce. The string should contain the $file, $line, and $text 571 | # tags, which will be replaced by the file and line number from which the 572 | # warning originated and the warning text. Optionally the format may contain 573 | # $version, which will be replaced by the version of the file (if it could 574 | # be obtained via FILE_VERSION_FILTER) 575 | 576 | WARN_FORMAT = "$file:$line: $text" 577 | 578 | # The WARN_LOGFILE tag can be used to specify a file to which warning 579 | # and error messages should be written. If left blank the output is written 580 | # to stderr. 581 | 582 | WARN_LOGFILE = 583 | 584 | #--------------------------------------------------------------------------- 585 | # configuration options related to the input files 586 | #--------------------------------------------------------------------------- 587 | 588 | # The INPUT tag can be used to specify the files and/or directories that contain 589 | # documented source files. You may enter file names like "myfile.cpp" or 590 | # directories like "/usr/src/myproject". Separate the files or directories 591 | # with spaces. 592 | 593 | INPUT = . 594 | 595 | # This tag can be used to specify the character encoding of the source files 596 | # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 597 | # also the default input encoding. Doxygen uses libiconv (or the iconv built 598 | # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 599 | # the list of possible encodings. 600 | 601 | INPUT_ENCODING = UTF-8 602 | 603 | # If the value of the INPUT tag contains directories, you can use the 604 | # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 605 | # and *.h) to filter out the source-files in the directories. If left 606 | # blank the following patterns are tested: 607 | # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 608 | # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 609 | # *.f90 *.f *.vhd *.vhdl 610 | 611 | FILE_PATTERNS = *.c \ 612 | *.cc \ 613 | *.cxx \ 614 | *.cpp \ 615 | *.c++ \ 616 | *.d \ 617 | *.java \ 618 | *.ii \ 619 | *.ixx \ 620 | *.ipp \ 621 | *.i++ \ 622 | *.inl \ 623 | *.h \ 624 | *.hh \ 625 | *.hxx \ 626 | *.hpp \ 627 | *.h++ \ 628 | *.idl \ 629 | *.odl \ 630 | *.cs \ 631 | *.php \ 632 | *.php3 \ 633 | *.inc \ 634 | *.m \ 635 | *.mm \ 636 | *.dox \ 637 | *.py \ 638 | *.f90 \ 639 | *.f \ 640 | *.vhd \ 641 | *.vhdl 642 | 643 | # The RECURSIVE tag can be used to turn specify whether or not subdirectories 644 | # should be searched for input files as well. Possible values are YES and NO. 645 | # If left blank NO is used. 646 | 647 | RECURSIVE = YES 648 | 649 | # The EXCLUDE tag can be used to specify files and/or directories that should 650 | # excluded from the INPUT source files. This way you can easily exclude a 651 | # subdirectory from a directory tree whose root is specified with the INPUT tag. 652 | 653 | EXCLUDE = 654 | 655 | # The EXCLUDE_SYMLINKS tag can be used select whether or not files or 656 | # directories that are symbolic links (a Unix filesystem feature) are excluded 657 | # from the input. 658 | 659 | EXCLUDE_SYMLINKS = NO 660 | 661 | # If the value of the INPUT tag contains directories, you can use the 662 | # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 663 | # certain files from those directories. Note that the wildcards are matched 664 | # against the file with absolute path, so to exclude all test directories 665 | # for example use the pattern */test/* 666 | 667 | EXCLUDE_PATTERNS = 668 | 669 | # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 670 | # (namespaces, classes, functions, etc.) that should be excluded from the 671 | # output. The symbol name can be a fully qualified name, a word, or if the 672 | # wildcard * is used, a substring. Examples: ANamespace, AClass, 673 | # AClass::ANamespace, ANamespace::*Test 674 | 675 | EXCLUDE_SYMBOLS = 676 | 677 | # The EXAMPLE_PATH tag can be used to specify one or more files or 678 | # directories that contain example code fragments that are included (see 679 | # the \include command). 680 | 681 | EXAMPLE_PATH = 682 | 683 | # If the value of the EXAMPLE_PATH tag contains directories, you can use the 684 | # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 685 | # and *.h) to filter out the source-files in the directories. If left 686 | # blank all files are included. 687 | 688 | EXAMPLE_PATTERNS = * 689 | 690 | # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 691 | # searched for input files to be used with the \include or \dontinclude 692 | # commands irrespective of the value of the RECURSIVE tag. 693 | # Possible values are YES and NO. If left blank NO is used. 694 | 695 | EXAMPLE_RECURSIVE = NO 696 | 697 | # The IMAGE_PATH tag can be used to specify one or more files or 698 | # directories that contain image that are included in the documentation (see 699 | # the \image command). 700 | 701 | IMAGE_PATH = 702 | 703 | # The INPUT_FILTER tag can be used to specify a program that doxygen should 704 | # invoke to filter for each input file. Doxygen will invoke the filter program 705 | # by executing (via popen()) the command , where 706 | # is the value of the INPUT_FILTER tag, and is the name of an 707 | # input file. Doxygen will then use the output that the filter program writes 708 | # to standard output. If FILTER_PATTERNS is specified, this tag will be 709 | # ignored. 710 | 711 | INPUT_FILTER = 712 | 713 | # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 714 | # basis. Doxygen will compare the file name with each pattern and apply the 715 | # filter if there is a match. The filters are a list of the form: 716 | # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 717 | # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 718 | # is applied to all files. 719 | 720 | FILTER_PATTERNS = 721 | 722 | # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 723 | # INPUT_FILTER) will be used to filter the input files when producing source 724 | # files to browse (i.e. when SOURCE_BROWSER is set to YES). 725 | 726 | FILTER_SOURCE_FILES = NO 727 | 728 | #--------------------------------------------------------------------------- 729 | # configuration options related to source browsing 730 | #--------------------------------------------------------------------------- 731 | 732 | # If the SOURCE_BROWSER tag is set to YES then a list of source files will 733 | # be generated. Documented entities will be cross-referenced with these sources. 734 | # Note: To get rid of all source code in the generated output, make sure also 735 | # VERBATIM_HEADERS is set to NO. 736 | 737 | SOURCE_BROWSER = YES 738 | 739 | # Setting the INLINE_SOURCES tag to YES will include the body 740 | # of functions and classes directly in the documentation. 741 | 742 | INLINE_SOURCES = NO 743 | 744 | # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 745 | # doxygen to hide any special comment blocks from generated source code 746 | # fragments. Normal C and C++ comments will always remain visible. 747 | 748 | STRIP_CODE_COMMENTS = YES 749 | 750 | # If the REFERENCED_BY_RELATION tag is set to YES 751 | # then for each documented function all documented 752 | # functions referencing it will be listed. 753 | 754 | REFERENCED_BY_RELATION = NO 755 | 756 | # If the REFERENCES_RELATION tag is set to YES 757 | # then for each documented function all documented entities 758 | # called/used by that function will be listed. 759 | 760 | REFERENCES_RELATION = NO 761 | 762 | # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 763 | # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 764 | # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 765 | # link to the source code. Otherwise they will link to the documentation. 766 | 767 | REFERENCES_LINK_SOURCE = YES 768 | 769 | # If the USE_HTAGS tag is set to YES then the references to source code 770 | # will point to the HTML generated by the htags(1) tool instead of doxygen 771 | # built-in source browser. The htags tool is part of GNU's global source 772 | # tagging system (see http://www.gnu.org/software/global/global.html). You 773 | # will need version 4.8.6 or higher. 774 | 775 | USE_HTAGS = NO 776 | 777 | # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 778 | # will generate a verbatim copy of the header file for each class for 779 | # which an include is specified. Set to NO to disable this. 780 | 781 | VERBATIM_HEADERS = YES 782 | 783 | #--------------------------------------------------------------------------- 784 | # configuration options related to the alphabetical class index 785 | #--------------------------------------------------------------------------- 786 | 787 | # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 788 | # of all compounds will be generated. Enable this if the project 789 | # contains a lot of classes, structs, unions or interfaces. 790 | 791 | ALPHABETICAL_INDEX = NO 792 | 793 | # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 794 | # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 795 | # in which this list will be split (can be a number in the range [1..20]) 796 | 797 | COLS_IN_ALPHA_INDEX = 5 798 | 799 | # In case all classes in a project start with a common prefix, all 800 | # classes will be put under the same header in the alphabetical index. 801 | # The IGNORE_PREFIX tag can be used to specify one or more prefixes that 802 | # should be ignored while generating the index headers. 803 | 804 | IGNORE_PREFIX = 805 | 806 | #--------------------------------------------------------------------------- 807 | # configuration options related to the HTML output 808 | #--------------------------------------------------------------------------- 809 | 810 | # If the GENERATE_HTML tag is set to YES (the default) Doxygen will 811 | # generate HTML output. 812 | 813 | GENERATE_HTML = YES 814 | 815 | # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 816 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 817 | # put in front of it. If left blank `html' will be used as the default path. 818 | 819 | HTML_OUTPUT = html 820 | 821 | # The HTML_FILE_EXTENSION tag can be used to specify the file extension for 822 | # each generated HTML page (for example: .htm,.php,.asp). If it is left blank 823 | # doxygen will generate files with .html extension. 824 | 825 | HTML_FILE_EXTENSION = .html 826 | 827 | # The HTML_HEADER tag can be used to specify a personal HTML header for 828 | # each generated HTML page. If it is left blank doxygen will generate a 829 | # standard header. 830 | 831 | HTML_HEADER = 832 | 833 | # The HTML_FOOTER tag can be used to specify a personal HTML footer for 834 | # each generated HTML page. If it is left blank doxygen will generate a 835 | # standard footer. 836 | 837 | HTML_FOOTER = 838 | 839 | # The HTML_STYLESHEET tag can be used to specify a user-defined cascading 840 | # style sheet that is used by each HTML page. It can be used to 841 | # fine-tune the look of the HTML output. If the tag is left blank doxygen 842 | # will generate a default style sheet. Note that doxygen will try to copy 843 | # the style sheet file to the HTML output directory, so don't put your own 844 | # stylesheet in the HTML output directory as well, or it will be erased! 845 | 846 | HTML_STYLESHEET = 847 | 848 | # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 849 | # Doxygen will adjust the colors in the stylesheet and background images 850 | # according to this color. Hue is specified as an angle on a colorwheel, 851 | # see http://en.wikipedia.org/wiki/Hue for more information. 852 | # For instance the value 0 represents red, 60 is yellow, 120 is green, 853 | # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 854 | # The allowed range is 0 to 359. 855 | 856 | HTML_COLORSTYLE_HUE = 220 857 | 858 | # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 859 | # the colors in the HTML output. For a value of 0 the output will use 860 | # grayscales only. A value of 255 will produce the most vivid colors. 861 | 862 | HTML_COLORSTYLE_SAT = 100 863 | 864 | # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 865 | # the luminance component of the colors in the HTML output. Values below 866 | # 100 gradually make the output lighter, whereas values above 100 make 867 | # the output darker. The value divided by 100 is the actual gamma applied, 868 | # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 869 | # and 100 does not change the gamma. 870 | 871 | HTML_COLORSTYLE_GAMMA = 80 872 | 873 | # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 874 | # page will contain the date and time when the page was generated. Setting 875 | # this to NO can help when comparing the output of multiple runs. 876 | 877 | HTML_TIMESTAMP = YES 878 | 879 | # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 880 | # files or namespaces will be aligned in HTML using tables. If set to 881 | # NO a bullet list will be used. 882 | 883 | HTML_ALIGN_MEMBERS = YES 884 | 885 | # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 886 | # documentation will contain sections that can be hidden and shown after the 887 | # page has loaded. For this to work a browser that supports 888 | # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 889 | # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). 890 | 891 | HTML_DYNAMIC_SECTIONS = NO 892 | 893 | # If the GENERATE_DOCSET tag is set to YES, additional index files 894 | # will be generated that can be used as input for Apple's Xcode 3 895 | # integrated development environment, introduced with OSX 10.5 (Leopard). 896 | # To create a documentation set, doxygen will generate a Makefile in the 897 | # HTML output directory. Running make will produce the docset in that 898 | # directory and running "make install" will install the docset in 899 | # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 900 | # it at startup. 901 | # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 902 | # for more information. 903 | 904 | GENERATE_DOCSET = NO 905 | 906 | # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 907 | # feed. A documentation feed provides an umbrella under which multiple 908 | # documentation sets from a single provider (such as a company or product suite) 909 | # can be grouped. 910 | 911 | DOCSET_FEEDNAME = "Doxygen generated docs" 912 | 913 | # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 914 | # should uniquely identify the documentation set bundle. This should be a 915 | # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 916 | # will append .docset to the name. 917 | 918 | DOCSET_BUNDLE_ID = org.doxygen.Project 919 | 920 | # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 921 | # the documentation publisher. This should be a reverse domain-name style 922 | # string, e.g. com.mycompany.MyDocSet.documentation. 923 | 924 | DOCSET_PUBLISHER_ID = org.doxygen.Publisher 925 | 926 | # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. 927 | 928 | DOCSET_PUBLISHER_NAME = Publisher 929 | 930 | # If the GENERATE_HTMLHELP tag is set to YES, additional index files 931 | # will be generated that can be used as input for tools like the 932 | # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 933 | # of the generated HTML documentation. 934 | 935 | GENERATE_HTMLHELP = NO 936 | 937 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 938 | # be used to specify the file name of the resulting .chm file. You 939 | # can add a path in front of the file if the result should not be 940 | # written to the html output directory. 941 | 942 | CHM_FILE = 943 | 944 | # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 945 | # be used to specify the location (absolute path including file name) of 946 | # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 947 | # the HTML help compiler on the generated index.hhp. 948 | 949 | HHC_LOCATION = 950 | 951 | # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 952 | # controls if a separate .chi index file is generated (YES) or that 953 | # it should be included in the master .chm file (NO). 954 | 955 | GENERATE_CHI = NO 956 | 957 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 958 | # is used to encode HtmlHelp index (hhk), content (hhc) and project file 959 | # content. 960 | 961 | CHM_INDEX_ENCODING = 962 | 963 | # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 964 | # controls whether a binary table of contents is generated (YES) or a 965 | # normal table of contents (NO) in the .chm file. 966 | 967 | BINARY_TOC = NO 968 | 969 | # The TOC_EXPAND flag can be set to YES to add extra items for group members 970 | # to the contents of the HTML help documentation and to the tree view. 971 | 972 | TOC_EXPAND = NO 973 | 974 | # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 975 | # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 976 | # that can be used as input for Qt's qhelpgenerator to generate a 977 | # Qt Compressed Help (.qch) of the generated HTML documentation. 978 | 979 | GENERATE_QHP = NO 980 | 981 | # If the QHG_LOCATION tag is specified, the QCH_FILE tag can 982 | # be used to specify the file name of the resulting .qch file. 983 | # The path specified is relative to the HTML output folder. 984 | 985 | QCH_FILE = 986 | 987 | # The QHP_NAMESPACE tag specifies the namespace to use when generating 988 | # Qt Help Project output. For more information please see 989 | # http://doc.trolltech.com/qthelpproject.html#namespace 990 | 991 | QHP_NAMESPACE = org.doxygen.Project 992 | 993 | # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 994 | # Qt Help Project output. For more information please see 995 | # http://doc.trolltech.com/qthelpproject.html#virtual-folders 996 | 997 | QHP_VIRTUAL_FOLDER = doc 998 | 999 | # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 1000 | # add. For more information please see 1001 | # http://doc.trolltech.com/qthelpproject.html#custom-filters 1002 | 1003 | QHP_CUST_FILTER_NAME = 1004 | 1005 | # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 1006 | # custom filter to add. For more information please see 1007 | # 1008 | # Qt Help Project / Custom Filters. 1009 | 1010 | QHP_CUST_FILTER_ATTRS = 1011 | 1012 | # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 1013 | # project's 1014 | # filter section matches. 1015 | # 1016 | # Qt Help Project / Filter Attributes. 1017 | 1018 | QHP_SECT_FILTER_ATTRS = 1019 | 1020 | # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 1021 | # be used to specify the location of Qt's qhelpgenerator. 1022 | # If non-empty doxygen will try to run qhelpgenerator on the generated 1023 | # .qhp file. 1024 | 1025 | QHG_LOCATION = 1026 | 1027 | # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files 1028 | # will be generated, which together with the HTML files, form an Eclipse help 1029 | # plugin. To install this plugin and make it available under the help contents 1030 | # menu in Eclipse, the contents of the directory containing the HTML and XML 1031 | # files needs to be copied into the plugins directory of eclipse. The name of 1032 | # the directory within the plugins directory should be the same as 1033 | # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 1034 | # the help appears. 1035 | 1036 | GENERATE_ECLIPSEHELP = NO 1037 | 1038 | # A unique identifier for the eclipse help plugin. When installing the plugin 1039 | # the directory name containing the HTML and XML files should also have 1040 | # this name. 1041 | 1042 | ECLIPSE_DOC_ID = org.doxygen.Project 1043 | 1044 | # The DISABLE_INDEX tag can be used to turn on/off the condensed index at 1045 | # top of each HTML page. The value NO (the default) enables the index and 1046 | # the value YES disables it. 1047 | 1048 | DISABLE_INDEX = NO 1049 | 1050 | # This tag can be used to set the number of enum values (range [0,1..20]) 1051 | # that doxygen will group on one line in the generated HTML documentation. 1052 | # Note that a value of 0 will completely suppress the enum values from 1053 | # appearing in the overview section. 1054 | 1055 | ENUM_VALUES_PER_LINE = 4 1056 | 1057 | # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 1058 | # structure should be generated to display hierarchical information. 1059 | # If the tag value is set to YES, a side panel will be generated 1060 | # containing a tree-like index structure (just like the one that 1061 | # is generated for HTML Help). For this to work a browser that supports 1062 | # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 1063 | # Windows users are probably better off using the HTML help feature. 1064 | 1065 | GENERATE_TREEVIEW = NO 1066 | 1067 | # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 1068 | # and Class Hierarchy pages using a tree view instead of an ordered list. 1069 | 1070 | USE_INLINE_TREES = NO 1071 | 1072 | # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 1073 | # used to set the initial width (in pixels) of the frame in which the tree 1074 | # is shown. 1075 | 1076 | TREEVIEW_WIDTH = 250 1077 | 1078 | # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 1079 | # links to external symbols imported via tag files in a separate window. 1080 | 1081 | EXT_LINKS_IN_WINDOW = NO 1082 | 1083 | # Use this tag to change the font size of Latex formulas included 1084 | # as images in the HTML documentation. The default is 10. Note that 1085 | # when you change the font size after a successful doxygen run you need 1086 | # to manually remove any form_*.png images from the HTML output directory 1087 | # to force them to be regenerated. 1088 | 1089 | FORMULA_FONTSIZE = 10 1090 | 1091 | # Use the FORMULA_TRANPARENT tag to determine whether or not the images 1092 | # generated for formulas are transparent PNGs. Transparent PNGs are 1093 | # not supported properly for IE 6.0, but are supported on all modern browsers. 1094 | # Note that when changing this option you need to delete any form_*.png files 1095 | # in the HTML output before the changes have effect. 1096 | 1097 | FORMULA_TRANSPARENT = YES 1098 | 1099 | # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 1100 | # (see http://www.mathjax.org) which uses client side Javascript for the 1101 | # rendering instead of using prerendered bitmaps. Use this if you do not 1102 | # have LaTeX installed or if you want to formulas look prettier in the HTML 1103 | # output. When enabled you also need to install MathJax separately and 1104 | # configure the path to it using the MATHJAX_RELPATH option. 1105 | 1106 | USE_MATHJAX = NO 1107 | 1108 | # When MathJax is enabled you need to specify the location relative to the 1109 | # HTML output directory using the MATHJAX_RELPATH option. The destination 1110 | # directory should contain the MathJax.js script. For instance, if the mathjax 1111 | # directory is located at the same level as the HTML output directory, then 1112 | # MATHJAX_RELPATH should be ../mathjax. The default value points to the 1113 | # mathjax.org site, so you can quickly see the result without installing 1114 | # MathJax, but it is strongly recommended to install a local copy of MathJax 1115 | # before deployment. 1116 | 1117 | MATHJAX_RELPATH = http://www.mathjax.org/mathjax 1118 | 1119 | # When the SEARCHENGINE tag is enabled doxygen will generate a search box 1120 | # for the HTML output. The underlying search engine uses javascript 1121 | # and DHTML and should work on any modern browser. Note that when using 1122 | # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 1123 | # (GENERATE_DOCSET) there is already a search function so this one should 1124 | # typically be disabled. For large projects the javascript based search engine 1125 | # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. 1126 | 1127 | SEARCHENGINE = YES 1128 | 1129 | # When the SERVER_BASED_SEARCH tag is enabled the search engine will be 1130 | # implemented using a PHP enabled web server instead of at the web client 1131 | # using Javascript. Doxygen will generate the search PHP script and index 1132 | # file to put on the web server. The advantage of the server 1133 | # based approach is that it scales better to large projects and allows 1134 | # full text search. The disadvantages are that it is more difficult to setup 1135 | # and does not have live searching capabilities. 1136 | 1137 | SERVER_BASED_SEARCH = NO 1138 | 1139 | #--------------------------------------------------------------------------- 1140 | # configuration options related to the LaTeX output 1141 | #--------------------------------------------------------------------------- 1142 | 1143 | # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 1144 | # generate Latex output. 1145 | 1146 | GENERATE_LATEX = NO 1147 | 1148 | # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 1149 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1150 | # put in front of it. If left blank `latex' will be used as the default path. 1151 | 1152 | LATEX_OUTPUT = latex 1153 | 1154 | # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 1155 | # invoked. If left blank `latex' will be used as the default command name. 1156 | # Note that when enabling USE_PDFLATEX this option is only used for 1157 | # generating bitmaps for formulas in the HTML output, but not in the 1158 | # Makefile that is written to the output directory. 1159 | 1160 | LATEX_CMD_NAME = latex 1161 | 1162 | # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 1163 | # generate index for LaTeX. If left blank `makeindex' will be used as the 1164 | # default command name. 1165 | 1166 | MAKEINDEX_CMD_NAME = makeindex 1167 | 1168 | # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 1169 | # LaTeX documents. This may be useful for small projects and may help to 1170 | # save some trees in general. 1171 | 1172 | COMPACT_LATEX = NO 1173 | 1174 | # The PAPER_TYPE tag can be used to set the paper type that is used 1175 | # by the printer. Possible values are: a4, letter, legal and 1176 | # executive. If left blank a4wide will be used. 1177 | 1178 | PAPER_TYPE = a4wide 1179 | 1180 | # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 1181 | # packages that should be included in the LaTeX output. 1182 | 1183 | EXTRA_PACKAGES = 1184 | 1185 | # The LATEX_HEADER tag can be used to specify a personal LaTeX header for 1186 | # the generated latex document. The header should contain everything until 1187 | # the first chapter. If it is left blank doxygen will generate a 1188 | # standard header. Notice: only use this tag if you know what you are doing! 1189 | 1190 | LATEX_HEADER = 1191 | 1192 | # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 1193 | # is prepared for conversion to pdf (using ps2pdf). The pdf file will 1194 | # contain links (just like the HTML output) instead of page references 1195 | # This makes the output suitable for online browsing using a pdf viewer. 1196 | 1197 | PDF_HYPERLINKS = YES 1198 | 1199 | # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 1200 | # plain latex in the generated Makefile. Set this option to YES to get a 1201 | # higher quality PDF documentation. 1202 | 1203 | USE_PDFLATEX = YES 1204 | 1205 | # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 1206 | # command to the generated LaTeX files. This will instruct LaTeX to keep 1207 | # running if errors occur, instead of asking the user for help. 1208 | # This option is also used when generating formulas in HTML. 1209 | 1210 | LATEX_BATCHMODE = NO 1211 | 1212 | # If LATEX_HIDE_INDICES is set to YES then doxygen will not 1213 | # include the index chapters (such as File Index, Compound Index, etc.) 1214 | # in the output. 1215 | 1216 | LATEX_HIDE_INDICES = NO 1217 | 1218 | # If LATEX_SOURCE_CODE is set to YES then doxygen will include 1219 | # source code with syntax highlighting in the LaTeX output. 1220 | # Note that which sources are shown also depends on other settings 1221 | # such as SOURCE_BROWSER. 1222 | 1223 | LATEX_SOURCE_CODE = NO 1224 | 1225 | #--------------------------------------------------------------------------- 1226 | # configuration options related to the RTF output 1227 | #--------------------------------------------------------------------------- 1228 | 1229 | # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 1230 | # The RTF output is optimized for Word 97 and may not look very pretty with 1231 | # other RTF readers or editors. 1232 | 1233 | GENERATE_RTF = NO 1234 | 1235 | # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 1236 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1237 | # put in front of it. If left blank `rtf' will be used as the default path. 1238 | 1239 | RTF_OUTPUT = rtf 1240 | 1241 | # If the COMPACT_RTF tag is set to YES Doxygen generates more compact 1242 | # RTF documents. This may be useful for small projects and may help to 1243 | # save some trees in general. 1244 | 1245 | COMPACT_RTF = NO 1246 | 1247 | # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 1248 | # will contain hyperlink fields. The RTF file will 1249 | # contain links (just like the HTML output) instead of page references. 1250 | # This makes the output suitable for online browsing using WORD or other 1251 | # programs which support those fields. 1252 | # Note: wordpad (write) and others do not support links. 1253 | 1254 | RTF_HYPERLINKS = NO 1255 | 1256 | # Load stylesheet definitions from file. Syntax is similar to doxygen's 1257 | # config file, i.e. a series of assignments. You only have to provide 1258 | # replacements, missing definitions are set to their default value. 1259 | 1260 | RTF_STYLESHEET_FILE = 1261 | 1262 | # Set optional variables used in the generation of an rtf document. 1263 | # Syntax is similar to doxygen's config file. 1264 | 1265 | RTF_EXTENSIONS_FILE = 1266 | 1267 | #--------------------------------------------------------------------------- 1268 | # configuration options related to the man page output 1269 | #--------------------------------------------------------------------------- 1270 | 1271 | # If the GENERATE_MAN tag is set to YES (the default) Doxygen will 1272 | # generate man pages 1273 | 1274 | GENERATE_MAN = NO 1275 | 1276 | # The MAN_OUTPUT tag is used to specify where the man pages will be put. 1277 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1278 | # put in front of it. If left blank `man' will be used as the default path. 1279 | 1280 | MAN_OUTPUT = man 1281 | 1282 | # The MAN_EXTENSION tag determines the extension that is added to 1283 | # the generated man pages (default is the subroutine's section .3) 1284 | 1285 | MAN_EXTENSION = .3 1286 | 1287 | # If the MAN_LINKS tag is set to YES and Doxygen generates man output, 1288 | # then it will generate one additional man file for each entity 1289 | # documented in the real man page(s). These additional files 1290 | # only source the real man page, but without them the man command 1291 | # would be unable to find the correct page. The default is NO. 1292 | 1293 | MAN_LINKS = NO 1294 | 1295 | #--------------------------------------------------------------------------- 1296 | # configuration options related to the XML output 1297 | #--------------------------------------------------------------------------- 1298 | 1299 | # If the GENERATE_XML tag is set to YES Doxygen will 1300 | # generate an XML file that captures the structure of 1301 | # the code including all documentation. 1302 | 1303 | GENERATE_XML = NO 1304 | 1305 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. 1306 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1307 | # put in front of it. If left blank `xml' will be used as the default path. 1308 | 1309 | XML_OUTPUT = xml 1310 | 1311 | # The XML_SCHEMA tag can be used to specify an XML schema, 1312 | # which can be used by a validating XML parser to check the 1313 | # syntax of the XML files. 1314 | 1315 | XML_SCHEMA = 1316 | 1317 | # The XML_DTD tag can be used to specify an XML DTD, 1318 | # which can be used by a validating XML parser to check the 1319 | # syntax of the XML files. 1320 | 1321 | XML_DTD = 1322 | 1323 | # If the XML_PROGRAMLISTING tag is set to YES Doxygen will 1324 | # dump the program listings (including syntax highlighting 1325 | # and cross-referencing information) to the XML output. Note that 1326 | # enabling this will significantly increase the size of the XML output. 1327 | 1328 | XML_PROGRAMLISTING = YES 1329 | 1330 | #--------------------------------------------------------------------------- 1331 | # configuration options for the AutoGen Definitions output 1332 | #--------------------------------------------------------------------------- 1333 | 1334 | # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 1335 | # generate an AutoGen Definitions (see autogen.sf.net) file 1336 | # that captures the structure of the code including all 1337 | # documentation. Note that this feature is still experimental 1338 | # and incomplete at the moment. 1339 | 1340 | GENERATE_AUTOGEN_DEF = NO 1341 | 1342 | #--------------------------------------------------------------------------- 1343 | # configuration options related to the Perl module output 1344 | #--------------------------------------------------------------------------- 1345 | 1346 | # If the GENERATE_PERLMOD tag is set to YES Doxygen will 1347 | # generate a Perl module file that captures the structure of 1348 | # the code including all documentation. Note that this 1349 | # feature is still experimental and incomplete at the 1350 | # moment. 1351 | 1352 | GENERATE_PERLMOD = NO 1353 | 1354 | # If the PERLMOD_LATEX tag is set to YES Doxygen will generate 1355 | # the necessary Makefile rules, Perl scripts and LaTeX code to be able 1356 | # to generate PDF and DVI output from the Perl module output. 1357 | 1358 | PERLMOD_LATEX = NO 1359 | 1360 | # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 1361 | # nicely formatted so it can be parsed by a human reader. This is useful 1362 | # if you want to understand what is going on. On the other hand, if this 1363 | # tag is set to NO the size of the Perl module output will be much smaller 1364 | # and Perl will parse it just the same. 1365 | 1366 | PERLMOD_PRETTY = YES 1367 | 1368 | # The names of the make variables in the generated doxyrules.make file 1369 | # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 1370 | # This is useful so different doxyrules.make files included by the same 1371 | # Makefile don't overwrite each other's variables. 1372 | 1373 | PERLMOD_MAKEVAR_PREFIX = 1374 | 1375 | #--------------------------------------------------------------------------- 1376 | # Configuration options related to the preprocessor 1377 | #--------------------------------------------------------------------------- 1378 | 1379 | # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 1380 | # evaluate all C-preprocessor directives found in the sources and include 1381 | # files. 1382 | 1383 | ENABLE_PREPROCESSING = YES 1384 | 1385 | # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 1386 | # names in the source code. If set to NO (the default) only conditional 1387 | # compilation will be performed. Macro expansion can be done in a controlled 1388 | # way by setting EXPAND_ONLY_PREDEF to YES. 1389 | 1390 | MACRO_EXPANSION = NO 1391 | 1392 | # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 1393 | # then the macro expansion is limited to the macros specified with the 1394 | # PREDEFINED and EXPAND_AS_DEFINED tags. 1395 | 1396 | EXPAND_ONLY_PREDEF = NO 1397 | 1398 | # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 1399 | # in the INCLUDE_PATH (see below) will be search if a #include is found. 1400 | 1401 | SEARCH_INCLUDES = YES 1402 | 1403 | # The INCLUDE_PATH tag can be used to specify one or more directories that 1404 | # contain include files that are not input files but should be processed by 1405 | # the preprocessor. 1406 | 1407 | INCLUDE_PATH = 1408 | 1409 | # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 1410 | # patterns (like *.h and *.hpp) to filter out the header-files in the 1411 | # directories. If left blank, the patterns specified with FILE_PATTERNS will 1412 | # be used. 1413 | 1414 | INCLUDE_FILE_PATTERNS = 1415 | 1416 | # The PREDEFINED tag can be used to specify one or more macro names that 1417 | # are defined before the preprocessor is started (similar to the -D option of 1418 | # gcc). The argument of the tag is a list of macros of the form: name 1419 | # or name=definition (no spaces). If the definition and the = are 1420 | # omitted =1 is assumed. To prevent a macro definition from being 1421 | # undefined via #undef or recursively expanded use the := operator 1422 | # instead of the = operator. 1423 | 1424 | PREDEFINED = 1425 | 1426 | # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 1427 | # this tag can be used to specify a list of macro names that should be expanded. 1428 | # The macro definition that is found in the sources will be used. 1429 | # Use the PREDEFINED tag if you want to use a different macro definition. 1430 | 1431 | EXPAND_AS_DEFINED = 1432 | 1433 | # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 1434 | # doxygen's preprocessor will remove all function-like macros that are alone 1435 | # on a line, have an all uppercase name, and do not end with a semicolon. Such 1436 | # function macros are typically used for boiler-plate code, and will confuse 1437 | # the parser if not removed. 1438 | 1439 | SKIP_FUNCTION_MACROS = YES 1440 | 1441 | #--------------------------------------------------------------------------- 1442 | # Configuration::additions related to external references 1443 | #--------------------------------------------------------------------------- 1444 | 1445 | # The TAGFILES option can be used to specify one or more tagfiles. 1446 | # Optionally an initial location of the external documentation 1447 | # can be added for each tagfile. The format of a tag file without 1448 | # this location is as follows: 1449 | # TAGFILES = file1 file2 ... 1450 | # Adding location for the tag files is done as follows: 1451 | # TAGFILES = file1=loc1 "file2 = loc2" ... 1452 | # where "loc1" and "loc2" can be relative or absolute paths or 1453 | # URLs. If a location is present for each tag, the installdox tool 1454 | # does not have to be run to correct the links. 1455 | # Note that each tag file must have a unique name 1456 | # (where the name does NOT include the path) 1457 | # If a tag file is not located in the directory in which doxygen 1458 | # is run, you must also specify the path to the tagfile here. 1459 | 1460 | TAGFILES = 1461 | 1462 | # When a file name is specified after GENERATE_TAGFILE, doxygen will create 1463 | # a tag file that is based on the input files it reads. 1464 | 1465 | GENERATE_TAGFILE = 1466 | 1467 | # If the ALLEXTERNALS tag is set to YES all external classes will be listed 1468 | # in the class index. If set to NO only the inherited external classes 1469 | # will be listed. 1470 | 1471 | ALLEXTERNALS = NO 1472 | 1473 | # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 1474 | # in the modules index. If set to NO, only the current project's groups will 1475 | # be listed. 1476 | 1477 | EXTERNAL_GROUPS = YES 1478 | 1479 | # The PERL_PATH should be the absolute path and name of the perl script 1480 | # interpreter (i.e. the result of `which perl'). 1481 | 1482 | PERL_PATH = /usr/bin/perl 1483 | 1484 | #--------------------------------------------------------------------------- 1485 | # Configuration options related to the dot tool 1486 | #--------------------------------------------------------------------------- 1487 | 1488 | # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 1489 | # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 1490 | # or super classes. Setting the tag to NO turns the diagrams off. Note that 1491 | # this option also works with HAVE_DOT disabled, but it is recommended to 1492 | # install and use dot, since it yields more powerful graphs. 1493 | 1494 | CLASS_DIAGRAMS = NO 1495 | 1496 | # You can define message sequence charts within doxygen comments using the \msc 1497 | # command. Doxygen will then run the mscgen tool (see 1498 | # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 1499 | # documentation. The MSCGEN_PATH tag allows you to specify the directory where 1500 | # the mscgen tool resides. If left empty the tool is assumed to be found in the 1501 | # default search path. 1502 | 1503 | MSCGEN_PATH = 1504 | 1505 | # If set to YES, the inheritance and collaboration graphs will hide 1506 | # inheritance and usage relations if the target is undocumented 1507 | # or is not a class. 1508 | 1509 | HIDE_UNDOC_RELATIONS = YES 1510 | 1511 | # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 1512 | # available from the path. This tool is part of Graphviz, a graph visualization 1513 | # toolkit from AT&T and Lucent Bell Labs. The other options in this section 1514 | # have no effect if this option is set to NO (the default) 1515 | 1516 | HAVE_DOT = YES 1517 | 1518 | # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 1519 | # allowed to run in parallel. When set to 0 (the default) doxygen will 1520 | # base this on the number of processors available in the system. You can set it 1521 | # explicitly to a value larger than 0 to get control over the balance 1522 | # between CPU load and processing speed. 1523 | 1524 | DOT_NUM_THREADS = 0 1525 | 1526 | # By default doxygen will write a font called FreeSans.ttf to the output 1527 | # directory and reference it in all dot files that doxygen generates. This 1528 | # font does not include all possible unicode characters however, so when you need 1529 | # these (or just want a differently looking font) you can specify the font name 1530 | # using DOT_FONTNAME. You need need to make sure dot is able to find the font, 1531 | # which can be done by putting it in a standard location or by setting the 1532 | # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 1533 | # containing the font. 1534 | 1535 | DOT_FONTNAME = FreeSans 1536 | 1537 | # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 1538 | # The default size is 10pt. 1539 | 1540 | DOT_FONTSIZE = 10 1541 | 1542 | # By default doxygen will tell dot to use the output directory to look for the 1543 | # FreeSans.ttf font (which doxygen will put there itself). If you specify a 1544 | # different font using DOT_FONTNAME you can set the path where dot 1545 | # can find it using this tag. 1546 | 1547 | DOT_FONTPATH = 1548 | 1549 | # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 1550 | # will generate a graph for each documented class showing the direct and 1551 | # indirect inheritance relations. Setting this tag to YES will force the 1552 | # the CLASS_DIAGRAMS tag to NO. 1553 | 1554 | CLASS_GRAPH = YES 1555 | 1556 | # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 1557 | # will generate a graph for each documented class showing the direct and 1558 | # indirect implementation dependencies (inheritance, containment, and 1559 | # class references variables) of the class with other documented classes. 1560 | 1561 | COLLABORATION_GRAPH = YES 1562 | 1563 | # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 1564 | # will generate a graph for groups, showing the direct groups dependencies 1565 | 1566 | GROUP_GRAPHS = YES 1567 | 1568 | # If the UML_LOOK tag is set to YES doxygen will generate inheritance and 1569 | # collaboration diagrams in a style similar to the OMG's Unified Modeling 1570 | # Language. 1571 | 1572 | UML_LOOK = NO 1573 | 1574 | # If set to YES, the inheritance and collaboration graphs will show the 1575 | # relations between templates and their instances. 1576 | 1577 | TEMPLATE_RELATIONS = NO 1578 | 1579 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 1580 | # tags are set to YES then doxygen will generate a graph for each documented 1581 | # file showing the direct and indirect include dependencies of the file with 1582 | # other documented files. 1583 | 1584 | INCLUDE_GRAPH = YES 1585 | 1586 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 1587 | # HAVE_DOT tags are set to YES then doxygen will generate a graph for each 1588 | # documented header file showing the documented files that directly or 1589 | # indirectly include this file. 1590 | 1591 | INCLUDED_BY_GRAPH = YES 1592 | 1593 | # If the CALL_GRAPH and HAVE_DOT options are set to YES then 1594 | # doxygen will generate a call dependency graph for every global function 1595 | # or class method. Note that enabling this option will significantly increase 1596 | # the time of a run. So in most cases it will be better to enable call graphs 1597 | # for selected functions only using the \callgraph command. 1598 | 1599 | CALL_GRAPH = YES 1600 | 1601 | # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 1602 | # doxygen will generate a caller dependency graph for every global function 1603 | # or class method. Note that enabling this option will significantly increase 1604 | # the time of a run. So in most cases it will be better to enable caller 1605 | # graphs for selected functions only using the \callergraph command. 1606 | 1607 | CALLER_GRAPH = YES 1608 | 1609 | # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 1610 | # will generate a graphical hierarchy of all classes instead of a textual one. 1611 | 1612 | GRAPHICAL_HIERARCHY = YES 1613 | 1614 | # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 1615 | # then doxygen will show the dependencies a directory has on other directories 1616 | # in a graphical way. The dependency relations are determined by the #include 1617 | # relations between the files in the directories. 1618 | 1619 | DIRECTORY_GRAPH = YES 1620 | 1621 | # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 1622 | # generated by dot. Possible values are png, jpg, or gif. 1623 | # If left blank png will be used. 1624 | 1625 | DOT_IMAGE_FORMAT = png 1626 | 1627 | # The tag DOT_PATH can be used to specify the path where the dot tool can be 1628 | # found. If left blank, it is assumed the dot tool can be found in the path. 1629 | 1630 | DOT_PATH = 1631 | 1632 | # The DOTFILE_DIRS tag can be used to specify one or more directories that 1633 | # contain dot files that are included in the documentation (see the 1634 | # \dotfile command). 1635 | 1636 | DOTFILE_DIRS = 1637 | 1638 | # The MSCFILE_DIRS tag can be used to specify one or more directories that 1639 | # contain msc files that are included in the documentation (see the 1640 | # \mscfile command). 1641 | 1642 | MSCFILE_DIRS = 1643 | 1644 | # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 1645 | # nodes that will be shown in the graph. If the number of nodes in a graph 1646 | # becomes larger than this value, doxygen will truncate the graph, which is 1647 | # visualized by representing a node as a red box. Note that doxygen if the 1648 | # number of direct children of the root node in a graph is already larger than 1649 | # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 1650 | # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. 1651 | 1652 | DOT_GRAPH_MAX_NODES = 50 1653 | 1654 | # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 1655 | # graphs generated by dot. A depth value of 3 means that only nodes reachable 1656 | # from the root by following a path via at most 3 edges will be shown. Nodes 1657 | # that lay further from the root node will be omitted. Note that setting this 1658 | # option to 1 or 2 may greatly reduce the computation time needed for large 1659 | # code bases. Also note that the size of a graph can be further restricted by 1660 | # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. 1661 | 1662 | MAX_DOT_GRAPH_DEPTH = 0 1663 | 1664 | # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 1665 | # background. This is disabled by default, because dot on Windows does not 1666 | # seem to support this out of the box. Warning: Depending on the platform used, 1667 | # enabling this option may lead to badly anti-aliased labels on the edges of 1668 | # a graph (i.e. they become hard to read). 1669 | 1670 | DOT_TRANSPARENT = NO 1671 | 1672 | # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 1673 | # files in one run (i.e. multiple -o and -T options on the command line). This 1674 | # makes dot run faster, but since only newer versions of dot (>1.8.10) 1675 | # support this, this feature is disabled by default. 1676 | 1677 | DOT_MULTI_TARGETS = NO 1678 | 1679 | # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 1680 | # generate a legend page explaining the meaning of the various boxes and 1681 | # arrows in the dot generated graphs. 1682 | 1683 | GENERATE_LEGEND = YES 1684 | 1685 | # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 1686 | # remove the intermediate dot files that are used to generate 1687 | # the various graphs. 1688 | 1689 | DOT_CLEANUP = YES 1690 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # avoids problems with non-gnu makes 2 | SHELL = /bin/sh 3 | 4 | # suffix Definitions 5 | .SUFFIXES: # Delete the default suffixes 6 | .SUFFIXES: .c .o .h # Define our suffix list 7 | 8 | .c.o: 9 | @echo compiling $< ... 10 | @$(CC) $(CFLAGS) $(DEFINES) -c $< -o $@ 1>/dev/null 11 | 12 | 13 | CC = cc 14 | RM = rm -f 15 | ED = ed 16 | MV = mv 17 | NM = nm 18 | SORT = sort 19 | RANLIB = ranlib 20 | AR = ar rc 21 | 22 | 23 | # build specific variables 24 | LIBRARY = libunif.a 25 | APPNAME = libunif 26 | 27 | DEFINES = -DNDEBUG -D`uname` 28 | INCLUDES = 29 | CFLAGS = -ansi -pedantic -W -Wall -ggdb -O2 $(INCLUDES) 30 | LDFLAGS = 31 | 32 | 33 | # search path for dependencies 34 | VPATH = . 35 | 36 | # source files 37 | H_FILES = unif_crc32.h ines_convert.h lib_ines.h lib_unif.h load_ines.h load_unif.h std_func.h unif_types.h 38 | C_FILES = unif_crc32.c ines_convert.c lib_ines.c lib_unif.c load_ines.c load_unif.c std_func.c 39 | O_FILES = $(C_FILES:.c=.o) 40 | SOURCEFILES = $(H_FILES) $(C_FILES) 41 | .PRECIOUS: $(SOURCEFILES) 42 | .PHONY : clean 43 | 44 | # main targets 45 | all: $(LIBRARY) $(APPNAME) 46 | 47 | $(APPNAME): main.o $(LIBRARY) 48 | @echo "building test application ..." 49 | $(CC) $< -lunif -L. -o $@ 50 | 51 | $(LIBRARY): $(O_FILES) 52 | @echo "linking ..." 53 | @$(AR) $@ $(O_FILES) 1>/dev/null 54 | -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 55 | 56 | clean: 57 | $(RM) $(O_FILES) $(APPNAME) $(LIBRARY) core *~ main.o 2> /dev/null 58 | 59 | depend: $(C_FILES) 60 | @echo "Building Dependency Information..." 61 | @$(CC) $(DEFINES) -MM $? > makedep 62 | @echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep 63 | @echo '$$r makedep' >>eddep 64 | @echo 'w' >>eddep 65 | @$(ED) - Makefile < eddep 66 | @$(RM) eddep makedep 67 | @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile 68 | @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile 69 | @echo '# see make depend above' >> Makefile 70 | @echo "Done" 71 | 72 | #----------------------------------------------------------------- 73 | # DO NOT DELETE THIS LINE -- make depend uses it 74 | #----------------------------------------------------------------- 75 | unif_crc32.o: unif_crc32.c unif_crc32.h unif_types.h 76 | ines_convert.o: ines_convert.c ines_convert.h unif_types.h load_ines.h \ 77 | lib_ines.h load_unif.h lib_unif.h std_func.h unif_crc32.h 78 | lib_ines.o: lib_ines.c lib_ines.h unif_types.h 79 | lib_unif.o: lib_unif.c lib_unif.h unif_types.h 80 | load_ines.o: load_ines.c load_ines.h lib_ines.h unif_types.h 81 | load_unif.o: load_unif.c load_unif.h lib_unif.h unif_types.h 82 | std_func.o: std_func.c std_func.h 83 | # DEPENDENCIES MUST END AT END OF FILE 84 | # IF YOU PUT STUFF HERE IT WILL GO AWAY 85 | # see make depend above 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The UNIF format is a portable, flexible REPLACEMENT of the NES standard (Designed by Marat Fayzullin). It is a chunked file format in the lines of the Amiga IFF (LBM), Microsoft RIFF (WAV) and Autodesk 3D studio mesh files (3DS). The goal of having a chunked definition is to provide flexibility and ease of implementation, as data is described in blocks with type IDs referring to them and header information to provide a selective data reading. 2 | 3 | The format uses symetric data conversion for numerical compatibility between the different platforms' byte ordering. The ordering used is the 6502 Byte order (Intel). 4 | -------------------------------------------------------------------------------- /UNIF_current.txt: -------------------------------------------------------------------------------- 1 | **************************************************************************** 2 | UNIF file format specifications 3 | (Universal NES Image) file format 4 | 5 | Created by Tennessee Carmel-Veilleux (veilleux@ameth.org) 6 | REV 7c, March 21st, 2015 7 | 8 | Maintinted by Evan Teran (evan.teran@gmail.com) 9 | 10 | 11 | ***********THIS IS AN OPEN STANDARD. IT IS OPEN TO SUGGESTIONS************** 12 | 13 | Overview 14 | -------- 15 | The UNIF format is a portable, flexible REPLACEMENT of the NES standard 16 | (Designed by Marat Fayzullin). It is a chunked file format in the lines of 17 | the Amiga IFF (LBM), Microsoft RIFF (WAV) and Autodesk 3D studio mesh 18 | files (3DS). The goal of having a chunked definition is to provide 19 | flexibility and ease of implementation, as data is described in blocks 20 | with type IDs referring to them and header information to provide a 21 | selective data reading. The format uses symetric data conversion for 22 | numerical compatibility between the different platforms' byte ordering. 23 | The ordering used is the 6502 Byte order (Intel), so that no more 24 | bickering arrises from people who do not appreciate Network Byte Ordering 25 | (Motorola). 26 | 27 | *** 28 | The extension suggested for use with this format is .UNF (.UNIF under Operating 29 | systems which support longer extensions). 30 | *** 31 | 32 | Byte ordering 33 | ------------- 34 | Byte ordering used throughout the file for DWORDs and WORDs is 6502 Byte 35 | order. The 6502 byte order is LSB, least significant byte first 36 | (Little-endian): 37 | 38 | 3 2 1 0 <- Byte order for MSB (Network Byte order, m68k, PowerPC) 39 | 0 1 2 3 <- Byte order for LSB (80x86, 6502, Z80) 40 | 41 | Care must be taken to convert the WORDs and DWORDs if you are using a 42 | non-LSB platform (Mac, Amiga, some others). 43 | 44 | File format 45 | ----------- 46 | 00h-1Fh : Header 47 | 20h-EOF : Chunks 48 | 49 | I can not think of an easier format to describe :) 50 | 51 | Header 52 | ------ 53 | The 32-byte header contains the string "UNIF" , NON null-terminated, case 54 | as written. This is for identification purposes, a little like .NES' "NES^Z" 55 | The string is followed by Revision number and reserved bytes. 56 | 57 | Format: 00h-03h: "UNIF" tag identifier 58 | 04h-07h: DWORD -> Revision number, currently 7 59 | 08h-1Fh: Reserved for future usage 60 | 61 | Sample structure: 62 | 63 | structure UNIF_header [ 64 | char identification[4]; /* MUST be "UNIF" */ 65 | dword revision; /* Revision number */ 66 | byte expansion[24]; 67 | ]; 68 | 69 | Chunks 70 | ------ 71 | Each chunks is composed of 3 distinct elements: 72 | 00h-03h: Chunk ID string 73 | 04h-07h: DWORD -> Block Length of Data 74 | 08h-?? : Data 75 | 76 | All the chunks are written sequentially in the file. If you do not understand 77 | a chunk by its ID, simply jump over it using the data length information. 78 | *** ALL THE CHUNKS ARE OPTIONAL *** 79 | That means that there are NO mandatory chunks, and you support only the 80 | ONES YOU WISH, passing over the others while you are interpreting the 81 | file. 82 | 83 | Sample structure: 84 | 85 | structure UNIF_chunk [ 86 | char chunk_ID[4]; /* Chunk identification string. Can also be considered a 87 | number. UTF-8 format */ 88 | dword length; /* Data length, in little-endian format */ 89 | ]; 90 | 91 | The different chunks: 92 | --------------------- 93 | ******************************************************************************* 94 | How chunks are described: 95 | ID field: Contains the 4-characters string identifier for the chunk 96 | 97 | Length: Length of the block. If it is "??", then the block may have 98 | variable data size depending on the cartridge. 99 | 100 | Revision: First revision in which the chunk appeared. If your reader supports 101 | a lower revision, you might be unable to read the chunk, simply pass 102 | over it. The Revision used by the cart is written in the header. The 103 | number represents the Revision Number of the most recent chunk 104 | contained in the file. Example : If you have 5 chunks of revision 1 105 | and 2 chunks of revision 4 in the file, the Revision number in the 106 | header will be 4. 107 | 108 | Description: Complete description of the contents and encoding of the chunk 109 | ******************************************************************************* 110 | 111 | ID: [MAPR] 112 | Length: ?? (Suggested max: 32 chars) 113 | Revision: 1 114 | Description: This is supplemental information about the mapper. DO NOT USE 115 | A MAPPER NUMBER HERE ! Rather use the BOARD NAME. There is 116 | already a list in progress describing each NES cart and the 117 | board it uses. The string is NULL-TERMINATED UTF-8. 118 | 119 | examples: N,E,S,-,N,R,O,M,-,2,5,6,\0 -> This "No mapper" 120 | N,E,S,-,U,N,R,O,M,\0 -> This is (LS161+LS32) 121 | 122 | NOTA: This mapper organization suggests that emulators must be rewritten 123 | to emulate the ACTUAL CARTRIDGE HARDWARE, and not solely a case of another 124 | mapper number. That means you have to make for UNROM: 125 | 1- Mapper handler (74LS161+74LS32) 126 | 2- CHR-RAM Handler 127 | 128 | Those components can be reused, since many boards only have a slight 129 | difference in them compared to similar ones. 130 | 131 | **IT SHOULD BE NOTED THAT**: A board name tells you EVERYTHING there is to 132 | know about a board. You do not need other chunks to tell you how much RAM 133 | there is, or if it is VRAM. It is all implied by the board name. A list 134 | will soon be distributed containing board name information. 135 | 136 | Address of board table for North American Games and Board Names description: 137 | http://codef00.com/boardtable.txt 138 | http://codef00.com/boardnames.txt 139 | 140 | ID: [READ] 141 | Length: ?? 142 | Revision: 1 143 | Description: Commentaries for the user of the ROM image. In the case of a 144 | homebrew game, this can be very useful to store credit and maker 145 | information. *** This could be "Incitation to littering". Please do not 146 | put garbage in there. It is meant for either mapper information or 147 | licensing information for homebrew games.*** 148 | 149 | 150 | ID: [NAME] 151 | Length: ?? 152 | Revision: 1 153 | Description: NULL-terminated UTF-8 string containing the name of the game. If not 154 | present, use the filename as the name. 155 | 156 | ID: [TVCI] 157 | Length: BYTE 158 | Revision: 6 159 | Description: Television Standards Compatability Information set to: 160 | 0- Originally NTSC cartridge 161 | 1- Originally PAL cartridge 162 | 2- Does not matter 163 | NOTE: ALL North American carts that are dumps of the North American 164 | Version are NTSC. All licensed famicom games are NTSC. 165 | 166 | ID: [DINF] 167 | Length: 204 168 | Revision: 2 169 | Description: Dumper information block: 170 | structure dumper_info [ 171 | 172 | char dumper_name[100]; /* NULL-terminated UTF-8 string containing the name 173 | of the person who dumped the cart. */ 174 | byte day; /* Day of the month when cartridge was dumped */ 175 | byte month; /* Month of the year when cartridge was dumped */ 176 | word year; /* Year during which the cartridge was dumped */ 177 | char dumper_agent[100]; /* NULL-terminated UTF-8 string containing the name of 178 | the ROM-dumping means used */ 179 | ] 180 | 181 | ID: [CTRL] 182 | Length: BYTE 183 | Revision: 7 184 | Description: Bitfield containing information about the controllers used by the 185 | cartridge. 186 | 187 | Bit 0: Regular Joypad 188 | Bit 1: Zapper 189 | Bit 2: R.O.B 190 | Bit 3: Arkanoid Controller 191 | Bit 4: Power Pad 192 | Bit 5: Four-Score adapter 193 | Bit 6: Expansion (Do not touch) 194 | Bit 7: Expansion (Do not touch) 195 | 196 | ID: [PCK0] through [PCKF] 197 | Length: DWORD 198 | Reivision: 5 199 | Description: This block contains a 32-bit CRC which can be used to make 200 | sure that the ROM content matches a checksum when burning on EPROM. This 201 | block provides a checksum for [PRG0] through [PRGF] inclusively 202 | 203 | ID: [CCK0] through [CCKF] 204 | Length: DWORD 205 | Reivision: 5 206 | Description: This block contains a 32-bit CRC which can be used to make 207 | sure that the ROM content matches a checksum when burning on EPROM. This 208 | block provides a checksum for [CHR0] through [CHRF] inclusively 209 | 210 | ID: [PRG0] through [PRGF] 211 | Length: ?? 212 | Revision: 4 213 | Description: Chunks containing the Binary data of the PRG ROM. If there 214 | are more than 1 PRG chips on the PRG bus, use PRG1, PRG2, PRG4, etc. 215 | The way PRGs are handled depends on the mapper and emulator. Most generaly 216 | (99%), only use PRG0. (Some carts have been witnessed with 8 PRG ROMs). 217 | 218 | ID: [CHR0] through [CHRF] 219 | Length: ?? 220 | Revision: 4 221 | Description: Chunks containing the binary data of the CHR ROM. If there 222 | are more than 1 CHR chips on the CHR bus, use CHR1, CHR2, CHR4, etc. The 223 | way CHRs are handled depends on the mapper and emulator. Most generaly 224 | (99%), only CHR0 is used. 225 | 226 | ID: [BATR] 227 | Length: BYTE 228 | Revision: 5 229 | Description: The presence of this block indicates that the board indeed 230 | contains a battery. This is necessary because many boards have the 231 | capability of a battery (the traces and holes are there), but they only 232 | use RAM and don't add the battery at manufacturing time. Examples: 233 | * SAROM: MMC1B, PRG ROM, CHR ROM, optional 8k of RAM (battery) 234 | * SKROM: MMC1B, PRG ROM, CHR ROM, 8k optional RAM (battery) 235 | 236 | Both these boards (SAROM and SKROM) can have a battery, but usually they 237 | don't have it. 238 | 239 | ID: [VROR] 240 | Length: BYTE 241 | Revision: 5 242 | Description: This is a VRAM Override. If this chunk is present, then the 243 | CHR-ROM area will be considered as RAM even if ROM is present. This 244 | overrides board identification. This is present so that homemade carts 245 | which use NROM or others and replace the CHR-ROM with CHR-RAM can still be 246 | interpreted (since NROM is always CHR-ROM in commercial games). 247 | 248 | ID: [MIRR] 249 | Length: BYTE 250 | Revision: 5 251 | Description: This chunk tells you how the hardwired mirroring is setup on 252 | the board. The board name CANNOT tell you (in most cases) what the 253 | mirroring is, since the all have solder pads to select the mirroring at 254 | manufacturing time. The following values are legal: 255 | 256 | * $00 - Horizontal Mirroring (Hard Wired) 257 | * $01 - Vertical Mirroring (Hard Wired) 258 | * $02 - Mirror All Pages From $2000 (Hard Wired) 259 | * $03 - Mirror All Pages From $2400 (Hard Wired) 260 | * $04 - Four Screens of VRAM (Hard Wired) 261 | * $05 - Mirroring Controlled By Mapper Hardware 262 | 263 | Conclusion 264 | ---------- 265 | This ends the specification for Revision 7 of UNIF. If you have ANY 266 | suggestions to make regarding the UNIF file format, such as chunk ideas or 267 | modifications, or would like to collaborate to the elaboration and design 268 | process, e-mail Evan Teran at: evan.teran@gmail.com. 269 | 270 | A multi-platform C Code Library for UNIF support was made by Evan Teran. It 271 | is available at http://codef00.com/projects#unif. 272 | 273 | [References] 274 | {.NES file format specifications} by Marat Fayzullin (fms@cs.umd.edu) 275 | {NESDEV mailing list} by Various authors 276 | {NES technical documentation} by Jeremy Chadwick (yoshi@parodius.com) 277 | 278 | [Credits] 279 | Neal Tew for his neat emulator and great contribution to the NESdev 280 | community. 281 | 282 | Jeremy Chadwick (yoshi@parodius.com) for his contribution to the NESdev 283 | community and great advice over the time. 284 | 285 | Mark Knibbs (mark_k@iname.com) for his excellent web site as well as his 286 | more than honorable contribution to the NES world 287 | 288 | Matthew Conte (itsbroke@classicgaming.com) for his CajoNES and Nofrendo 289 | programs 290 | 291 | Michael Iwaniec (mrbananmos@yahoo.com) for his interest in UNIF and 292 | constructive criticism. 293 | 294 | Kevin Horton (khorton@iquest.net) for his proposals and support of 295 | UNIF. He's also been a fantastic help to me in my learning curve of the 296 | NES's hardware aspects. 297 | 298 | /Firebug/ (firebug@cfl.rr.com) for the ideas brought with NIFF 299 | 300 | T. Alex Reed {W1k} (rizen@netzero.net) for suggestions of additions 301 | to UNIF. He also pointed out some mistakes in the original specifications. 302 | 303 | Evan Teran {proxy} (evan.teran@gmail.com) for making suggestions as well as 304 | writing a .NES->UNIF converter and the LIB_UNIF library. 305 | -------------------------------------------------------------------------------- /ines_convert.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "ines_convert.h" 20 | #include "load_ines.h" 21 | #include "load_unif.h" 22 | #include "std_func.h" 23 | #include "unif_crc32.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* 31 | Tags not supprted yet in conversion 32 | READ_TAG 33 | */ 34 | 35 | /*------------------------------------------------------------------------------ 36 | // Name: recommend_board 37 | //----------------------------------------------------------------------------*/ 38 | static void recommend_board(const ines_cart_t *cart) { 39 | assert(cart != 0); 40 | 41 | do { 42 | const uint32_t ines_mapper = mapper_INES(cart); 43 | const uint32_t ines_submapper = submapper_INES(cart); 44 | const uint32_t prg_size = prg_size_INES(cart) * 16384; 45 | 46 | (void)ines_submapper; 47 | 48 | /* TODO: expand this to many more mappers :-) as we can best detect them */ 49 | if(ines_mapper == 0) { 50 | switch(prg_size * 8) { 51 | case 0x40000: 52 | printf("Recommended Board: NES-NROM-256\n"); 53 | break; 54 | case 0x20000: 55 | printf("Recommended Board: NES-NROM-128\n"); 56 | break; 57 | default: 58 | printf("Recommended Board: NES-NROM\n"); 59 | break; 60 | } 61 | } else if(ines_mapper == 2) { 62 | switch(prg_size) { 63 | case 0x40000: 64 | printf("Recommended Board: NES-UOROM\n"); 65 | break; 66 | case 0x20000: 67 | printf("Recommended Board: NES-UNROM\n"); 68 | break; 69 | default: 70 | break; 71 | } 72 | } 73 | } while(0); 74 | } 75 | 76 | /*------------------------------------------------------------------------------ 77 | // Name: unif_strncasecmp 78 | //----------------------------------------------------------------------------*/ 79 | int unif_strncasecmp(const char *s1, const char *s2, size_t n) { 80 | int ret = 0; 81 | 82 | assert(s1 != 0); 83 | assert(s2 != 0); 84 | 85 | while(!ret && (*s1 || *s2) && n--) { 86 | const char cs1 = (const char)tolower(*s1); 87 | const char cs2 = (const char)tolower(*s2); 88 | ret = (cs2 - cs1); 89 | ++s1; 90 | ++s2; 91 | } 92 | return ret; 93 | } 94 | 95 | /*----------------------------------------------------------------------------- 96 | // Name: write_header 97 | //---------------------------------------------------------------------------*/ 98 | UNIF_RETURN_CODE write_header(FILE *file) { 99 | 100 | unif_header_t hdr; 101 | assert(file != 0); 102 | 103 | /* ensure that all reserved bits are 0 */ 104 | memset(&hdr, 0, sizeof(unif_header_t)); 105 | 106 | /* setup tag and revision number */ 107 | memcpy(hdr.id, "UNIF", 4); 108 | hdr.revision = UNIF_REVISION; 109 | 110 | /* write to a file */ 111 | return write_header_UNIF(file, &hdr); 112 | } 113 | 114 | /*----------------------------------------------------------------------------- 115 | // Name: write_read 116 | //---------------------------------------------------------------------------*/ 117 | UNIF_RETURN_CODE write_read(FILE *file){ 118 | 119 | #if 0 120 | unif_chunk_t chunk_header_UNIF; 121 | /* TODO: come up with a better solution than this */ 122 | char read_data[0x4000]; /* should be enough */ 123 | #endif 124 | 125 | assert(file != 0); 126 | 127 | (void)file; 128 | 129 | if(ask_question_yn("do you want a READ block (y/n)? [n]")) { 130 | #ifndef ENABLE_READ 131 | printf("%s\n", "Temporarily disabled"); 132 | #endif 133 | } 134 | 135 | return UNIF_OK; 136 | } 137 | 138 | /*----------------------------------------------------------------------------- 139 | // Name: write_pck 140 | //---------------------------------------------------------------------------*/ 141 | UNIF_RETURN_CODE write_pck(FILE *file, uint8_t *prg_code, size_t size) { 142 | 143 | assert(file != 0); 144 | assert(prg_code != 0); 145 | assert(size != 0); 146 | 147 | if(ask_question_yn("do you want a PCK0 block (PRG0 CRC) (y/n)? [n] ")) { 148 | unif_chunk_t chunk_header_UNIF; 149 | uint32_t crc; 150 | 151 | memcpy(chunk_header_UNIF.id, "PCK0", 4); 152 | chunk_header_UNIF.length = sizeof(uint32_t); 153 | 154 | crc = unif_crc32(prg_code, (uint32_t)size, 0); 155 | 156 | return write_chunk_UNIF(file, &chunk_header_UNIF, &crc); 157 | } 158 | 159 | return UNIF_OK; 160 | } 161 | 162 | /*----------------------------------------------------------------------------- 163 | // Name: write_cck 164 | //---------------------------------------------------------------------------*/ 165 | UNIF_RETURN_CODE write_cck(FILE * file, uint8_t *chr_code, size_t size) { 166 | 167 | assert(file != 0); 168 | assert(chr_code != 0); 169 | assert(size != 0); 170 | 171 | if(ask_question_yn("do you want a CCK0 block (CHR0 CRC) (y/n)? [n] ")) { 172 | unif_chunk_t chunk_header_UNIF; 173 | uint32_t crc; 174 | 175 | memcpy(chunk_header_UNIF.id, "CCK0", 4); 176 | chunk_header_UNIF.length = sizeof(uint32_t); 177 | 178 | crc = unif_crc32(chr_code, (uint32_t)size, 0); 179 | 180 | return write_chunk_UNIF(file, &chunk_header_UNIF, &crc); 181 | } 182 | 183 | return UNIF_OK; 184 | } 185 | 186 | 187 | /*----------------------------------------------------------------------------- 188 | // Name: write_batr 189 | //---------------------------------------------------------------------------*/ 190 | UNIF_RETURN_CODE write_batr(FILE *file) { 191 | 192 | assert(file != 0); 193 | 194 | if(ask_question_yn("does this rom have a battery backup (y/n)? [n] ")) { 195 | unif_chunk_t chunk_header_UNIF; 196 | uint8_t chunk_data = 0; 197 | 198 | memcpy(chunk_header_UNIF.id, "BATR", 4); 199 | chunk_header_UNIF.length = sizeof(uint8_t); 200 | 201 | return write_chunk_UNIF(file, &chunk_header_UNIF, &chunk_data); 202 | } 203 | 204 | return UNIF_OK; 205 | } 206 | 207 | 208 | /*----------------------------------------------------------------------------- 209 | // Name: write_vror 210 | //---------------------------------------------------------------------------*/ 211 | UNIF_RETURN_CODE write_vror(FILE *file) { 212 | 213 | assert(file != 0); 214 | 215 | if(ask_question_yn("enable VRAM override (y/n)? [n] ")) { 216 | unif_chunk_t chunk_header_UNIF; 217 | uint8_t chunk_data = 0; 218 | 219 | memcpy(chunk_header_UNIF.id, "VROR", 4); 220 | chunk_header_UNIF.length = sizeof(uint8_t); 221 | 222 | return write_chunk_UNIF(file, &chunk_header_UNIF, &chunk_data); 223 | } 224 | 225 | return UNIF_OK; 226 | } 227 | 228 | /*----------------------------------------------------------------------------- 229 | // Name: write_mirr 230 | //---------------------------------------------------------------------------*/ 231 | UNIF_RETURN_CODE write_mirr(FILE *file) { 232 | 233 | assert(file != 0); 234 | 235 | if(ask_question_yn("do you want a MIRR block (y/n)? [n] ")) { 236 | unif_chunk_t chunk_header_UNIF; 237 | 238 | size_t user_input = display_menu( 239 | 6, /* numer of items */ 240 | "Please select mirroring type: (0,1,2,3,4,5)", /* prompt */ 241 | "Horizontal Mirroring (Hard Wired)", /* options */ 242 | "Vertical Mirroring (Hard Wired)", 243 | "Mirror All Pages From $2000 (Hard Wired)", 244 | "Mirror All Pages From $2400 (Hard Wired)", 245 | "Four Screens of VRAM (Hard Wired)", 246 | "Mirroring Controlled By Mapper Hardware" 247 | ); 248 | 249 | /* write block */ 250 | memcpy(chunk_header_UNIF.id, "MIRR", 4); 251 | chunk_header_UNIF.length = sizeof(user_input); 252 | 253 | return write_chunk_UNIF(file, &chunk_header_UNIF, &user_input); 254 | } 255 | 256 | return UNIF_OK; 257 | } 258 | 259 | /*----------------------------------------------------------------------------- 260 | // Name: write_mapr 261 | //---------------------------------------------------------------------------*/ 262 | UNIF_RETURN_CODE write_mapr(FILE *file) { 263 | 264 | unif_chunk_t chunk_header_UNIF; 265 | char board_name[64]; 266 | 267 | assert(file != 0); 268 | 269 | memcpy(chunk_header_UNIF.id, "MAPR", 4); 270 | chunk_header_UNIF.length = sizeof(board_name); 271 | 272 | printf("%s%lu%s", "what is the board type/name? ( MAX ", sizeof(board_name), " chars ) "); 273 | memset(board_name, 0, sizeof(board_name)); 274 | if(fgets(board_name, sizeof(board_name), stdin) == 0) { 275 | return UNIF_INPUT_FAIL; 276 | } 277 | 278 | /* eliminate new line */ 279 | if(board_name[strlen(board_name) - 1] == '\n') { 280 | board_name[strlen(board_name) - 1] = '\0'; 281 | } 282 | 283 | return write_chunk_UNIF(file, &chunk_header_UNIF, board_name); 284 | } 285 | 286 | /*----------------------------------------------------------------------------- 287 | // Name: write_name 288 | //---------------------------------------------------------------------------*/ 289 | UNIF_RETURN_CODE write_name(FILE *file) { 290 | 291 | assert(file != 0); 292 | 293 | if(ask_question_yn("do you want an internal ROM name (y/n)? [n] ")) { 294 | unif_chunk_t chunk_header_UNIF; 295 | char internal_name[0x400]; /* more than enough ? */ 296 | 297 | printf("what is the internal name? "); 298 | memset(internal_name, 0, sizeof(internal_name)); 299 | if(fgets(internal_name, sizeof(internal_name), stdin) == 0) { 300 | return UNIF_INPUT_FAIL; 301 | } 302 | 303 | /* eliminate new line */ 304 | if(internal_name[strlen(internal_name) - 1] == '\n') { 305 | internal_name[strlen(internal_name) - 1] = '\0'; 306 | } 307 | 308 | memcpy(chunk_header_UNIF.id, "NAME", 4); 309 | chunk_header_UNIF.length = (uint32_t)strlen(internal_name) + 1; 310 | 311 | return write_chunk_UNIF(file, &chunk_header_UNIF, internal_name); 312 | } 313 | 314 | return UNIF_OK; 315 | } 316 | 317 | /*----------------------------------------------------------------------------- 318 | // Name: write_prg 319 | //---------------------------------------------------------------------------*/ 320 | UNIF_RETURN_CODE write_prg(FILE * file, uint8_t *prg_code, size_t size) { 321 | 322 | unif_chunk_t chunk_header_UNIF; 323 | 324 | assert(file != 0); 325 | assert(prg_code != 0); 326 | assert(size != 0); 327 | 328 | /* write PRG code */ 329 | memcpy(chunk_header_UNIF.id, "PRG0", 4); 330 | chunk_header_UNIF.length = (uint32_t)size; 331 | 332 | return write_chunk_UNIF(file, &chunk_header_UNIF, prg_code); 333 | } 334 | 335 | /*----------------------------------------------------------------------------- 336 | // Name: write_chr 337 | //---------------------------------------------------------------------------*/ 338 | UNIF_RETURN_CODE write_chr(FILE *file, uint8_t *chr_code, size_t size) { 339 | 340 | unif_chunk_t chunk_header_UNIF; 341 | 342 | assert(file != 0); 343 | 344 | if(size != 0) { 345 | /* write CHR code */ 346 | memcpy(chunk_header_UNIF.id, "CHR0", 4); 347 | chunk_header_UNIF.length = (uint32_t)size; 348 | 349 | return write_chunk_UNIF(file, &chunk_header_UNIF, chr_code); 350 | } 351 | 352 | return UNIF_OK; 353 | } 354 | 355 | /*----------------------------------------------------------------------------- 356 | // Name: write_tvci 357 | //---------------------------------------------------------------------------*/ 358 | UNIF_RETURN_CODE write_tvci(FILE *file) { 359 | 360 | assert(file != 0); 361 | 362 | if(ask_question_yn("do you want a TVCI block (y/n)? [n] ")) { 363 | unif_chunk_t chunk_header_UNIF; 364 | 365 | size_t user_input = display_menu( 366 | 3, /* numer of items */ 367 | "Please select TV compatibility: (0,1,2)", /* prompt */ 368 | "Originally NTSC cartridge", /* options */ 369 | "Originally PAL cartridge", 370 | "Does not matter" ); 371 | 372 | /* write block */ 373 | memcpy(chunk_header_UNIF.id, "TVCI", 4); 374 | chunk_header_UNIF.length = sizeof(user_input); 375 | 376 | return write_chunk_UNIF(file, &chunk_header_UNIF, &user_input); 377 | } 378 | 379 | return UNIF_OK; 380 | } 381 | 382 | 383 | /*----------------------------------------------------------------------------- 384 | // Name: write_ctrl 385 | //---------------------------------------------------------------------------*/ 386 | UNIF_RETURN_CODE write_ctrl(FILE *file) { 387 | 388 | assert(file != 0); 389 | 390 | if(ask_question_yn("do you want a CTRL block (y/n)? [n] ")) { 391 | unif_chunk_t chunk_header_UNIF; 392 | uint8_t ctrl_data = 0; 393 | 394 | if(ask_question_yn( "does this cart use a standard joypad (y/n)? [n] ")) { 395 | ctrl_data |= CTRL_STDJOY; 396 | } 397 | 398 | if(ask_question_yn( "does this cart use a zapper (y/n)? [n] ")) { 399 | ctrl_data |= CTRL_ZAPPER; 400 | } 401 | 402 | if(ask_question_yn( "does this cart use a R.O.B. (y/n)? [n] ")) { 403 | ctrl_data |= CTRL_ROB; 404 | } 405 | 406 | if(ask_question_yn( "does this cart use the arkanoid controller (y/n)? [n] ")) { 407 | ctrl_data |= CTRL_ARKANOID; 408 | } 409 | 410 | if(ask_question_yn( "does this cart use the powerpad (y/n)? [n] ")) { 411 | ctrl_data |= CTRL_POWPAD; 412 | } 413 | 414 | if(ask_question_yn( "does this cart use the Four-Score adapter (y/n)? [n] ")) { 415 | ctrl_data |= CTRL_4SCORE; 416 | } 417 | 418 | /* write block */ 419 | memcpy(chunk_header_UNIF.id, "CTRL", 4); 420 | chunk_header_UNIF.length = sizeof(ctrl_data); 421 | 422 | return write_chunk_UNIF(file, &chunk_header_UNIF, &ctrl_data); 423 | } 424 | 425 | return UNIF_OK; 426 | } 427 | 428 | 429 | /*----------------------------------------------------------------------------- 430 | // Name: write_dinf 431 | //---------------------------------------------------------------------------*/ 432 | UNIF_RETURN_CODE write_dinf(FILE *file) { 433 | 434 | assert(file != 0); 435 | 436 | if(ask_question_yn("do you want a DINF block (y/n)? [n] ")) { 437 | unif_chunk_t chunk_header_UNIF; 438 | dumper_info_t dinf_block; 439 | unsigned tmp_num; 440 | char numeric_line[256]; 441 | 442 | printf("%s\n", "Name? ( 100 chars max ):"); 443 | memset(dinf_block.dumper_name, 0, sizeof(dinf_block.dumper_name)); 444 | if(fgets(dinf_block.dumper_name, sizeof(dinf_block.dumper_name), stdin) == 0) { 445 | return UNIF_INPUT_FAIL; 446 | } 447 | 448 | /* eliminate new line */ 449 | if(dinf_block.dumper_name[strlen(dinf_block.dumper_name) - 1] == '\n') { 450 | dinf_block.dumper_name[strlen(dinf_block.dumper_name) - 1] = '\0'; 451 | } 452 | 453 | 454 | do { 455 | printf("Day? "); 456 | 457 | if(fgets(numeric_line, sizeof(numeric_line), stdin) == 0) { 458 | return UNIF_INPUT_FAIL; 459 | } 460 | 461 | if(sscanf(numeric_line, "%255u", &tmp_num) == 1) { 462 | break; 463 | } 464 | 465 | } while(1); 466 | 467 | dinf_block.day = (unsigned char)tmp_num; 468 | 469 | do { 470 | printf("Month? "); 471 | if(fgets(numeric_line, sizeof(numeric_line), stdin) == 0) { 472 | return UNIF_INPUT_FAIL; 473 | } 474 | 475 | if(sscanf(numeric_line, "%255u", &tmp_num) == 1) { 476 | break; 477 | } 478 | } while(1); 479 | 480 | dinf_block.month = (unsigned char)tmp_num; 481 | 482 | do { 483 | printf("Year? "); 484 | if(fgets(numeric_line, sizeof(numeric_line), stdin) == 0) { 485 | return UNIF_INPUT_FAIL; 486 | } 487 | 488 | if(sscanf(numeric_line, "%255u", &tmp_num) == 1) { 489 | break; 490 | } 491 | } while(1); 492 | 493 | dinf_block.year = (unsigned short)tmp_num; 494 | 495 | printf("%s\n", "Dumper Agent? ( 100 chars max ) "); 496 | memset(dinf_block.dumper_agent, 0, sizeof(dinf_block.dumper_agent)); 497 | if(fgets(dinf_block.dumper_agent, sizeof(dinf_block.dumper_agent), stdin) == 0) { 498 | return UNIF_INPUT_FAIL; 499 | } 500 | 501 | /* eliminate new line */ 502 | if(dinf_block.dumper_agent[strlen(dinf_block.dumper_agent) - 1] == '\n') { 503 | dinf_block.dumper_agent[strlen(dinf_block.dumper_agent) - 1] = '\0'; 504 | } 505 | 506 | memcpy(chunk_header_UNIF.id, "DINF", 4); 507 | chunk_header_UNIF.length = sizeof(dumper_info_t); 508 | 509 | return write_chunk_UNIF(file, &chunk_header_UNIF, &dinf_block); 510 | } 511 | 512 | return UNIF_OK; 513 | } 514 | 515 | /*----------------------------------------------------------------------------- 516 | // Name: make_unif_file_from_nes 517 | //---------------------------------------------------------------------------*/ 518 | void make_unif_file_from_nes(const char *unif_file, const char *ines_file) { 519 | 520 | FILE *file_dest = 0; 521 | ines_cart_t cart; 522 | INES_MIRRORING mirroring; 523 | 524 | assert(unif_file != 0); 525 | assert(ines_file != 0); 526 | 527 | /* read the source .nes file */ 528 | if(load_file_INES(ines_file, &cart) != UNIF_OK) { 529 | printf("error loading iNES file\n"); 530 | return; 531 | } 532 | 533 | mirroring = mirroring_INES(&cart); 534 | 535 | printf("source filename - %s\n", ines_file); 536 | printf("iNES mapper # - %d.%d\n", mapper_INES(&cart), submapper_INES(&cart)); 537 | 538 | 539 | switch(mirroring) { 540 | case MIRR_HORIZONTAL: 541 | printf("mirroring - %s\n", "horizontal"); 542 | break; 543 | case MIRR_VERTICAL: 544 | printf("mirroring - %s\n", "vertical"); 545 | break; 546 | case MIRR_4SCREEN: 547 | printf("mirroring - %s\n", "4 screen"); 548 | break; 549 | } 550 | 551 | printf("sram enabled - %d\n", (cart.header->ctrl1 & INES_SRAM) != 0); 552 | printf("trainer present - %d\n", (cart.header->ctrl1 & INES_TRAINER) != 0); 553 | printf("# of 16k PRG Pages - %d\n", prg_size_INES(&cart)); 554 | printf("# of 8k CHR Pages - %d\n", chr_size_INES(&cart)); 555 | recommend_board(&cart); 556 | 557 | open_UNIF(unif_file, &file_dest, UNIF_OPEN_WRITE); 558 | 559 | write_header(file_dest); 560 | write_mapr(file_dest); 561 | write_name(file_dest); 562 | write_mirr(file_dest); 563 | write_ctrl(file_dest); 564 | write_tvci(file_dest); 565 | write_read(file_dest); 566 | write_batr(file_dest); 567 | write_vror(file_dest); 568 | write_dinf(file_dest); 569 | write_prg(file_dest, cart.prg_rom, prg_size_INES(&cart) * 16384); 570 | write_pck(file_dest, cart.prg_rom, prg_size_INES(&cart) * 16384); 571 | write_chr(file_dest, cart.chr_rom, chr_size_INES(&cart) * 8192); 572 | write_cck(file_dest, cart.chr_rom, chr_size_INES(&cart) * 8192); 573 | 574 | close_UNIF(file_dest); 575 | free_file_INES(&cart); 576 | } 577 | 578 | 579 | /*----------------------------------------------------------------------------- 580 | // Name: get_ines_mapperstrSourceNES 581 | //---------------------------------------------------------------------------*/ 582 | int get_ines_mapper(const char *board_name, ines_info_t *info) { 583 | 584 | const mapr_num_table_t *tbl_ptr = 0; 585 | mapr_num_table_t table[] = { 586 | /* name, ines #, chr-rom, four_screen */ 587 | { "NES-NROM", 0, 1, 0 }, /* NROM: No mapper, PRG-ROM, CHR-ROM */ 588 | { "UNL-SA-NROM", 0, 1, 0 }, 589 | { "NES-NROM-128", 0, 1, 0 }, /* NROM-128: No mapper, PRG-ROM, CHR-ROM */ 590 | { "NES-NROM-256", 0, 1, 0 }, /* NROM-256: No mapper, PRG-ROM, CHR-ROM */ 591 | { "NES-RROM", 0, 1, 0 }, /* NES-RROM: Same as NROM (Only used in Clu Clu land) */ 592 | 593 | { "NES-SAROM", 1, 1, 0 }, /* 128KB PRG (28-pin), 64KB CHR, 8KB S-RAM or W-RAM */ 594 | { "NES-SBROM", 1, 1, 0 }, /* 128KB PRG (28-pin), 64KB CHR (28-pin) */ 595 | { "NES-SCROM", 1, 1, 0 }, /* 128KB PRG (28-pin), 128KB CHR (32-pin) */ 596 | { "NES-SEROM", 1, 1, 0 }, /* 32KB not banked, 64KB CHR (28-pin) */ 597 | { "NES-SFROM", 1, 1, 0 }, /* 256KB PRG (32-pin), 64KB CHR (28-pin) */ 598 | { "NES-SGROM", 1, 0, 0 }, /* 256KB PRG, 8KB C-RAM banked */ 599 | { "NES-SHROM", 1, 1, 0 }, /* 32KB not banked, 128KB CHR (32-pin) */ 600 | { "NES-SJROM", 1, 0, 0 }, /* 256KB PRG, 8KB C-RAM, 8KB S-RAM or W-RAM */ 601 | { "NES-SKROM", 1, 1, 0 }, /* 256KB PRG, 128KB CHR, 8KB S-RAM or W-RAM */ 602 | { "NES-SLROM", 1, 1, 0 }, /* 256KB PRG, 128KB CHR */ 603 | { "NES-SL1ROM", 1, 1, 0 }, /* */ 604 | { "NES-SL2ROM", 1, 1, 0 }, /* */ 605 | { "NES-SL3ROM", 1, 1, 0 }, /* */ 606 | { "NES-SLRROM", 1, 1, 0 }, /* 256KB PRG, 128KB CHR (non JEDEC-pinout) */ 607 | { "NES-SNROM", 1, 0, 0 }, /* 256KB PRG, 8KB C-RAM banked, 8KB S-RAM or W-RAM */ 608 | { "NES-SOROM", 1, 0, 0 }, /* 256KB PRG, 128KB CHR, 16KB S-RAM or W-RAM thru CHR bit */ 609 | { "NES-SUROM", 1, 0, 0 }, /* 512K PRG thru CHR bit, 8KB C-RAM banked, 8KB S-RAM */ 610 | { "NES-SVROM", 1, 1, 0 }, /* 512KB PRG thru CHR bit, 8KB CHR banked, 16KB S-RAM or W-RAM thru CHR bit */ 611 | 612 | { "NES-UNROM", 2, 0, 0 }, /* UNROM: 74LS32+74LS161 mapper, 128k PRG, 8k CHR-RAM */ 613 | { "NES-UOROM", 2, 0, 0 }, /* UOROM: 74LS32+74LS161 mapper, 128k PRG, 8k CHR-RAM */ 614 | 615 | { "NES-CNROM", 3, 0, 0 }, /* CNROM: LS161 mapper, PRG-ROM, CHR-ROM?/CHR-RAM */ 616 | { "NES-TBROM", 4, 1, 0 }, 617 | { "NES-TEROM", 4, 1, 0 }, /* TEROM: MMC3A, PRG ROM, CHR ROM, (32k ROMs) */ 618 | { "NES-TFROM", 4, 1, 0 }, /* TFROM: MMC3B, PRG ROM, CHR ROM (64K of CHR only) */ 619 | { "NES-TGROM", 4, 0, 0 }, /* TGROM: MMC3C, PRG ROM, VRAM (512K of PRG) */ 620 | { "NES-TVROM", 4, 1, 0 }, /* TVROM: MMC3B, PRG ROM, CHR ROM, 4K of Nametable RAM (4-screen) */ 621 | { "NES-TSROM", 4, 1, 0 }, /* TSROM: MMC3A, PRG ROM, CHR ROM, 8k optional RAM */ 622 | { "NES-TQROM", 4, 0, 0 }, /* TQROM: MMC3B+74HC32, PRG ROM, CHR ROM + 8k of CHR-RAM */ 623 | { "NES-TKROM", 4, 1, 0 }, /* TKROM: MMC3A, PRG ROM, CHR ROM, 8k optional RAM (battery) */ 624 | { "NES-TKROM", 4, 1, 0 }, /* TKROM: MMC3A, PRG ROM, CHR ROM, 8k optional RAM (battery) */ 625 | { "NES-TLSROM", 4, 0, 0 }, /* TLSROM: Same as TLROM */ 626 | { "NES-DRROM", 4, 1, 1 }, /* DRROM: MMC3, 4K of nametable RAM (for 4-screen), PRG-ROM, CHR-ROM (only in Gauntlet) */ 627 | { "NES-TLROM", 4, 1, 0 }, /* TLROM: MMC3B, PRG ROM, CHR ROM */ 628 | { "ELROM", 5, 1, 0 }, /* ELROM: MMC5, PRG-ROM, CHR-ROM */ 629 | { "ETROM", 5, 1, 0 }, /* ETROM: MMC5, PRG-ROM, CHR-ROM, 2x 8k optionnal RAM (battery) */ 630 | { "EWROM", 5, 1, 0 }, /* EWROM: MMC5, PRG-ROM, CHR-ROM, 32k optionnal RAM (battery) */ 631 | { "NES-AOROM", 7, 1, 0 }, /* AOROM: LS161 mapper, PRG-ROM, CHR-ROM */ 632 | { "NES-ANROM", 7, 0, 0 }, /* ANROM: LS161+LS02 mapper, PRG-ROM, CHR-RAM */ 633 | { "PNROM", 9, 1, 0 }, /* PNROM: MMC2, PRG-ROM, CHR-ROM */ 634 | { 0, 0, 0, 0 } 635 | 636 | /* 637 | 351258: UNROM 638 | 351298: UNROM 639 | 351908 640 | 352026: TLROM (w/ LS32 for VROM enable control) 641 | 51555: Acclaim, MMC3B mapper, PRG ROM, CHR ROM 642 | AMROM: LS161, VRAM, PRG-ROM 643 | BNROM: LS161, VRAM, PRG-ROM (Different LS161 bits? Only used on Deadly Towers) 644 | COB: "Glop Top" style board 645 | CPROM: LS04, LS08, LS161, 32K ROM, 16K VRAM (bankswitched, Videomation only) 646 | GNROM: LS161 mapper, PRG ROM, CHR ROM 647 | HKROM: MMC6B, PRG-ROM, CHR-ROM, Battery 648 | MHROM: LS161 mapper, black blob chips. Mario Bros / Duck Hunt multi 649 | NES-B4: Same as TLROM 650 | NES-BTR: Sunsoft FME7 mapper, PRG ROM, CHR ROM, 8k optionnal RAM 651 | SC1ROM: MMC1B, PRG ROM, CHR ROM 652 | SCROM: LS161, LS02, VRAM, PRG-ROM (Similar to UNROM) 653 | SEROM: MMC1B, PRG ROM, CHR ROM 654 | SKROM: MMC1B, PRG ROM, CHR ROM, 8k optional RAM (battery) 655 | SN1-ROM AW (Overlord only) 656 | TL1ROM: Same as TLROM 657 | */ 658 | }; 659 | 660 | 661 | assert(board_name != 0); 662 | assert(info != 0); 663 | 664 | info->has_chr_rom = 0; 665 | info->ines_number = 0; 666 | info->four_screen = 0; 667 | 668 | for(tbl_ptr = table; tbl_ptr->board_name != 0; ++tbl_ptr) { 669 | 670 | if(unif_strncasecmp(board_name, tbl_ptr->board_name, 32) == 0) { 671 | info->has_chr_rom = tbl_ptr->chr_rom; 672 | info->ines_number = tbl_ptr->ines_number; 673 | info->four_screen = tbl_ptr->four_screen; 674 | return 0; 675 | } 676 | } 677 | 678 | return -1; 679 | } 680 | 681 | /*----------------------------------------------------------------------------- 682 | // Name: get_cart_type 683 | //---------------------------------------------------------------------------*/ 684 | CART_TYPE get_cart_type(const char *filename) { 685 | union { 686 | ines_header_t ines_header; 687 | unif_header_t unif_header; 688 | } headers; 689 | 690 | FILE *file = fopen(filename, "rb"); 691 | UNIF_RETURN_CODE ret = UNIF_BAD_HEADER; 692 | 693 | /* header is ALWAYS at begining of file */ 694 | fseek(file, 0, SEEK_SET); 695 | 696 | /* read the header data */ 697 | if(fread(&headers, 1, sizeof(headers), file) == 0) { 698 | fclose(file); 699 | return CART_INVALID; 700 | } 701 | 702 | fclose(file); 703 | 704 | ret = check_header_UNIF(&(headers.unif_header)); 705 | if(ret == UNIF_OK || ret == UNIF_DIRTY_HEADER) { 706 | return CART_UNIF; 707 | } 708 | 709 | ret = check_header_INES(&(headers.ines_header), 1); 710 | if(ret == UNIF_OK || ret == UNIF_DIRTY_HEADER) { 711 | return CART_INES; 712 | } 713 | 714 | return CART_INVALID; 715 | } 716 | -------------------------------------------------------------------------------- /ines_convert.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef INES_CONVERT_20080314_H_ 20 | #define INES_CONVERT_20080314_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | #include "unif_types.h" 27 | 28 | #include 29 | 30 | typedef enum { 31 | CART_UNIF, 32 | CART_INES, 33 | CART_INVALID 34 | } CART_TYPE; 35 | 36 | typedef struct { 37 | int has_chr_rom; 38 | uint8_t ines_number; 39 | int four_screen; 40 | } ines_info_t; 41 | 42 | typedef struct { 43 | const char *board_name; 44 | uint8_t ines_number; 45 | int chr_rom; 46 | int four_screen; 47 | } mapr_num_table_t; 48 | 49 | void make_unif_file_from_nes(const char *unif_file, const char *ines_file); 50 | int get_ines_mapper(const char *board_name, ines_info_t *info); 51 | CART_TYPE get_cart_type(const char *filename); 52 | 53 | UNIF_RETURN_CODE write_header(FILE *file); 54 | UNIF_RETURN_CODE write_mapr(FILE *file); 55 | UNIF_RETURN_CODE write_name(FILE *file); 56 | UNIF_RETURN_CODE write_prg(FILE *file, uint8_t *prg_code, size_t size); 57 | UNIF_RETURN_CODE write_chr(FILE *file, uint8_t *chr_code, size_t size); 58 | UNIF_RETURN_CODE write_read(FILE *file); 59 | UNIF_RETURN_CODE write_tvsc(FILE *file); 60 | UNIF_RETURN_CODE write_dinf(FILE *file); 61 | UNIF_RETURN_CODE write_batr(FILE *file); 62 | UNIF_RETURN_CODE write_pck(FILE *file, uint8_t *prg_code, size_t size); 63 | UNIF_RETURN_CODE write_cck(FILE *file, uint8_t *chr_code, size_t size); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif 70 | 71 | -------------------------------------------------------------------------------- /lib_ines.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifdef _MSC_VER 20 | #pragma warning( disable : 4127 ) 21 | #endif 22 | 23 | #include "lib_ines.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | /*----------------------------------------------------------------------------- 30 | // open_INES(const char *filename, FILE **file, UNIF_OPEN_MODE mode) 31 | //---------------------------------------------------------------------------*/ 32 | UNIF_RETURN_CODE open_INES(const char *filename, FILE **file, UNIF_OPEN_MODE mode) { 33 | 34 | /* check pointers */ 35 | assert(filename != 0); 36 | assert(file != 0); 37 | 38 | /* open the file */ 39 | if(mode == UNIF_OPEN_READ) *file = fopen(filename, "rb"); 40 | else *file = fopen(filename, "wb"); 41 | 42 | /* check if successful */ 43 | if(*file == 0) { 44 | return UNIF_OPEN_FAILED; 45 | } 46 | 47 | return UNIF_OK; 48 | } 49 | 50 | /*----------------------------------------------------------------------------- 51 | // close_INES(FILE *file) 52 | //---------------------------------------------------------------------------*/ 53 | UNIF_RETURN_CODE close_INES(FILE *file) { 54 | 55 | /* check pointers */ 56 | assert(file != 0); 57 | 58 | /* close file */ 59 | if(fclose(file) == EOF) { 60 | return UNIF_CLOSE_FAILED; 61 | } 62 | 63 | return UNIF_OK; 64 | } 65 | 66 | /*----------------------------------------------------------------------------- 67 | // read_header_INES(FILE *file, ines_header_t *header) 68 | //---------------------------------------------------------------------------*/ 69 | UNIF_RETURN_CODE read_header_INES(FILE *file, ines_header_t *header) { 70 | 71 | /* check pointers */ 72 | assert(file != 0); 73 | assert(header != 0); 74 | 75 | /* header is ALWAYS at begining of file */ 76 | rewind(file); 77 | 78 | /* read the header data */ 79 | if(fread(header, 1, sizeof(ines_header_t), file) != sizeof(ines_header_t)) { 80 | return UNIF_READ_FAILED; 81 | } 82 | 83 | return UNIF_OK; 84 | } 85 | 86 | /*----------------------------------------------------------------------------- 87 | // write_header_INES(FILE *file, const ines_header_t *header) 88 | //---------------------------------------------------------------------------*/ 89 | UNIF_RETURN_CODE write_header_INES(FILE *file, const ines_header_t *header) { 90 | /* check pointers */ 91 | assert(file != 0); 92 | assert(header != 0); 93 | 94 | /* header is ALWAYS at begining of file */ 95 | rewind(file); 96 | 97 | /* write the header data */ 98 | if(fwrite(header, 1, sizeof(ines_header_t), file) != sizeof(ines_header_t)) { 99 | return UNIF_WRITE_FAILED; 100 | } 101 | 102 | return UNIF_OK; 103 | } 104 | 105 | /*----------------------------------------------------------------------------- 106 | // check_header_INES(const ines_header_t *header, int version) 107 | //---------------------------------------------------------------------------*/ 108 | UNIF_RETURN_CODE check_header_INES(const ines_header_t *header, int version) { 109 | 110 | assert(header != 0); 111 | 112 | if(memcmp(header->ines_signature, "NES\x1a", 4) != 0) { 113 | return UNIF_BAD_HEADER; 114 | } 115 | 116 | if(version != 2) { 117 | if(header->extended.ines1.reserved_2 != 0 || header->extended.ines1.reserved_1 != 0) { 118 | return UNIF_DIRTY_HEADER; 119 | } 120 | } 121 | 122 | return UNIF_OK; 123 | } 124 | 125 | /*----------------------------------------------------------------------------- 126 | // read_data_INES( FILE * file, uint8_t *dst, size_t len ) 127 | //---------------------------------------------------------------------------*/ 128 | UNIF_RETURN_CODE read_data_INES(FILE *file, uint8_t *dst, size_t len) { 129 | assert(file != 0); 130 | assert(dst != 0); 131 | 132 | if(fread(dst, 1, len, file) != len) { 133 | return UNIF_READ_FAILED; 134 | } 135 | 136 | return UNIF_OK; 137 | } 138 | -------------------------------------------------------------------------------- /lib_ines.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef LIB_INES_20080314_H_ 20 | #define LIB_INES_20080314_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | #include "unif_types.h" 27 | #include 28 | 29 | /* Layout of First Sixteen Bytes of NES Cartridge in iNES format*/ 30 | typedef struct { 31 | char ines_signature[4]; /* 0x1A53454E (NES file signature) */ 32 | uint8_t prg_size; /* in 16k banks */ 33 | uint8_t chr_size; /* in 8k banks */ 34 | uint8_t ctrl1; /* %NNNN.FTBM */ 35 | uint8_t ctrl2; /* %NNNN.SSPV (version 2.0 when SS = 10b*/ 36 | 37 | /* in iNES 2.0, these mean something, otherwise, should be 0 */ 38 | union { 39 | struct ines2_t { 40 | uint8_t byte8; /* %SSSS.MMMM */ 41 | uint8_t byte9; /* %CCCC.PPPP */ 42 | uint8_t byte10; /* %pppp.PPPP */ 43 | uint8_t byte11; /* %cccc.CCCC */ 44 | uint8_t byte12; /* %xxxx.xxBP */ 45 | uint8_t byte13; /* %MMMM.PPPP */ 46 | uint8_t byte14; /* reserved */ 47 | uint8_t byte15; /* reserved */ 48 | } ines2; 49 | 50 | struct ines1_t { 51 | uint32_t reserved_1; 52 | uint32_t reserved_2; 53 | } ines1; 54 | } extended; 55 | } ines_header_t; 56 | 57 | /* Flags in NES_HEADER.ctrl1 */ 58 | #define INES_MIRROR 0x01 59 | #define INES_SRAM 0x02 60 | #define INES_TRAINER 0x04 61 | #define INES_4SCREEN 0x08 62 | 63 | /* function prototypes */ 64 | UNIF_RETURN_CODE check_header_INES(const ines_header_t *header, int version); 65 | UNIF_RETURN_CODE close_INES(FILE *file); 66 | UNIF_RETURN_CODE open_INES(const char *filename, FILE **file, UNIF_OPEN_MODE mode); 67 | UNIF_RETURN_CODE read_data_INES(FILE *file, uint8_t *dst, size_t len); 68 | UNIF_RETURN_CODE read_header_INES(FILE *file, ines_header_t *header); 69 | UNIF_RETURN_CODE write_header_INES(FILE *file, const ines_header_t *header); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /lib_unif.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifdef _MSC_VER 20 | #pragma warning( disable : 4127 ) 21 | #endif 22 | 23 | #include "lib_unif.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | /*----------------------------------------------------------------------------- 30 | // name: open_UNIF(const char *filename, FILE **file, UNIF_OPEN_MODE mode) 31 | //---------------------------------------------------------------------------*/ 32 | UNIF_RETURN_CODE open_UNIF(const char *filename, FILE **file, UNIF_OPEN_MODE mode) { 33 | 34 | /* check pointers */ 35 | assert(file != 0); 36 | assert(filename != 0); 37 | 38 | /* open the file */ 39 | if(mode == UNIF_OPEN_READ) *file = fopen(filename, "rb"); 40 | else *file = fopen(filename, "wb"); 41 | 42 | /* check if successful */ 43 | if(*file == 0) { 44 | return UNIF_OPEN_FAILED; 45 | } 46 | 47 | return UNIF_OK; 48 | } 49 | 50 | /*----------------------------------------------------------------------------- 51 | // name: check_header_UNIF(unif_header_t *header) 52 | //---------------------------------------------------------------------------*/ 53 | UNIF_RETURN_CODE check_header_UNIF(unif_header_t *header) { 54 | 55 | /* check pointers */ 56 | assert(header != 0); 57 | 58 | /* check if the tag is right */ 59 | if(memcmp(header->id, "UNIF", 4) != 0) { 60 | return UNIF_BAD_HEADER; 61 | } 62 | 63 | /* is this revision too high for this lib? */ 64 | if(header->revision > UNIF_REVISION) { 65 | return UNIF_BAD_REVISION_NUMBER; 66 | } 67 | 68 | /* make sure reserved space is all zeros */ 69 | if(memcmp( 70 | header->expansion, 71 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 72 | sizeof(header->expansion) 73 | )) { 74 | return UNIF_DIRTY_HEADER; 75 | } 76 | 77 | return UNIF_OK; 78 | } 79 | 80 | /*----------------------------------------------------------------------------- 81 | // name: close_UNIF(FILE *file) 82 | //---------------------------------------------------------------------------*/ 83 | UNIF_RETURN_CODE close_UNIF(FILE *file) { 84 | 85 | /* check pointers */ 86 | assert(file != 0); 87 | 88 | /* close file */ 89 | if(fclose(file) == EOF) { 90 | return UNIF_CLOSE_FAILED; 91 | } 92 | 93 | return UNIF_OK; 94 | } 95 | 96 | /*----------------------------------------------------------------------------- 97 | // name: read_header_UNIF(FILE *file, unif_header_t *header) 98 | //---------------------------------------------------------------------------*/ 99 | UNIF_RETURN_CODE read_header_UNIF(FILE *file, unif_header_t *header) { 100 | 101 | /* check pointers */ 102 | assert(file != 0); 103 | assert(header != 0); 104 | 105 | /* header is ALWAYS at begining of file */ 106 | rewind(file); 107 | 108 | /* read the header data */ 109 | if(fread(header, 1, sizeof(unif_header_t), file) != sizeof(unif_header_t)) { 110 | return UNIF_READ_FAILED; 111 | } 112 | 113 | return UNIF_OK; 114 | } 115 | 116 | /*----------------------------------------------------------------------------- 117 | // name: write_header_UNIF(FILE *file, unif_header_t *header) 118 | //---------------------------------------------------------------------------*/ 119 | UNIF_RETURN_CODE write_header_UNIF(FILE *file, unif_header_t *header) { 120 | 121 | /* check pointers */ 122 | assert(file != 0); 123 | assert(header != 0); 124 | 125 | /* header is ALWAYS at begining of file */ 126 | rewind(file); 127 | 128 | /* write the header data */ 129 | if(fwrite(header, 1, sizeof(unif_header_t), file) != sizeof(unif_header_t)) { 130 | return UNIF_WRITE_FAILED; 131 | } 132 | 133 | return UNIF_OK; 134 | } 135 | 136 | /*----------------------------------------------------------------------------- 137 | // name: read_chunk_UNIF(FILE *file, unif_chunk_t *chunk_header, void **chunk_data) 138 | //---------------------------------------------------------------------------*/ 139 | UNIF_RETURN_CODE read_chunk_UNIF(FILE *file, unif_chunk_t *chunk_header, void **chunk_data) { 140 | 141 | /* check pointers */ 142 | assert(file != 0); 143 | assert(chunk_header != 0); 144 | assert(chunk_data != 0); 145 | 146 | /* read the header of the chunk */ 147 | if(fread(chunk_header, 1, sizeof(unif_chunk_t), file) != sizeof(unif_chunk_t)) { 148 | /* on a failed read, check if it was because of EOF */ 149 | if(feof(file)) { 150 | return UNIF_END_OF_FILE; 151 | } 152 | 153 | return UNIF_READ_FAILED; 154 | } 155 | 156 | /* allocate memory for the chunk data */ 157 | *chunk_data = malloc(chunk_header->length); 158 | if(*chunk_data == 0) { 159 | return UNIF_OUT_OF_MEMORY; 160 | } 161 | 162 | /* read the chunk data */ 163 | if(fread(*chunk_data, 1, chunk_header->length, file) != chunk_header->length) { 164 | free(*chunk_data); 165 | return UNIF_READ_FAILED; 166 | } 167 | 168 | return UNIF_OK; 169 | } 170 | 171 | /*----------------------------------------------------------------------------- 172 | // name: write_chunk_UNIF(FILE *file, unif_chunk_t *chunk_header, void *chunk_data) 173 | //---------------------------------------------------------------------------*/ 174 | UNIF_RETURN_CODE write_chunk_UNIF(FILE *file, unif_chunk_t *chunk_header, void *chunk_data) { 175 | 176 | /* check pointers */ 177 | assert(file != 0); 178 | assert(chunk_header != 0); 179 | assert(chunk_data != 0); 180 | 181 | /* write the header of the chunk */ 182 | if(fwrite(chunk_header, 1, sizeof(unif_chunk_t), file) != sizeof(unif_chunk_t)) { 183 | return UNIF_WRITE_FAILED; 184 | } 185 | 186 | /* write the chunk data */ 187 | if(fwrite(chunk_data, 1, chunk_header->length, file) != chunk_header->length) { 188 | return UNIF_WRITE_FAILED; 189 | } 190 | 191 | return UNIF_OK; 192 | } 193 | 194 | /*----------------------------------------------------------------------------- 195 | // name: get_error_string_UNIF(UNIF_RETURN_CODE code) 196 | //---------------------------------------------------------------------------*/ 197 | const char *get_error_string_UNIF(UNIF_RETURN_CODE code) { 198 | 199 | switch (code) { 200 | case UNIF_OK: 201 | return "no error"; 202 | case UNIF_END_OF_FILE: 203 | return "buffer has hit end of file"; 204 | case UNIF_BAD_HEADER: 205 | return "invalid header"; 206 | case UNIF_BAD_REVISION_NUMBER: 207 | return "revision number of this ROM is not supported"; 208 | case UNIF_DIRTY_HEADER: 209 | return "the reserved area of the header has junk in it"; 210 | case UNIF_OUT_OF_MEMORY: 211 | return "failed to allocate memory"; 212 | case UNIF_OPEN_FAILED: 213 | return "could not open file for reading/writing"; 214 | case UNIF_READ_FAILED: 215 | return "could not read file"; 216 | case UNIF_CLOSE_FAILED: 217 | return "could not properly close file"; 218 | case UNIF_WRITE_FAILED: 219 | return "could not write to file"; 220 | case UNIF_INPUT_FAIL: 221 | return "input error"; 222 | case UNIF_LENGTH_ERROR: 223 | return "invalid length provided"; 224 | default: 225 | return "unknown error"; 226 | } 227 | } 228 | 229 | 230 | -------------------------------------------------------------------------------- /lib_unif.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef LIB_UNIF_20080314_H_ 20 | #define LIB_UNIF_20080314_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | #include "unif_types.h" 27 | 28 | #include 29 | 30 | /* the file we read MAY NOT have a revision greater than this */ 31 | #define UNIF_REVISION 0x00000007 32 | 33 | /* definitions for the CTRL block */ 34 | #define CTRL_STDJOY 0x01 /* Bit 0: Regular Joypad */ 35 | #define CTRL_ZAPPER 0x02 /* Bit 1: Zapper */ 36 | #define CTRL_ROB 0x04 /* Bit 2: R.O.B */ 37 | #define CTRL_ARKANOID 0x08 /* Bit 3: Arkanoid Controller */ 38 | #define CTRL_POWPAD 0x10 /* Bit 4: Power Pad */ 39 | #define CTRL_4SCORE 0x20 /* Bit 5: Four-Score adapter */ 40 | #define CTRL_RESERVE1 0x40 /* Bit 6: Expansion (Do not touch) */ 41 | #define CTRL_RESERVE2 0x80 /* Bit 7: Expansion (Do not touch) */ 42 | 43 | /* header structure */ 44 | typedef struct { 45 | char id[4]; /* MUST be "UNIF", NOT null terminated */ 46 | uint32_t revision; /* Revision number */ 47 | uint8_t expansion[24]; /* reserved */ 48 | } unif_header_t; 49 | 50 | /* chunk header */ 51 | typedef struct { 52 | char id[4]; /* Chunk identification string. */ 53 | uint32_t length; /* Data length, in little-endian format */ 54 | } unif_chunk_t; 55 | 56 | /* handy for reading dumper info */ 57 | typedef struct { 58 | char dumper_name[100]; /* NULL-terminated string containing the name of 59 | * the person who dumped the cart. */ 60 | unsigned char day; /* Day of the month when cartridge was dumped */ 61 | unsigned char month; /* Month of the year when cartridge was dumped */ 62 | unsigned short year; /* Year during which the cartridge was dumped */ 63 | char dumper_agent[100]; /* NULL-terminated string containing the name of 64 | * the ROM-dumping means used */ 65 | } dumper_info_t; 66 | 67 | 68 | /* function prototypes */ 69 | UNIF_RETURN_CODE open_UNIF(const char *filename, FILE **file, UNIF_OPEN_MODE mode); 70 | UNIF_RETURN_CODE close_UNIF(FILE *file); 71 | 72 | UNIF_RETURN_CODE read_header_UNIF(FILE *file, unif_header_t *header); 73 | UNIF_RETURN_CODE write_header_UNIF(FILE *file, unif_header_t *header); 74 | UNIF_RETURN_CODE check_header_UNIF(unif_header_t *header); 75 | 76 | UNIF_RETURN_CODE read_chunk_UNIF(FILE *file, unif_chunk_t *chunk_header, void **chunk_data ); 77 | UNIF_RETURN_CODE write_chunk_UNIF(FILE *file, unif_chunk_t *chunk_header, void *chunk_data ); 78 | 79 | const char *get_error_string_UNIF(UNIF_RETURN_CODE code); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | #endif 86 | 87 | -------------------------------------------------------------------------------- /load_ines.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "load_ines.h" 20 | #include "unif_crc32.h" 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | /*------------------------------------------------------------------------------ 27 | // Name: 28 | //----------------------------------------------------------------------------*/ 29 | size_t next_power(size_t size) { 30 | 31 | /* returns 1 less than closest fitting power of 2 32 | * is this number not a power of two or 0? 33 | */ 34 | if((size & (size - 1)) != 0) { 35 | --size; 36 | size |= size >> 1; 37 | size |= size >> 2; 38 | size |= size >> 4; 39 | size |= size >> 8; 40 | size |= size >> 16; 41 | ++size; 42 | } else if(size == 0) { 43 | ++size; 44 | } 45 | 46 | return size; 47 | } 48 | 49 | /*----------------------------------------------------------------------------- 50 | // Name: write_file_INES 51 | //---------------------------------------------------------------------------*/ 52 | UNIF_RETURN_CODE write_file_INES(const char *filename, const ines_cart_t *cart) { 53 | 54 | UNIF_RETURN_CODE retcode = UNIF_OK; 55 | FILE *file = 0; 56 | const int prg_size = prg_size_INES(cart) * 16384; 57 | const int chr_size = chr_size_INES(cart) * 8192; 58 | 59 | assert(filename != 0); 60 | assert(cart != 0); 61 | 62 | if((retcode = open_INES(filename, &file, UNIF_OPEN_WRITE)) != UNIF_OK) { 63 | return retcode; 64 | } 65 | 66 | if((retcode = write_header_INES(file, cart->header)) != UNIF_OK) { 67 | close_INES(file); 68 | return retcode; 69 | } 70 | 71 | if((cart->header->ctrl1 & INES_TRAINER) != 0) { 72 | if(fwrite(cart->trainer, 512, 1, file) != 1) { 73 | close_INES(file); 74 | return UNIF_WRITE_FAILED; 75 | } 76 | } 77 | 78 | if(prg_size > 0) { 79 | if(fwrite(cart->prg_rom, prg_size, 1, file) != 1) { 80 | close_INES(file); 81 | return UNIF_WRITE_FAILED; 82 | } 83 | } 84 | 85 | if(chr_size > 0) { 86 | if(fwrite(cart->chr_rom, chr_size, 1, file) != 1) { 87 | close_INES(file); 88 | return UNIF_WRITE_FAILED; 89 | } 90 | } 91 | 92 | close_INES(file); 93 | return retcode; 94 | } 95 | 96 | /*----------------------------------------------------------------------------- 97 | // Name: load_ptr_INES 98 | //---------------------------------------------------------------------------*/ 99 | UNIF_RETURN_CODE load_ptr_INES(const uint8_t *rom, size_t size, ines_cart_t *cart) { 100 | 101 | UNIF_RETURN_CODE retcode = UNIF_OK; 102 | const uint8_t *rom_ptr = 0; 103 | size_t prg_size = 0; 104 | size_t chr_size = 0; 105 | size_t trainer_size = 0; 106 | size_t prg_alloc_size = 0; 107 | size_t chr_alloc_size = 0; 108 | ines_header_t header; 109 | 110 | void *header_ptr = 0; 111 | void *prg_ptr = 0; 112 | void *chr_ptr = 0; 113 | void *trainer_ptr = 0; 114 | 115 | assert(cart != 0); 116 | assert(rom != 0); 117 | 118 | if(size < sizeof(ines_header_t)) { 119 | return UNIF_LENGTH_ERROR; 120 | } 121 | 122 | memcpy(&header, rom, sizeof(ines_header_t)); 123 | 124 | cart->header = 0; 125 | cart->trainer = 0; 126 | cart->prg_rom = 0; 127 | cart->chr_rom = 0; 128 | cart->version = ((header.ctrl2 & 0xc) == 0x8) ? 2 : 1; 129 | 130 | retcode = check_header_INES(&header, cart->version); 131 | if((retcode != UNIF_OK) && (retcode != UNIF_DIRTY_HEADER)) { 132 | return retcode; 133 | } 134 | 135 | /* temporarily make the cart point to our read header */ 136 | cart->header = &header; 137 | 138 | if((header.ctrl1 & INES_TRAINER) != 0) { 139 | trainer_size = 512; 140 | } 141 | 142 | prg_size = prg_size_INES(cart) * 16384; 143 | chr_size = chr_size_INES(cart) * 8192; 144 | 145 | prg_alloc_size = next_power(prg_size); 146 | chr_alloc_size = next_power(chr_size); 147 | 148 | /* NULL the cart header pointer, it was temporary */ 149 | cart->header = 0; 150 | 151 | if(size < sizeof(ines_header_t) + trainer_size + prg_size + chr_size) { 152 | return UNIF_LENGTH_ERROR; 153 | } 154 | 155 | /* allocate memory for the cart */ 156 | header_ptr = malloc(sizeof(ines_header_t)); 157 | prg_ptr = prg_size ? malloc(prg_alloc_size) : 0; 158 | chr_ptr = chr_size ? malloc(chr_alloc_size) : 0; 159 | trainer_ptr = trainer_size ? malloc(trainer_size) : 0; 160 | 161 | /* make sure it all went smoothly */ 162 | if((!header_ptr) || (prg_size & !prg_ptr) || (chr_size & !chr_ptr) || (trainer_size & !trainer_ptr)) { 163 | free(header_ptr); 164 | free(prg_ptr); 165 | free(chr_ptr); 166 | free(trainer_ptr); 167 | 168 | cart->header = 0; 169 | cart->trainer = 0; 170 | cart->prg_rom = 0; 171 | cart->chr_rom = 0; 172 | 173 | return UNIF_OUT_OF_MEMORY; 174 | } 175 | 176 | /* assign some pointers */ 177 | cart->header = header_ptr; 178 | cart->prg_rom = prg_ptr; 179 | cart->chr_rom = chr_ptr; 180 | cart->trainer = trainer_ptr; 181 | 182 | rom_ptr = rom; 183 | 184 | memcpy(cart->header, rom_ptr, sizeof(ines_header_t)); 185 | rom_ptr += sizeof(ines_header_t); 186 | 187 | if(trainer_size) { 188 | memcpy(cart->trainer, rom_ptr, trainer_size); 189 | rom_ptr += trainer_size; 190 | } 191 | 192 | memcpy(cart->prg_rom, rom_ptr, prg_size); 193 | if((prg_alloc_size - prg_size) > 0x2000 && prg_size >= 0x2000) { 194 | /* replicate the last bank if necessary */ 195 | uint8_t *const last_8k = cart->prg_rom + prg_size - 0x2000; 196 | uint8_t *p = cart->prg_rom + prg_size; 197 | while(p < cart->prg_rom + prg_alloc_size) { 198 | memcpy(p, last_8k, 0x2000); 199 | p += 0x2000; 200 | } 201 | } 202 | 203 | rom_ptr += prg_size; 204 | 205 | if(chr_size != 0) { 206 | memcpy(cart->chr_rom, rom_ptr, chr_size); 207 | if(chr_size != chr_alloc_size) { 208 | uint8_t *p = cart->chr_rom + chr_size; 209 | while(p != cart->chr_rom + chr_alloc_size) { 210 | *p++ = 0xff; 211 | } 212 | } 213 | } 214 | 215 | return retcode; 216 | } 217 | 218 | /*----------------------------------------------------------------------------- 219 | // Name: load_file_INES 220 | //---------------------------------------------------------------------------*/ 221 | UNIF_RETURN_CODE load_file_INES(const char *filename, ines_cart_t *cart) { 222 | 223 | UNIF_RETURN_CODE retcode = UNIF_OK; 224 | 225 | FILE *file = 0; 226 | size_t trainer_size = 0; 227 | size_t prg_size = 0; 228 | size_t chr_size = 0; 229 | size_t prg_alloc_size = 0; 230 | size_t chr_alloc_size = 0; 231 | ines_header_t header; 232 | 233 | void *header_ptr = 0; 234 | void *prg_ptr = 0; 235 | void *chr_ptr = 0; 236 | void *trainer_ptr = 0; 237 | 238 | assert(cart != 0); 239 | assert(filename != 0); 240 | 241 | cart->header = 0; 242 | cart->trainer = 0; 243 | cart->prg_rom = 0; 244 | cart->chr_rom = 0; 245 | 246 | if((retcode = open_INES(filename, &file, UNIF_OPEN_READ)) != UNIF_OK) { 247 | return retcode; 248 | } 249 | 250 | if((retcode = read_header_INES(file, &header)) != UNIF_OK) { 251 | close_INES(file); 252 | return retcode; 253 | } 254 | 255 | cart->version = ((header.ctrl2 & 0xc) == 0x8) ? 2 : 1; 256 | 257 | retcode = check_header_INES(&header, cart->version); 258 | if((retcode != UNIF_OK) && (retcode != UNIF_DIRTY_HEADER)) { 259 | close_INES(file); 260 | return retcode; 261 | } 262 | 263 | /* temporarily make the cart point to our read header */ 264 | cart->header = &header; 265 | 266 | if((header.ctrl1 & INES_TRAINER) != 0) { 267 | trainer_size = 512; 268 | } 269 | 270 | prg_size = prg_size_INES(cart) * 16384; 271 | chr_size = chr_size_INES(cart) * 8192; 272 | 273 | prg_alloc_size = next_power(prg_size); 274 | chr_alloc_size = next_power(chr_size); 275 | 276 | /* NULL the cart header pointer, it was temporary */ 277 | cart->header = 0; 278 | 279 | /* allocate memory for the cart */ 280 | header_ptr = malloc(sizeof(ines_header_t)); 281 | prg_ptr = prg_size ? malloc(prg_alloc_size) : 0; 282 | chr_ptr = chr_size ? malloc(chr_alloc_size) : 0; 283 | trainer_ptr = trainer_size ? malloc(trainer_size) : 0; 284 | 285 | /* make sure it all went smoothly */ 286 | if((!header_ptr) || (prg_size & !prg_ptr) || (chr_size & !chr_ptr) || (trainer_size & !trainer_ptr)) { 287 | retcode = UNIF_OUT_OF_MEMORY; 288 | goto error; 289 | } 290 | 291 | /* assign some pointers */ 292 | cart->header = header_ptr; 293 | cart->prg_rom = prg_ptr; 294 | cart->chr_rom = chr_ptr; 295 | cart->trainer = trainer_ptr; 296 | 297 | memcpy(cart->header, &header, sizeof(ines_header_t)); 298 | if(trainer_size != 0) { 299 | retcode = read_data_INES(file, cart->trainer, trainer_size); 300 | if(retcode != UNIF_OK) { 301 | goto error; 302 | } 303 | } 304 | 305 | if(prg_size != 0) { 306 | retcode = read_data_INES(file, cart->prg_rom, prg_size); 307 | if(retcode != UNIF_OK) { 308 | goto error; 309 | } 310 | 311 | if((prg_alloc_size - prg_size) > 0x2000 && prg_size >= 0x2000) { 312 | /* replicate the last bank if necessary */ 313 | uint8_t *const last_8k = cart->prg_rom + prg_size - 0x2000; 314 | uint8_t *p = cart->prg_rom + prg_size; 315 | while(p < cart->prg_rom + prg_alloc_size) { 316 | memcpy(p, last_8k, 0x2000); 317 | p += 0x2000; 318 | } 319 | } 320 | } 321 | 322 | if(chr_size != 0) { 323 | uint8_t *p; 324 | retcode = read_data_INES(file, cart->chr_rom, chr_size); 325 | if(retcode != UNIF_OK) { 326 | goto error; 327 | } 328 | 329 | p = cart->chr_rom + chr_size; 330 | while(p != cart->chr_rom + chr_alloc_size) { 331 | *p++ = 0xff; 332 | } 333 | } 334 | 335 | close_INES(file); 336 | return retcode; 337 | 338 | error: 339 | free(header_ptr); 340 | free(prg_ptr); 341 | free(chr_ptr); 342 | free(trainer_ptr); 343 | 344 | cart->header = 0; 345 | cart->trainer = 0; 346 | cart->prg_rom = 0; 347 | cart->chr_rom = 0; 348 | 349 | close_INES(file); 350 | return retcode; 351 | } 352 | 353 | /*----------------------------------------------------------------------------- 354 | // Name: free_file_INES 355 | //---------------------------------------------------------------------------*/ 356 | UNIF_RETURN_CODE free_file_INES(ines_cart_t *cart) { 357 | assert(cart); 358 | 359 | free(cart->header); 360 | free(cart->trainer); 361 | free(cart->prg_rom); 362 | free(cart->chr_rom); 363 | 364 | cart->header = 0; 365 | cart->trainer = 0; 366 | cart->prg_rom = 0; 367 | cart->chr_rom = 0; 368 | 369 | return UNIF_OK; 370 | } 371 | 372 | /*----------------------------------------------------------------------------- 373 | // Name: mirroring_INES 374 | //---------------------------------------------------------------------------*/ 375 | INES_MIRRORING mirroring_INES(const ines_cart_t *cart) { 376 | 377 | assert(cart); 378 | 379 | switch(cart->header->ctrl1 & 0x09) { 380 | case 0x09: 381 | case 0x08: 382 | return MIRR_4SCREEN; 383 | case 0x01: 384 | return MIRR_VERTICAL; 385 | case 0x00: 386 | default: 387 | return MIRR_HORIZONTAL; 388 | } 389 | } 390 | 391 | /*----------------------------------------------------------------------------- 392 | // Name: system_INES 393 | //---------------------------------------------------------------------------*/ 394 | INES_SYSTEM system_INES(const ines_cart_t *cart) { 395 | assert(cart); 396 | 397 | switch(cart->header->ctrl2 & 0x03) { 398 | case 0x01: return SYS_VS; 399 | case 0x02: return SYS_P10; 400 | default: 401 | return SYS_NES; 402 | } 403 | } 404 | 405 | /*----------------------------------------------------------------------------- 406 | // Name: mapper_INES 407 | //---------------------------------------------------------------------------*/ 408 | uint32_t mapper_INES(const ines_cart_t *cart) { 409 | 410 | assert(cart); 411 | 412 | switch(cart->version) { 413 | case 2: 414 | return (((uint32_t)(cart->header->extended.ines2.byte8 & 0x0f)) << 8) | (cart->header->ctrl1 >> 4) | (cart->header->ctrl2 & 0xf0); 415 | default: 416 | return (cart->header->ctrl1 >> 4) | (cart->header->ctrl2 & 0xf0); 417 | } 418 | } 419 | 420 | /*----------------------------------------------------------------------------- 421 | // Name: mapper_INES 422 | //---------------------------------------------------------------------------*/ 423 | uint32_t submapper_INES(const ines_cart_t *cart) { 424 | 425 | assert(cart); 426 | 427 | switch(cart->version) { 428 | case 2: 429 | return (cart->header->extended.ines2.byte8 & 0xf0) >> 4; 430 | default: 431 | return 0; 432 | } 433 | } 434 | 435 | /*----------------------------------------------------------------------------- 436 | // Name: prg_size_INES 437 | //---------------------------------------------------------------------------*/ 438 | uint32_t prg_size_INES(const ines_cart_t *cart) { 439 | 440 | assert(cart); 441 | 442 | switch(cart->version) { 443 | case 2: 444 | return cart->header->prg_size | (((uint32_t)cart->header->extended.ines2.byte9 & 0x0f) << 8); 445 | default: 446 | return cart->header->prg_size; 447 | } 448 | } 449 | 450 | /*----------------------------------------------------------------------------- 451 | // Name: chr_size_INES 452 | //---------------------------------------------------------------------------*/ 453 | uint32_t chr_size_INES(const ines_cart_t *cart) { 454 | 455 | assert(cart); 456 | 457 | switch(cart->version) { 458 | case 2: 459 | return cart->header->chr_size | (((uint32_t)cart->header->extended.ines2.byte9 & 0xf0) << 4); 460 | default: 461 | return cart->header->chr_size; 462 | } 463 | } 464 | 465 | /*----------------------------------------------------------------------------- 466 | // Name: display_INES 467 | //---------------------------------------------------------------------------*/ 468 | INES_DISPLAY display_INES(const ines_cart_t *cart) { 469 | switch(cart->version) { 470 | case 2: 471 | switch(cart->header->extended.ines2.byte12 & 0x03) { 472 | case 0x00: return DISP_NTSC; 473 | case 0x01: return DISP_PAL; 474 | case 0x02: return DISP_BOTH; 475 | case 0x03: return DISP_BOTH; 476 | } 477 | default: 478 | return DISP_BOTH; 479 | } 480 | } 481 | 482 | /*----------------------------------------------------------------------------- 483 | // Name: ppu_INES 484 | //---------------------------------------------------------------------------*/ 485 | INES_PPU ppu_INES(const ines_cart_t *cart) { 486 | switch(cart->version) { 487 | case 2: 488 | switch(cart->header->extended.ines2.byte13 & 0x0f) { 489 | case 0x00: return PPU_RP2C03B; 490 | case 0x01: return PPU_RP2C03G; 491 | case 0x02: return PPU_RP2C04_0001; 492 | case 0x03: return PPU_RP2C04_0002; 493 | case 0x04: return PPU_RP2C04_0003; 494 | case 0x05: return PPU_RP2C04_0004; 495 | case 0x06: return PPU_RC2C03B; 496 | case 0x07: return PPU_RC2C03C; 497 | case 0x08: return PPU_RC2C05_01; 498 | case 0x09: return PPU_RC2C05_02; 499 | case 0x0a: return PPU_RC2C05_03; 500 | case 0x0b: return PPU_RC2C05_04; 501 | case 0x0c: return PPU_RC2C05_05; 502 | default: 503 | return PPU_UNKNOWN; 504 | } 505 | default: 506 | return PPU_UNKNOWN; 507 | } 508 | } 509 | 510 | /*----------------------------------------------------------------------------- 511 | // Name: prg_hash_INES 512 | //---------------------------------------------------------------------------*/ 513 | uint32_t prg_hash_INES(const ines_cart_t *cart) { 514 | return unif_crc32(cart->prg_rom, prg_size_INES(cart) * 0x4000, 0); 515 | } 516 | 517 | /*----------------------------------------------------------------------------- 518 | // Name: chr_hash_INES 519 | //---------------------------------------------------------------------------*/ 520 | uint32_t chr_hash_INES(const ines_cart_t *cart) { 521 | return unif_crc32(cart->chr_rom, chr_size_INES(cart) * 0x2000, 0); 522 | } 523 | 524 | 525 | /*----------------------------------------------------------------------------- 526 | // Name: rom_hash_INES 527 | //---------------------------------------------------------------------------*/ 528 | uint32_t rom_hash_INES(const ines_cart_t *cart) { 529 | 530 | const uint32_t hash1 = cart->trainer ? unif_crc32(cart->trainer, 512, 0) : 0; 531 | const uint32_t hash2 = cart->prg_rom ? unif_crc32(cart->prg_rom, prg_size_INES(cart) * 0x4000, hash1) : hash1; 532 | const uint32_t hash3 = cart->prg_rom ? unif_crc32(cart->chr_rom, chr_size_INES(cart) * 0x2000, hash2) : hash2; 533 | 534 | return hash3; 535 | 536 | } 537 | 538 | -------------------------------------------------------------------------------- /load_ines.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef LOAD_INES_20080314_H_ 20 | #define LOAD_INES_20080314_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | #include "lib_ines.h" 27 | 28 | /* description of a ines file */ 29 | typedef struct { 30 | ines_header_t *header; 31 | uint8_t *trainer; 32 | uint8_t *prg_rom; 33 | uint8_t *chr_rom; 34 | uint8_t version; 35 | } ines_cart_t; 36 | 37 | typedef enum { 38 | MIRR_HORIZONTAL, 39 | MIRR_VERTICAL, 40 | MIRR_4SCREEN 41 | } INES_MIRRORING; 42 | 43 | typedef enum { 44 | SYS_NES, 45 | SYS_P10, 46 | SYS_VS 47 | } INES_SYSTEM; 48 | 49 | typedef enum { 50 | DISP_NTSC, 51 | DISP_PAL, 52 | DISP_BOTH 53 | } INES_DISPLAY; 54 | 55 | typedef enum { 56 | PPU_UNKNOWN, 57 | PPU_RP2C03B, /* (bog standard RGB palette) */ 58 | PPU_RP2C03G, /* (similar pallete to above, might have 1 changed colour) */ 59 | PPU_RP2C04_0001, /* (scrambled palette + new colours) */ 60 | PPU_RP2C04_0002, /* (same as above, different scrambling, diff new colours) */ 61 | PPU_RP2C04_0003, /* (similar to above) */ 62 | PPU_RP2C04_0004, /* (similar to above) */ 63 | PPU_RC2C03B, /* (bog standard palette, seems identical to RP2C03B) */ 64 | PPU_RC2C03C, /* (similar to above, but with 1 changed colour or so) */ 65 | PPU_RC2C05_01, /* (all five of these have the normal palette... */ 66 | PPU_RC2C05_02, /* (...but with different bits returned on 2002) */ 67 | PPU_RC2C05_03, 68 | PPU_RC2C05_04, 69 | PPU_RC2C05_05, 70 | PPU_RESERVED_1, 71 | PPU_RESERVED_2, 72 | PPU_RESERVED_3 73 | } INES_PPU; 74 | 75 | /* some example implementations for loading and freeing a INES file */ 76 | UNIF_RETURN_CODE load_file_INES(const char *filename, ines_cart_t *cart); 77 | UNIF_RETURN_CODE free_file_INES(ines_cart_t *cart); 78 | UNIF_RETURN_CODE load_ptr_INES(const uint8_t *rom, size_t size, ines_cart_t *cart); 79 | UNIF_RETURN_CODE write_file_INES(const char *filename, const ines_cart_t *cart); 80 | 81 | /* API access to iNES data, works with version 2.0 ROMs as well */ 82 | INES_MIRRORING mirroring_INES(const ines_cart_t *cart); 83 | INES_SYSTEM system_INES(const ines_cart_t *cart); 84 | INES_DISPLAY display_INES(const ines_cart_t *cart); 85 | INES_PPU ppu_INES(const ines_cart_t *cart); 86 | uint32_t mapper_INES(const ines_cart_t *cart); 87 | uint32_t submapper_INES(const ines_cart_t *cart); 88 | uint32_t prg_size_INES(const ines_cart_t *cart); 89 | uint32_t chr_size_INES(const ines_cart_t *cart); 90 | uint32_t prg_hash_INES(const ines_cart_t *cart); 91 | uint32_t chr_hash_INES(const ines_cart_t *cart); 92 | uint32_t rom_hash_INES(const ines_cart_t *cart); 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /load_unif.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifdef _MSC_VER 20 | #pragma warning( disable : 4127 ) 21 | #endif 22 | 23 | #include "load_unif.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #define SAFE_FREE(x) do { free(x); (x) = 0; } while(0) 30 | 31 | /*----------------------------------------------------------------------------- 32 | // name: load_file_UNIF(const char *filename, unif_cart_t *cart) 33 | //---------------------------------------------------------------------------*/ 34 | UNIF_RETURN_CODE load_file_UNIF(const char *filename, unif_cart_t *cart) { 35 | FILE *unif_file = 0; 36 | UNIF_RETURN_CODE ret_val; 37 | 38 | assert(cart != 0); 39 | assert(filename != 0); 40 | 41 | /* clear out out structure we use to store file info */ 42 | memset(cart, 0, sizeof(unif_cart_t)); 43 | 44 | /* open the file */ 45 | ret_val = open_UNIF(filename, &unif_file, UNIF_OPEN_READ); 46 | 47 | if(ret_val == UNIF_OK) { 48 | 49 | /* read the header */ 50 | /* automaticaly sets file pointer to begining of file */ 51 | ret_val = read_header_UNIF(unif_file, &cart->header); 52 | if(ret_val != UNIF_OK) { 53 | close_UNIF(unif_file); 54 | return ret_val; 55 | } 56 | 57 | /* do a check to see if the header is valid */ 58 | ret_val = check_header_UNIF(&(cart->header)); 59 | if(ret_val != UNIF_OK) { 60 | close_UNIF(unif_file); 61 | return ret_val; 62 | } 63 | 64 | /* as long as we dont have an error, proccess tags */ 65 | while(ret_val == UNIF_OK) { 66 | unif_chunk_t chunk_hdr = { "", 0 }; 67 | 68 | union { 69 | void *ptr; 70 | uint8_t *ptr8; 71 | uint32_t *ptr32; 72 | char *str; 73 | } chunk_data = { 0 }; 74 | 75 | ret_val = read_chunk_UNIF(unif_file, &chunk_hdr, &chunk_data.ptr); 76 | 77 | /* did we hit the end of the file? */ 78 | if(ret_val == UNIF_END_OF_FILE) 79 | break; 80 | 81 | /* if the read was ok, store it */ 82 | if(ret_val == UNIF_OK) { 83 | 84 | if(memcmp(chunk_hdr.id, "DINF", 4) == 0) { 85 | cart->dumper_info = chunk_data.ptr; 86 | } else if(memcmp(chunk_hdr.id, "MAPR", 4) == 0) { 87 | cart->mapr_name = chunk_data.str; 88 | } else if(memcmp(chunk_hdr.id, "READ", 4) == 0) { 89 | cart->read_text = chunk_data.str; 90 | } else if(memcmp(chunk_hdr.id, "NAME", 4) == 0) { 91 | cart->name = chunk_data.str; 92 | } else if(memcmp(chunk_hdr.id, "TVCI", 4) == 0) { 93 | cart->tvci_byte = chunk_data.ptr8; 94 | } else if(memcmp(chunk_hdr.id, "CTRL", 4) == 0) { 95 | cart->ctrl_byte = chunk_data.ptr8; 96 | } else if(memcmp(chunk_hdr.id, "BATR", 4) == 0) { 97 | cart->batr_byte = chunk_data.ptr8; 98 | } else if(memcmp(chunk_hdr.id, "VROR", 4) == 0) { 99 | cart->vror_byte = chunk_data.ptr8; 100 | } else if(memcmp(chunk_hdr.id, "MIRR", 4) == 0) { 101 | cart->mirr_data = chunk_data.ptr8; 102 | 103 | } else if(memcmp(chunk_hdr.id, "PRG", 3) == 0) { 104 | switch(chunk_hdr.id[3]) { 105 | case '0': 106 | cart->prg[0x00] = chunk_data.ptr8; 107 | cart->prg_pages[0x00] = (chunk_hdr.length >> 14); 108 | break; 109 | case '1': 110 | cart->prg[0x01] = chunk_data.ptr8; 111 | cart->prg_pages[0x01] = (chunk_hdr.length >> 14); 112 | break; 113 | case '2': 114 | cart->prg[0x02] = chunk_data.ptr8; 115 | cart->prg_pages[0x02] = (chunk_hdr.length >> 14); 116 | break; 117 | case '3': 118 | cart->prg[0x03] = chunk_data.ptr8; 119 | cart->prg_pages[0x03] = (chunk_hdr.length >> 14); 120 | break; 121 | case '4': 122 | cart->prg[0x04] = chunk_data.ptr8; 123 | cart->prg_pages[0x04] = (chunk_hdr.length >> 14); 124 | break; 125 | case '5': 126 | cart->prg[0x05] = chunk_data.ptr8; 127 | cart->prg_pages[0x05] = (chunk_hdr.length >> 14); 128 | break; 129 | case '6': 130 | cart->prg[0x06] = chunk_data.ptr8; 131 | cart->prg_pages[0x06] = (chunk_hdr.length >> 14); 132 | break; 133 | case '7': 134 | cart->prg[0x07] = chunk_data.ptr8; 135 | cart->prg_pages[0x07] = (chunk_hdr.length >> 14); 136 | break; 137 | case '8': 138 | cart->prg[0x08] = chunk_data.ptr8; 139 | cart->prg_pages[0x08] = (chunk_hdr.length >> 14); 140 | break; 141 | case '9': 142 | cart->prg[0x09] = chunk_data.ptr8; 143 | cart->prg_pages[0x09] = (chunk_hdr.length >> 14); 144 | break; 145 | case 'A': 146 | cart->prg[0x0a] = chunk_data.ptr8; 147 | cart->prg_pages[0x0a] = (chunk_hdr.length >> 14); 148 | break; 149 | case 'B': 150 | cart->prg[0x0b] = chunk_data.ptr8; 151 | cart->prg_pages[0x0b] = (chunk_hdr.length >> 14); 152 | break; 153 | case 'C': 154 | cart->prg[0x0c] = chunk_data.ptr8; 155 | cart->prg_pages[0x0c] = (chunk_hdr.length >> 14); 156 | break; 157 | case 'D': 158 | cart->prg[0x0d] = chunk_data.ptr8; 159 | cart->prg_pages[0x0d] = (chunk_hdr.length >> 14); 160 | break; 161 | case 'E': 162 | cart->prg[0x0e] = chunk_data.ptr8; 163 | cart->prg_pages[0x0e] = (chunk_hdr.length >> 14); 164 | break; 165 | case 'F': 166 | cart->prg[0x0f] = chunk_data.ptr8; 167 | cart->prg_pages[0x0f] = (chunk_hdr.length >> 14); 168 | break; 169 | default: 170 | SAFE_FREE(chunk_data.ptr); 171 | } 172 | } else if(memcmp(chunk_hdr.id, "CHR", 3) == 0) { 173 | switch(chunk_hdr.id[3]) { 174 | case '0': 175 | cart->chr[0x00] = chunk_data.ptr8; 176 | cart->chr_pages[0x00] = (chunk_hdr.length >> 13); 177 | break; 178 | case '1': 179 | cart->chr[0x01] = chunk_data.ptr8; 180 | cart->chr_pages[0x01] = (chunk_hdr.length >> 13); 181 | break; 182 | case '2': 183 | cart->chr[0x02] = chunk_data.ptr8; 184 | cart->chr_pages[0x02] = (chunk_hdr.length >> 13); 185 | break; 186 | case '3': 187 | cart->chr[0x03] = chunk_data.ptr8; 188 | cart->chr_pages[0x03] = (chunk_hdr.length >> 13); 189 | break; 190 | case '4': 191 | cart->chr[0x04] = chunk_data.ptr8; 192 | cart->chr_pages[0x04] = (chunk_hdr.length >> 13); 193 | break; 194 | case '5': 195 | cart->chr[0x05] = chunk_data.ptr8; 196 | cart->chr_pages[0x05] = (chunk_hdr.length >> 13); 197 | break; 198 | case '6': 199 | cart->chr[0x06] = chunk_data.ptr8; 200 | cart->chr_pages[0x06] = (chunk_hdr.length >> 13); 201 | break; 202 | case '7': 203 | cart->chr[0x07] = chunk_data.ptr8; 204 | cart->chr_pages[0x07] = (chunk_hdr.length >> 13); 205 | break; 206 | case '8': 207 | cart->chr[0x08] = chunk_data.ptr8; 208 | cart->chr_pages[0x08] = (chunk_hdr.length >> 13); 209 | break; 210 | case '9': 211 | cart->chr[0x09] = chunk_data.ptr8; 212 | cart->chr_pages[0x09] = (chunk_hdr.length >> 13); 213 | break; 214 | case 'A': 215 | cart->chr[0x0a] = chunk_data.ptr8; 216 | cart->chr_pages[0x0a] = (chunk_hdr.length >> 13); 217 | break; 218 | case 'B': 219 | cart->chr[0x0b] = chunk_data.ptr8; 220 | cart->chr_pages[0x0b] = (chunk_hdr.length >> 13); 221 | break; 222 | case 'C': 223 | cart->chr[0x0c] = chunk_data.ptr8; 224 | cart->chr_pages[0x0c] = (chunk_hdr.length >> 13); 225 | break; 226 | case 'D': 227 | cart->chr[0x0d] = chunk_data.ptr8; 228 | cart->chr_pages[0x0d] = (chunk_hdr.length >> 13); 229 | break; 230 | case 'E': 231 | cart->chr[0x0e] = chunk_data.ptr8; 232 | cart->chr_pages[0x0e] = (chunk_hdr.length >> 13); 233 | break; 234 | case 'F': 235 | cart->chr[0x0f] = chunk_data.ptr8; 236 | cart->chr_pages[0x0f] = (chunk_hdr.length >> 13); 237 | break; 238 | default: 239 | SAFE_FREE(chunk_data.ptr); 240 | } 241 | } else if(memcmp(chunk_hdr.id, "PCK", 3) == 0) { 242 | switch(chunk_hdr.id[3]) { 243 | case '0': cart->pck[0x00] = *chunk_data.ptr32; break; 244 | case '1': cart->pck[0x01] = *chunk_data.ptr32; break; 245 | case '2': cart->pck[0x02] = *chunk_data.ptr32; break; 246 | case '3': cart->pck[0x03] = *chunk_data.ptr32; break; 247 | case '4': cart->pck[0x04] = *chunk_data.ptr32; break; 248 | case '5': cart->pck[0x05] = *chunk_data.ptr32; break; 249 | case '6': cart->pck[0x06] = *chunk_data.ptr32; break; 250 | case '7': cart->pck[0x07] = *chunk_data.ptr32; break; 251 | case '8': cart->pck[0x08] = *chunk_data.ptr32; break; 252 | case '9': cart->pck[0x09] = *chunk_data.ptr32; break; 253 | case 'A': cart->pck[0x0a] = *chunk_data.ptr32; break; 254 | case 'B': cart->pck[0x0b] = *chunk_data.ptr32; break; 255 | case 'C': cart->pck[0x0c] = *chunk_data.ptr32; break; 256 | case 'D': cart->pck[0x0d] = *chunk_data.ptr32; break; 257 | case 'E': cart->pck[0x0e] = *chunk_data.ptr32; break; 258 | case 'F': cart->pck[0x0f] = *chunk_data.ptr32; break; 259 | default: 260 | break; 261 | } 262 | SAFE_FREE(chunk_data.ptr); 263 | } else if(memcmp(chunk_hdr.id, "CCK", 3) == 0) { 264 | switch(chunk_hdr.id[3]) { 265 | case '0': cart->cck[0x00] = *chunk_data.ptr32; break; 266 | case '1': cart->cck[0x01] = *chunk_data.ptr32; break; 267 | case '2': cart->cck[0x02] = *chunk_data.ptr32; break; 268 | case '3': cart->cck[0x03] = *chunk_data.ptr32; break; 269 | case '4': cart->cck[0x04] = *chunk_data.ptr32; break; 270 | case '5': cart->cck[0x05] = *chunk_data.ptr32; break; 271 | case '6': cart->cck[0x06] = *chunk_data.ptr32; break; 272 | case '7': cart->cck[0x07] = *chunk_data.ptr32; break; 273 | case '8': cart->cck[0x08] = *chunk_data.ptr32; break; 274 | case '9': cart->cck[0x09] = *chunk_data.ptr32; break; 275 | case 'A': cart->cck[0x0a] = *chunk_data.ptr32; break; 276 | case 'B': cart->cck[0x0b] = *chunk_data.ptr32; break; 277 | case 'C': cart->cck[0x0c] = *chunk_data.ptr32; break; 278 | case 'D': cart->cck[0x0d] = *chunk_data.ptr32; break; 279 | case 'E': cart->cck[0x0e] = *chunk_data.ptr32; break; 280 | case 'F': cart->cck[0x0f] = *chunk_data.ptr32; break; 281 | default: 282 | break; 283 | } 284 | SAFE_FREE(chunk_data.ptr); 285 | } else { 286 | /* since we aren't storing this pointer, free it */ 287 | SAFE_FREE(chunk_data.ptr); 288 | } 289 | 290 | } else { 291 | fprintf(stderr, "%s\n", get_error_string_UNIF(ret_val)); 292 | break; 293 | } 294 | } 295 | 296 | close_UNIF(unif_file); 297 | } 298 | 299 | return UNIF_OK; 300 | } 301 | 302 | /*----------------------------------------------------------------------------- 303 | // name: free_file_UNIF(unif_cart_t *cart) 304 | //---------------------------------------------------------------------------*/ 305 | UNIF_RETURN_CODE free_file_UNIF(unif_cart_t *cart) { 306 | size_t i; 307 | 308 | assert(cart != 0); 309 | 310 | SAFE_FREE(cart->mapr_name); 311 | SAFE_FREE(cart->dumper_info); 312 | SAFE_FREE(cart->read_text); 313 | SAFE_FREE(cart->name); 314 | 315 | SAFE_FREE(cart->batr_byte); 316 | SAFE_FREE(cart->ctrl_byte); 317 | SAFE_FREE(cart->mirr_data); 318 | SAFE_FREE(cart->tvci_byte); 319 | SAFE_FREE(cart->vror_byte); 320 | 321 | for(i = 0; i < 0x10; i++) { 322 | SAFE_FREE(cart->prg[i]); 323 | SAFE_FREE(cart->chr[i]); 324 | } 325 | 326 | return UNIF_OK; 327 | } 328 | 329 | -------------------------------------------------------------------------------- /load_unif.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef LOAD_UNIF_20080314_H_ 20 | #define LOAD_UNIF_20080314_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | #include "lib_unif.h" 27 | 28 | typedef struct { 29 | uint32_t pck[0x10]; 30 | uint32_t cck[0x10]; 31 | uint8_t *prg[0x10]; 32 | uint8_t *chr[0x10]; 33 | uint32_t prg_pages[0x10]; 34 | uint32_t chr_pages[0x10]; 35 | unif_header_t header; 36 | dumper_info_t *dumper_info; 37 | char *mapr_name; 38 | char *read_text; 39 | char *name; 40 | uint8_t *tvci_byte; 41 | uint8_t *ctrl_byte; 42 | uint8_t *batr_byte; 43 | uint8_t *vror_byte; 44 | uint8_t *mirr_data; 45 | } unif_cart_t; 46 | 47 | /* some example implementations for loading and freeing a UNIF file */ 48 | UNIF_RETURN_CODE load_file_UNIF(const char *filename, unif_cart_t *cart); 49 | UNIF_RETURN_CODE free_file_UNIF(unif_cart_t *cart); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | 57 | 58 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "ines_convert.h" 20 | #include "load_unif.h" 21 | 22 | #include 23 | 24 | /*----------------------------------------------------------------------------- 25 | // Name: main(int argc, char *argv[] ) 26 | //---------------------------------------------------------------------------*/ 27 | int main(int argc, char *argv[]) { 28 | 29 | unif_cart_t unif; 30 | ines_info_t ines; 31 | 32 | const char *source; 33 | const char *dest; 34 | 35 | UNIF_RETURN_CODE r; 36 | 37 | if(argc != 3) { 38 | fprintf(stderr, "usage: lib_unif \n"); 39 | return -1; 40 | } 41 | 42 | source = argv[1]; 43 | dest = argv[2]; 44 | 45 | make_unif_file_from_nes(dest, source); 46 | 47 | r = load_file_UNIF(dest, &unif); 48 | 49 | /* test loading of the file */ 50 | if(r != UNIF_OK) { 51 | fprintf(stderr, "error loading UNIF file %s\n", dest); 52 | fprintf(stderr, "%s\n", get_error_string_UNIF(r)); 53 | return -1; 54 | } 55 | 56 | /* test getting info */ 57 | get_ines_mapper(unif.mapr_name, &ines); 58 | free_file_UNIF(&unif); 59 | 60 | return 0; 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /std_func.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "std_func.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | /*----------------------------------------------------------------------------- 27 | // Name: ask_question_yn 28 | // Desc: presents the user with a yes or no question and waits for a 'y' or 'n' 29 | // Note: treats no input as 'n' 30 | //---------------------------------------------------------------------------*/ 31 | int ask_question_yn(const char *query) { 32 | 33 | char buffer[256]; 34 | 35 | assert(query != 0); 36 | 37 | do { 38 | /* print the question */ 39 | printf("%s", query); 40 | 41 | /* get the answer */ 42 | if(fgets(buffer, sizeof(buffer), stdin) == 0) { 43 | return 0; 44 | } 45 | 46 | buffer[0] = tolower(buffer[0]); 47 | 48 | /* we only can possibly read one character at a time, so only 49 | * need to check the first */ 50 | if(buffer[0] == '\n') { 51 | return 0; 52 | } 53 | 54 | } while((buffer[0] != 'y' && buffer[0] != 'n') || (buffer[1] != '\n' && buffer[1] != '\0')); 55 | 56 | return buffer[0] == 'y'; 57 | } 58 | 59 | /*----------------------------------------------------------------------------- 60 | // Name: display_menu 61 | // Note: returns (unsigned int)-1 on error 62 | //---------------------------------------------------------------------------*/ 63 | unsigned int display_menu(unsigned int n, const char *prompt, ...) { 64 | 65 | unsigned int user_selection; 66 | char buffer[256]; 67 | 68 | assert(prompt != 0); 69 | 70 | do { 71 | va_list var_arg; 72 | unsigned int count; 73 | 74 | /* print the menu */ 75 | va_start(var_arg, prompt); 76 | 77 | printf("%s\n", prompt); 78 | 79 | for(count = 0; count < n; ++count) { 80 | printf("\t%u - %s\n", count, va_arg(var_arg, const char *)); 81 | } 82 | 83 | va_end(var_arg); 84 | 85 | if(fgets(buffer, sizeof(buffer), stdin) == 0) { 86 | return (unsigned int)-1; 87 | } 88 | 89 | /* read the user selection */ 90 | if(sscanf(buffer, "%255u", &user_selection) == EOF) { 91 | continue; 92 | } 93 | } while(user_selection >= n); 94 | 95 | return user_selection; 96 | } 97 | 98 | -------------------------------------------------------------------------------- /std_func.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef STD_FUNC_20080314_H_ 20 | #define STD_FUNC_20080314_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | /* some general purpose functions to trim code */ 27 | unsigned int display_menu(unsigned int n, const char *prompt, ...); 28 | int ask_question_yn(const char *query); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /unif_crc32.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "unif_crc32.h" 20 | 21 | /* this table generated for poly = $edb88320 */ 22 | static const uint32_t crc_table[256] = { 23 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 24 | 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 25 | 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 26 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 27 | 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 28 | 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 29 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 30 | 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 31 | 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 32 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 33 | 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 34 | 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 35 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 36 | 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 37 | 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 38 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 39 | 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 40 | 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 41 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 42 | 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 43 | 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 44 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 45 | 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 46 | 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 47 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 48 | 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 49 | 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 50 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 51 | 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 52 | 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 53 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 54 | 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 55 | 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 56 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 57 | 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 58 | 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 59 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 60 | 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 61 | 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 62 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 63 | 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 64 | 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 65 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 66 | 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 67 | 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 68 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 69 | 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 70 | 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 71 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 72 | 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 73 | 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 74 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 75 | 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 76 | 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 77 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 78 | 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 79 | 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 80 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 81 | 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 82 | 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 83 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 84 | 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 85 | 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 86 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 87 | }; 88 | 89 | /*------------------------------------------------------------------------------ 90 | // Name: unif_crc32 91 | //----------------------------------------------------------------------------*/ 92 | uint32_t unif_crc32(const void *data, uint32_t length, uint32_t initial_value) { 93 | 94 | const uint8_t *ptr = data; 95 | 96 | /* start out with all bits set */ 97 | uint32_t crc = ~initial_value; 98 | 99 | if(ptr != 0) { 100 | while(length-- != 0) { 101 | /* accumulate crc */ 102 | crc = (crc >> 8) ^ crc_table[(crc & 0x000000ff) ^ *ptr++]; 103 | } 104 | } 105 | 106 | /* invert all bits, and we're done */ 107 | return ~crc; 108 | } 109 | -------------------------------------------------------------------------------- /unif_crc32.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef UNIF_CRC32_20080314_H_ 20 | #define UNIF_CRC32_20080314_H_ 21 | 22 | #include "unif_types.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | uint32_t unif_crc32(const void *data, uint32_t length, uint32_t initial_value); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /unif_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2000 - 2011 Evan Teran 3 | eteran@alum.rit.edu 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef UNIF_TYPES_20080314_H_ 20 | #define UNIF_TYPES_20080314_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | #if defined(_WIN32) || defined(_WIN64) 27 | 28 | #if defined(_MSC_VER) && _MSC_VER >= 1600 29 | #include 30 | #else 31 | typedef unsigned __int8 uint8_t; 32 | typedef unsigned __int16 uint16_t; 33 | typedef unsigned __int32 uint32_t; 34 | typedef unsigned __int64 uint64_t; 35 | 36 | typedef __int8 int8_t; 37 | typedef __int16 int16_t; 38 | typedef __int32 int32_t; 39 | typedef __int64 int64_t; 40 | #endif 41 | #elif defined (__HAIKU__) 42 | #include 43 | #elif defined (__APPLE__) && defined (__MACH__) 44 | #include 45 | #elif defined (__linux__) || defined(__linux) || defined(__gnu_linux__) 46 | #include 47 | #elif defined(SunOS) 48 | #include 49 | #endif 50 | 51 | /* enum for return info */ 52 | typedef enum { 53 | UNIF_OK, 54 | UNIF_END_OF_FILE, 55 | UNIF_BAD_HEADER, 56 | UNIF_BAD_REVISION_NUMBER, 57 | UNIF_DIRTY_HEADER, 58 | UNIF_OPEN_FAILED, 59 | UNIF_CLOSE_FAILED, 60 | UNIF_READ_FAILED, 61 | UNIF_WRITE_FAILED, 62 | UNIF_OUT_OF_MEMORY, 63 | UNIF_INPUT_FAIL, 64 | UNIF_LENGTH_ERROR 65 | } UNIF_RETURN_CODE; 66 | 67 | /* enum for open type */ 68 | typedef enum { 69 | UNIF_OPEN_READ, 70 | UNIF_OPEN_WRITE 71 | } UNIF_OPEN_MODE; 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif 78 | 79 | --------------------------------------------------------------------------------