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 |
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.
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 (...);
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.
typedef struct { unsigned long id; unsigned long length; void *data; } st_unif_chunk_t;
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};
unsigned char buf[SIZE_INFO], number[80]; // 4 should be enough, but don't // be too sensitive to errorsLong 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; ...
#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"
#ifndef SWC_H #define SWC_H ... #endif // SWC_HHeader 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.