Q1: Who develops uCON64?

Q2: How can I take part?

Q3: How do I get the source of uCON64, using CVS as an anonymous user?

Q4: How do I connect to the CVS repository as developer with read/write access?

Q5: How do I create a patch from the CVS repository?

Q6: How is the source of uCON64 organized?

Q7: What coding style is preferred?


Q1: Who develops uCON64?
A: Written/modified by:
1999 - 2002 NoisyB (Dirk) noisyb@gmx.net
2001 - 2002 dbjh

Uses code (or at least ideas) from:

Chicken & chp ronaldm@netcom.com (chp) original uCON
Silo / BlackBag APS patcher
madman IPS patcher
The White Knight / ATX BSL patcher
Icarus / Paradox PPF patcher
WyrmCorp http://wyrmcorp.com GameGenie "codec"
Marat Fayzullin fms@cs.umd.edu
http://www.komkon.org/fms/
some Famicom Disk System routines and NESLIST
Andreas Sterbenz stan@sbox.tu-graz.ac.at d64 transfer
Kami m-kami@da2.so-net.ne.jp
http://www.playoffline.com
NES emulator for GameBoy
Gilligan / DC-S show info for Neogeo Pocket
LaC N64 makesram
Jeff Frohwein info@devrs.com
http://www.devrs.com
Flash Advance Linker transfer
Omar Kilani gbautil@aurore.net GameBoy Advance SRAM routine
Caz turok2@currantbun.com
http://www.infernal.currantbun.com
I/O port driver for BeOS, SWC help and Super UFO SRAM header format
Cowering hotemu@hotmail.com BS (Broadcast Satellaview) ROM detection and BS checksum
Jerremy Koot jkoot@snes9x.com
http://www.snes9x.com
interleave detection and deinterleave code (SNES)
Gary Henderson gary@snes9x.com
http://www.snes9x.com
interleave detection and deinterleave code (SNES)
John Weidman jweidman@sonic.net Game Doctor ROM file support (SNES) and new BS detection
Evan Teran emt3734@ritvax.isc.rit.edu lib_unif (NES)
JohnDie Super Pro Fighter header format (SNES)
NSRT authors joecool22us@yahoo.com
http://www.geocities.com/joecool22us/nsrt.htm
checksum algorithm for Momotaro Dentetsu Happy of NSRT, the BASIC SNES ROM tool (BASIC also as in S-t-n's own foul language ;-) ) , their SNES add-on chip information page and some other info
Gilles Vollant info@winimage.com unzip.c & unzip.h


and others...

Q2: How can I take part?
A: Install CVS and checkout the latest version from http://ucon64.sourceforge.net. Then make your changes, email noisyb@gmx.net and you will be named in this file and in the sources of course. Just the typical way of open source development.

Q3: How do I get the source of uCON64, using CVS as an anonymous user?
A: For read-only access you must have CVS installed. If you have never logged in on the CVS server you will first have to do that. You only have to login once. So, if you have already logged in before you can skip this step.
To login, type:

cvs -d:pserver:anonymous@cvs.ucon64.sourceforge.net:/cvsroot/ucon64 login

Then CVS will ask you for a password. Since you are logged in as anonymous you do not have a password, so just type <enter> at the password prompt.
To download the uCON64 source, type:

cvs -d:pserver:anonymous@cvs.ucon64.sourceforge.net:/cvsroot/ucon64 checkout -PR ucon64

The uCON64 source will then be downloaded to the directory ./ucon64. You can speed up the download by using the option -z with a compression level parameter.
If you want to get up to date with the newest source code later, type:

cvs update -PRd

Q4: How do I connect to the CVS repository as developer with read/write access?
A: For read/write access you must have CVS and SSH installed and set the environment variable CVS_RSH=ssh.
To download the source code, type:

cvs -d:ext:<name>@cvs.ucon64.sourceforge.net:/cvsroot/ucon64 checkout -PR ucon64
<enter password at prompt>

Now all files will be downloaded. Afterwards you can simply cd into the top level directory and continue by just typing:

cvs update -PRd
cvs commit -R
cvs add <file>
cvs remove -f <file>

You don't need to specify -d:ext:<name>@cvs.ucon64.sourceforge.net:/cvsroot/ucon64 anymore, because that information is stored in the CVS directories then.
If you use the update command in combination with (-)d, never forget to also use the option -P or you will get a lot of crap.

Q5: How do I create a patch from the CVS repository?
A: As developer:
cvs -d:ext:<name>@cvs.ucon64.sourceforge.net:/cvsroot/ucon64 diff -u >mychanges.patch
<enter password at prompt>

As anonymous:
cvs -d:pserver:anonymous@cvs.ucon64.sourceforge.net:/cvsroot/ucon64 login
<just press enter at password prompt>
cvs -d:pserver:anonymous@cvs.ucon64.sourceforge.net:/cvsroot/ucon64 diff -u >mychanges.patch

Q6: How is the source of uCON64 organized?
A: The heart of uCON64 is ucon64.c/main()/rom. This struct is designed to hold all information you could get from a ROM.
uCON64 starts with the name of a ROM and possibly some arguments. Then it checks if a configuration file exists and creates one if that is not the case. uCON64 uses the configuration file to set some members of another important structure, ucon64.c/ucon64. For example the value of ucon64.parport, the variable that contains the I/O address of the parallel port, will initially be set to the value that is found in the configuration file.
Then it scans the command line for switches. Switches are command line arguments that will not result in an action by themselves, but they influence the other type of command line arguments, options. uCON64 initializes ucon64.c/ucon64, based on the switches. This code can be found in switches.c. This is also the place where ucon64.show_nfo is set. This variable determines whether or not uCON64 displays ROM information.
Then uCON64 calls ucon64.c/ucon64_init() which calls ucon64.c/ucon64_console_probe(). The latter calls the init function for all the supported console types if the user didn't use a force console switch. For example the init function for SNES is console/snes.c/snes_init(), for NES console/nes.c/nes_init(). Each init function tries to determine if the ROM file belongs to its console type. If that is the case it returns 0, otherwise -1.
Some ROM file types contain information such as the internal name, country and creator of the game that can be used to fill ucon64.c/main()/rom. SNES ROM files are an example of this type of file. For other ROM file types this information is not present inside the ROM file. NES ROMs are an example of that type. In that case uCON64 uses a large database in db.h to make it possible to display the country, creator and full name of the game. ucon64.c/ucon64_init() calls the function ucon64_db.c/ucon64_dbsearch() that uses the CRC32 of the ROM file data to find the required information in the database. If the information could be found ucon64_db.c/ucon64_dbsearch() fills ucon64.c/main()/rom with it.
After that if ucon64.show_nfo has the value UCON64_YES uCON64 will call ucon64.c/ucon64_nfo() which displays the values and strings of ucon64.c/main()/rom. For some options it doesn't make sense to display ROM info. If one of those options has been specified on the command line ucon64.show_nfo will be set to UCON64_NO.
Then uCON64 starts scanning the command line for options. This code can be found in options.c. From this code almost all operations of uCON64 are executed. Under Unix this is also the point where root privileges are given up with a call to misc.c/drop_privileges().

Q7: What coding style is preferred?
A:

Keywords
Always put a space after a keyword. That includes the keyword sizeof.

Indentation
Two spaces instead of a real tab. The curly braces of functions should not be indented.
If an if statement has an else part, that part should be aligned with the if part. For a do-while compound statement, do and while should also be aligned.
If else is immediately followed by an if statement, the if keyword together with the condition statement should be put on the same line as the else keyword. Example:

   if (...)
     {
       ...
     }
   else if (...)
     {
       ...
     }
   else
     {
       ...
     }
Note that this doesn't apply to the case where else is followed by a curly brace.

New lines
The statement(s) for if, while and for should always start on a new line. That also applies to one-line statements.

Compound statements
The curly braces should be indented and the code of the compound statement should be indented again. The only exception is the switch statement. The labels inside a switch statement should be aligned with the curly braces. Example:
   int
   function (int value)
   {
     if (value < 0)
       {
         printf ("Invalid argument: %d\n", value);
         exit (1);
       }
     switch (value)
       {
       case 0:
       case 1:
       case 2:                                     // falling through
         puts ("lesser than or equal to 2\n");
       case 3:
       case 4:
         puts ("lesser than or equal to 4\n");
         break;
       default:
         puts ("greater than 4\n");
         break;
       }

     return 0;
   }
A do-while compound statement should have this layout:
   do
     {
       ...
     }
   while (...);

Functions
Function calls should contain one space after the name of the function. Every parameter of the function should be separated from a previous one with a space after the comma.
For a function implementation the return type should be specified on its own line. This doesn't apply to function prototypes. If a function needn't be known at global scope it should be declared or defined as static. Function implementations should be separated from each other by two new lines.

Variables
Variables of the same type should be defined in one group. Example:
   int x, y = 0, z;
   char str1[] = "xyz", *str2;
Variables that need to be known at file scope but not at global scope should be defined as static. Variables that do need to be known at global scope should be defined in a source file, not in a header file. The header file should contain an extern statement for the variable.

Types (structs)
A struct tag of a struct should have the prefix "st_". A new type based on a struct should have the same prefix and the suffix "_t". Example:
 typedef struct
 {
   unsigned long id;
   unsigned long length;
   void *data;
 } st_unif_chunk_t;

Line length
The length of lines shouldn't be much longer than 90 characters. This doesn't necessarily include the length of comment. Longer lines should be broken into several shorter ones. Example:
   static const int unif_prg_ids[] = {PRG0_ID, PRG1_ID, PRG2_ID, PRG3_ID,
                                      PRG4_ID, PRG5_ID, PRG6_ID, PRG7_ID,
                                      PRG8_ID, PRG9_ID, PRGA_ID, PRGB_ID,
                                      PRGC_ID, PRGD_ID, PRGE_ID, PRGF_ID};

Comment
Single or two-line comments should use //. Comments that need more lines should use the pair /* and */. A two-line comment should signify that it is one two-line comment instead of two one-line comments by putting one extra space after the //. Single or two-line comments should start at column 49 if that's possible. Example:
   unsigned char buf[SIZE_INFO], number[80];     // 4 should be enough, but don't
                                                 //  be too sensitive to errors
Long comments should use the same indentation as the code that follows it:
  if (deinterleave)
    /*
      This is a bit of a hack, i.e., putting the following code in this
      ...
    */
    {
      unsigned char *data;
      int size, n = 0, prg = 0, chr = 0;
      ...

Preprocessor directives
Preprocessor directives should not be indented. This does not only apply to #include, but to all preprocessor directives.
For #if and #ifdef blocks that are complex or enclose many lines of code the corresponding #else, #elif or #endif should contain a comment that signifies to which #if or #ifdef it belongs. Example:
   #ifdef  __unix__                                // wait 32 milliseconds
     usleep (32000);
     ...
   #elif   defined __MSDOS__                       // __unix__
     delay (32);
     ...
   #elif   defined __BEOS__                        // __MSDOS__
     snooze (32000);
     ...
   #endif                                          // __BEOS__
Standard system header files should be included by specifying the name of the header file between angle brackets. Non-standard header files should be included with the name between double quotes. Example:
   #include <stdio.h>
   #ifdef  __unix__
   #include <unistd.h>
   #endif
   #include "ucon64.h"

Header files
Header files should be protected against being included multiple times by putting the entire file inside an #ifndef block. Define the constant for which the #ifndef checks inside the #ifndef block. For example, for the file swc.h:
   #ifndef SWC_H
   #define SWC_H
   ...
   #endif // SWC_H
Header files should only contain information about their corresponding source file that may be needed by other source files. They should not include information about variables or function definitions that are used only inside the source file.

Portability
Platform-specific function calls, variable types and #includes of header files should be put inside #ifdef or #if blocks. For an example see the first code example in the section Preprocessor directives.