               ____      _   _   _               _   _      _
              / ___| ___| |_| |_(_)_ __   __ _  | | | | ___| |_ __
             | |  _ / _ \ __| __| | '_ \ / _` | | |_| |/ _ \ | '_ \
             | |_| |  __/ |_| |_| | | | | (_| | |  _  |  __/ | |_) |
              \____|\___|\__|\__|_|_| |_|\__, | |_| |_|\___|_| .__/
                                         |___/               |_|



======================================
============ Introduction ============
======================================

   When things go wrong, it often seems like a good idea to ask other people 
   for help. Fortunately for people in this situation, there are many people 
   (both Allegro developers and users) who are happy to spend their time 
   answering support questions of this type, but there are various things 
   you can do to make this process work more efficiently. This document 
   describes some steps to take whenever you have a problem with an Allegro 
   program, suggesting ways that you can try to solve it yourself, and also 
   giving some tips about when/how to ask for help. Following these 
   guidelines will make life easier both for the helper (because all the 
   relevant information will be presented to them in a concise and useful 
   way), and for the helpee (because they are more likely to get a prompt 
   and accurate reply).



======================================================
============ Part 1 - who is the culprit? ============
======================================================

   Is the problem a bug in Allegro, or in your code? To find out, try 
   running the Allegro test programs, in particular the test.exe (for 
   graphics related problems), the play.exe (for soundcard troubles), and 
   the entire contents of the examples directory (for anything that is going 
   wrong). If you can't reproduce the problem with any of these, it is 
   probably your fault, in which case you should skip to part 3 below. 

   If the problem is related to DOS graphics modes, you should start by 
   getting a copy of Display Doctor from http://www.scitechsoft.com/.
   If this fixes the trouble, it almost certainly means that your original 
   VESA driver was broken in some way. I'm not interested in hearing reports 
   about problems of this type: there is nothing I can do to fix them, so 
   I'm afraid your only option is to get a better VESA driver, either by 
   hassling the manufacturer to fix their bugs, buying Display Doctor, or 
   writing a FreeBE/AF driver for your card (see 
   http://www.talula.demon.co.uk/freebe/).



===========================================================
============ Part 2 - when Allegro is at fault ============
===========================================================

   If you still think the problem lies with Allegro, post a system report 
   containing a description of the problem, what platform and library 
   version you are using, your hardware specs, and a list of exactly which 
   programs you were able to reproduce the problem with (it is important to 
   know not only what programs had trouble, but also which ones worked 
   correctly, if any).

   If the problem is related to DOS graphics modes, you should also post the 
   output from running the afinfo and vesainfo programs (the short version 
   is enough unless you are explicitly asked to add the -v switch: all that 
   extra data isn't usually needed). Try running the test.exe program with 
   various Allegro drivers (any native drivers that you think might work 
   with your card, VESA 2.0, and the VESA 1.x driver), and in various video 
   modes, and report exactly what modes and color depths cause problems. If 
   you are able to use any SVGA resolutions at all, run test.exe with the 
   Autodetect option and report the entire text that it displays in the 
   middle of the screen.

   If the problem is related to the DOS sound system, try using the setup 
   program to manually configure your card. You may need to manually enter 
   the hardware parameters, and if it is an SB clone card, try selecting 
   some earlier breed of SB card than whatever it is autodetecting (SB Pro, 
   SB 2.0, or SB 1.0). If you are still unable to get anything working, your 
   post should include the name and descriptions of whatever digital and 
   MIDI sound drivers are being autodetected (this information is displayed 
   by the play.exe program).



============================================================
============ Part 3 - when your program crashes ============
============================================================

   When a djgpp program crashes, you will usually get a stack traceback 
   looking something like:

      Exiting due to signal SIGSEGV
      General Protection Fault at eip=00001eca
      [snip]

      Call frame traceback EIPs:
        0x00001eca
        0x00001590
        0x00001aea

   This information tells you exactly where the crash occurred. To make 
   sense of it, you should compile your program with debugging information 
   (using the -g switch), and then run "symify program.exe" while this 
   traceback is displayed onscreen. That will change the traceback to 
   something along the lines of:

      Call frame traceback EIPs:
        0x00001eca   _strcpy+14
        0x00001590   _main+56, line 7 of t.c
        0x00001aea   ___crt1_startup+138

   In this case, you can see that the crash occurred in the strcpy() 
   function, which was called at line 7 of the main() function in the t.c 
   source file. Now you just have to go to that line, have a look at 
   whatever you are doing there, and change it to be correct :-)

   Note: if the crash happens deep inside an Allegro function, this 
   traceback may not be so useful. When this happens you can recompile 
   Allegro with debugging information (see the readme file), and then 
   link your program with the debugging library version.

   Note 2: even when this crash traceback points to one of the Allegro 
   functions, that does not necessarily mean the Allegro routine is at 
   fault. Anything will crash if you pass it invalid parameters, so unless 
   you can duplicate the problem in one of the Allegro example programs, you 
   should start out by assuming that it is a case of operator error and 
   double-check exactly what you are passing to the Allegro function.

   When your Allegro compiled Linux/Unix program crashes, you will usually
   get a not very meaningful message along with a core dump:

      Shutting down Allegro due to signal #11
      Segment violation (core dumped)

   Look at your filesystem: there should be a file named core or something
   similar with information telling you exactly where the crash occurred.
   If there is no core, check your environment settings, under bash this is
   done with the 'ulimit -a' command. Usually 'ulimit -c unlimited'
   somewhere in your login scripts should work fine.

   Just like with djgpp, to make sense of the core, you should compile your
   program with debugging information (using the -g switch), and then run
   the GNU debugger on it "gdb binary core". That will load the debugger,
   print some information about linked binaries and leave you at a prompt.
   Now you can get the full backtrace:

      (gdb) backtrace
      #0  0x08065237 in utf8_getx (s=0xbffffc5c) at ./src/unicode.c:347
      #1  0x0806953f in ustrzcpy (dest=0x0, size=2147483646, src=0x0) at ./src/unicode.c:1770
      #2  0x08057575 in _mangled_main () at t.c:9
      #3  0x0806c9bf in main (argc=1, argv=0xbffffd14) at ./src/unix/umain.c:39
      #4  0x4015414f in __libc_start_main () from /lib/libc.so.6

   In this case, you can see that the crash occurred in the ustrzcpy()
   function, which was called at line 9 of the main() function in the t.c
   source file. Now you just have to go to that line, have a look at 
   whatever you are doing there, and change it to be correct :-)

   Note that the crash happened deep inside an Allegro function, which is
   also revealed by the traceback. However, the binary was linked against a
   static debug version of Allegro, we wouldn't have had so much luck with
   a non debug or dynamically linked version.

   Since gdb is an interactive debugger, you could also select a frame and
   check out the values of the variables, to see better who is the culprit:

      (gdb) frame 2
      #2  0x08057575 in _mangled_main () at t.c:9
      9          ustrcpy(p1, p2);
      (gdb) list
      4
      5       int main(void)
      6       {
      7          char *p1 = 0, *p2 = 0;
      8          allegro_init();
      9          ustrcpy(p1, p2);
      10         return 0;
      11      }
      12      END_OF_MAIN()
      (gdb) print p1
      $1 = 0x0
      (gdb) print p2
      $2 = 0x0

   Yuck! Playing with NULL values doesn't really pay off. Ok, while this was
   a slightly out-of-the-can example, you surely get the point. Remember to
   check out GDB's manual to learn about more useful commands and/or how to
   debug your program while it's running and many other things.



======================================================================
============ Part 4 - things people don't do (but should) ============
======================================================================

   One of the most common errors made by programmers is to neglect to check 
   the return value from a function that may fail. Such an error will often 
   lead to unexpected and downright unusual errors, making for a debugging 
   nightmare. There are many functions in and out of Allegro that may or may 
   not work depending on varying circumstances. They are, however, nice 
   enough to let you know whether or not they were successful through 
   documented return values.

   Whenever you call a function that might fail (most importantly 
   set_gfx_mode(), install_sound(), and anything that loads data from the 
   disk), it is _essential_ that you check the return code from this, and 
   respond accordingly.

   Another commonly forgotten but important tool is to use whatever option 
   enables strict warnings for your compiler (gcc uses -Wall), when 
   compiling your code. Any warnings reported by this option will almost 
   certainly represent errors in your program, and should be fixed before 
   doing anything else. When using gcc, a useful trick is to compile with 
   the -O setting as well, because this causes gcc to examine the program's 
   actions in more detail, enabling more useful warnings. You should 
   normally disable optimisation while debugging, though. Although it gives 
   better compile time warnings, it is likely to upset any debugging tools 
   that you later try to use.



==================================================
============ Part 5 - asking for help ============
==================================================

   Ok, so you've tried everything described above, and your program still 
   doesn't work. You have no idea what to do next, so it is time to cast 
   yourself unto the mercies of the net, in hopes of finding some kind of 
   wise man, seer, or oracle that holds an answer for your question...

   The best place to ask is the Allegro mailing list: see readme.txt for 
   details. Please remember that this is an Allegro-specific list, though. 
   Problems relating to the C language or djgpp compiler belong in other 
   forums (comp.lang.c and comp.os.msdos.djgpp respectively).

   Both the Allegro and djgpp mailing lists are archived, and can be 
   searched via their respective homepages. It is very likely that you will 
   be able to find a solution to your problem by looking through the answers 
   to past questions, which will save you needing to post a query at all.

   In accordance with proper netiquette, it is assumed that when you post to 
   any forum on the Internet you have at least consulted the relevant 
   documentation first, if not read it in its entirety. If the problem you 
   are having is worth asking hundreds of people the answer for, then it is 
   certainly worth taking a few minutes to try to solve the problem 
   yourself. Allegro is extensively and painstakingly documented and it is 
   considered a prerequisite to posting that you have not only read the 
   text, but examined the example programs as well.



=========================================================
============ Part 6 - learn from my mistakes ============
=========================================================

   What not to do, Part One:

      "My program crashes. Please tell me why."

   Yes, people really do sometimes send me questions like this :-) Despite 
   years of practice I am still totally unable to read minds, so this is a 
   very pointless thing to ask. In order to get help with a problem you must 
   describe it in enough detail that other people will be able to understand 
   and reproduce it: this usually means posting some of your source code.


   What not to do, Part Two:

      "I've got a problem with my program. I'm attaching a 500k zip file 
      containing ten thousand lines of source code and all the graphics and 
      sound data: can you please debug it and tell me what the trouble is?"

   After wasting the time and phone bills to download such a huge file, it 
   is unlikely that anyone will even _want_ to help you, let alone invest 
   the amount of time it would take to read and understand such a huge mess 
   of information. You must try to isolate a smaller chunk of code that 
   demonstrates the trouble: the smaller you can make it, the more chance 
   that someone will be able to help you with it. Remember that you are 
   asking other people to do you a favour, so it is your responsibility to 
   make this process as easy for them as you possibly can.



====================================================
============ Part 7 - wording your plea ============
====================================================

   The most important thing is to include code that can be compiled and 
   tested by the person reading your message. Don't just post your entire 
   program: try to extract a small section that includes the specific lines 
   causing your problem, or reproduces the trouble in a simpler way (you 
   will often find that you can locate the error yourself in the process of 
   making this simpler version, so it is a good exercise in itself). This 
   code should be a small but complete program that can actually be compiled 
   and run, because it is very hard to debug incomplete code fragments.

   It is best to include the code directly in the text of your email 
   message, because it is easier for people to read this than if they have 
   to extract it from an attachment.

   Ideally your example should avoid using any external graphics and data 
   files. It is ok to include a small (max 2k) zip containing such 
   information, or failing that a description of what other files it needs 
   (eg. "put a 32x32 .pcx file called 'tile.pcx' into the same directory as 
   the program). If there is no way that you can simplify things this far, 
   you should upload the program and data to a website and then just post 
   that URL in your message.

   You should say what gcc command line you used to build the program, and 
   this should include the -Wall switch.

   Describe what you intended this program to do (it may not be instantly 
   obvious to other people), and also what it really does when you run it. 
   There is usually no need to post the actual crash traceback (other people 
   can duplicate this for themselves as long as they are able to compile and 
   run your code), but you should say whether you do get such a traceback, 
   or a lockup, or just incorrect results (and if so, in exactly what way 
   they differ from what you were expecting). It is useful to mark your 
   source with a comment to show what line the crash traceback points to.

   Any other information that you can include may also be useful. Most 
   importantly a brief machine description, information about any relevant 
   drivers, and your Allegro version (please don't just say "WIP", but give 
   the exact date if you are using anything other than an official numbered 
   release), 



========================================================
============ Part 8 - a model of perfection ============
========================================================

   For reference, here is an example of what I would consider to be an ideal 
   problem report:


   I'm having some trouble using the hicolor video modes in my program, 
   although they work fine with the Allegro tests. I'm using Allegro 3.0 
   with djgpp 2.02 (gcc version 2.8.1) on a p166, running under win95 and 
   using the builtin VESA 2.0 driver, which the vesainfo program describes 
   as "Matrox Graphics Inc.".

   This program is supposed to select a 640x480 16 bit resolution, draw a 
   blue rectangle near the top left corner of the screen, and then wait for 
   a keypress before quitting, but I just get a General Protection Fault 
   when I run it.

   I compile it using "gcc -Wall t.c -o t.exe -lalleg", and don't get any 
   warnings.


   --- cut here, t.c ---

   #include <stdio.h>
   #include <allegro.h>

   void main()
   {
      BITMAP *bmp = screen;

      install_keyboard();

      if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) {
         printf("Error setting video mode\n");
         return;
      }

      set_color_depth(16);

      /* crashes during this rectangle call! */
      rectfill(bmp, 32, 32, 64, 64, 0x001F);

      readkey();
   }


