Re: [AD] WIP time?

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


In reply to Peter Wang <tjaden@xxxxxxxxxx>:
>There are a couple of relatively simple things to do first, I think.
[snip MIDI]

>- load_bitmap constructor problem.

OK, I fixed this by adding support for destructor functions. These can
probably be used elsewhere within Allegro. Now, if constructors and
destructors are supported, the bitmap reader will initialise itself when
the library is actually loaded, and deinitialise when the library is
closed, irrespective of when allegro_init() and allegro_exit() are
called. A call to allegro_exit() will trim the list to Allegro-supplied
functions, however.

Some things to note:
1/. I'm not sure that the preprocessor directives I used are ANSI or 
    just a gcc thing (since I have only ever used gcc). Could somebody
    please confirm?

2/. In alconfig.h, I assumed that if `ALLEGRO_USE_CONSTRUCTOR' was  
    defined, that I could also define `DESTRUCTOR_FUNCTION'. This could
    be more specific, but I don't think it needs to be.

3/. Constructors weren't actually supported on anything other than 
    systems using autoconf. I changed al_config.h to enable them if
    __GNUC__ was defined. We could refine this, by checking for a
    version number, or possibly move it to a different header file.
    What does everyone think about this? (Also, support for this
    on other compilers would be good).

? docs/allegro.rtf
? examples/exfixed.upx
? lib/djgpp/staaaaaa
? obj/djgpp/mmx.h
? obj/djgpp/mmxtest.s
? obj/djgpp/setupdat.s
? tools/allegro.cfg
Index: include/allegro/alconfig.h
===================================================================
RCS file: /cvsroot/alleg/allegro/include/allegro/alconfig.h,v
retrieving revision 1.13
diff -u -r1.13 alconfig.h
--- include/allegro/alconfig.h	2001/06/08 12:54:23	1.13
+++ include/allegro/alconfig.h	2001/07/01 17:24:26
@@ -89,8 +89,18 @@
 /* use constructor functions, if supported */
 #ifdef ALLEGRO_USE_CONSTRUCTOR
    #define CONSTRUCTOR_FUNCTION(func)              func __attribute__ ((constructor))
+   #define DESTRUCTOR_FUNCTION(func)               func __attribute__ ((destructor))
 #endif
 
+
+
+/* if we are using gcc, then constructors are supported */
+#ifdef __GNUC__
+   #undef CONSTRUCTOR_FUNCTION
+   #undef DESTRUCTOR_FUNCTION
+   #define CONSTRUCTOR_FUNCTION(func)              func __attribute__ ((constructor))
+   #define DESTRUCTOR_FUNCTION(func)               func __attribute__ ((destructor))
+#endif
 
 /* the rest of this file fills in some default definitions of language
  * features and helper functions, which are conditionalised so they will
Index: src/allegro.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/allegro.c,v
retrieving revision 1.19
diff -u -r1.19 allegro.c
--- src/allegro.c	2001/06/23 10:14:58	1.19
+++ src/allegro.c	2001/07/01 17:24:29
@@ -280,6 +280,10 @@
       _midi_constructor();
       _mouse_constructor();
       _register_bitmap_file_type_init();
+   #else
+      #ifndef DESTRUCTOR_FUNCTION
+     _register_bitmap_file_type_init();
+      #endif
    #endif
 
    if (errno_ptr)
Index: src/readbmp.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/readbmp.c,v
retrieving revision 1.7
diff -u -r1.7 readbmp.c
--- src/readbmp.c	2001/06/15 11:34:01	1.7
+++ src/readbmp.c	2001/07/01 17:24:29
@@ -170,6 +170,14 @@
    
    bitmap_type_list = NULL;
 
+   /* If we are using a destructor, then we only want to prune the list
+    * down to valid modules. So we clean up as usual, but then reinstall
+    * the internal modules.
+    */
+   #if defined(CONSTRUCTOR_FUNCTION) && defined(DESTRUCTOR_FUNCTION)
+      _register_bitmap_file_type_init();
+   #endif
+
    _remove_exit_func(register_bitmap_file_type_exit);
 }
 
@@ -191,15 +199,40 @@
 }
 
 
-
-/* _bitmap_filetype_constructor:
- *  Register bitmap filetype functions if this object file is linked in.
- */
-#ifdef CONSTRUCTOR_FUNCTION
-   CONSTRUCTOR_FUNCTION(static void _bitmap_filetype_constructor());
 
-   static void _bitmap_filetype_constructor()
+#if defined(CONSTRUCTOR_FUNCTION) && defined(DESTRUCTOR_FUNCTION)
+   CONSTRUCTOR_FUNCTION(static void bitmap_filetype_constructor());
+   DESTRUCTOR_FUNCTION(static void bitmap_filetype_destructor());
+
+   /* _bitmap_filetype_constructor:
+    *  Register bitmap filetype functions if this object file is linked
+    *  in. This isn't called if the load_bitmap() and save_bitmap()
+    *  functions aren't used in a program, thus saving a little space
+    *  in statically linked programs.
+    */
+   static void bitmap_filetype_constructor()
    {
       _register_bitmap_file_type_init();
+   }
+
+   /* _bitmap_filetype_destructor:
+    *  Since we only want to destroy the whole list when we *actually*
+    *  quit, not just when allegro_exit() is called, we need to use a
+    *  destructor to accomplish this.
+    */
+   static void bitmap_filetype_destructor()
+   {
+      BITMAP_TYPE_INFO *iter = bitmap_type_list, *next;
+
+      while (iter) {
+         next = iter->next;
+         free(iter->ext);
+         free(iter);
+         iter = next;
+      }
+   
+      bitmap_type_list = NULL;
+
+      _remove_exit_func(register_bitmap_file_type_exit);
    }
 #endif
I have tested this on DJGPP; the grabber can export and import bitmaps
fine, exbitmap is fine, and the test program wasn't broken in any way by
enabling the constructor system.

I would also like to say this:

Size (mb) of example .exe files:
   Before patch    After patch
     9.88            6.89
   Saving:  30.3%

Note that this is the UPX-compressed filesize I am comparing; if not
compressed, the difference would be even larger. In extreme cases (eg.
exfixed), the filesize has become less than half of what it was.

>- (add others here)

 - Adding Eric's Unicode example?

 - Putting the game data back into CVS, in the new broken-down packfile 
   format? Of course, the zipup scripts would have to ignore the 
   directory we put them in.

For the future (perhaps the TODO list), but not this WIP:

 - Taking a look at what else we can avoid linking if we don't use it. I 
   think that this is a fairly big task if it is done properly, because
   the method used should make the code more modular and readable, not 
   less so. I maybe volunteer for this :-)

 - Rewriting gfx_init(), so that it is more readable, and so that we can 
   use a dynamic driver registration thing. I did have a go at this a 
   while ago, but it is non-trivial and I was a little too busy at the 
   time. The advantage of this would be that people writing add-ons 
   could add their own graphics modes (like my GFX_FORCE idea for 
   laptops, or Kendall Bennet's Nucleus driver), and people writing
   ports to other platforms would have a (slightly) easier time.

 - Making more use of the FAQ list. Some questions come up regularly,     
   especially on the allegro.cc boards, and I think we could put them in 
   the FAQ. I think the FAQ could probably do with a general overhaul
   and reorganisation, anyway. (Example new question: "Why can't I use
   a C++ object method as a GUI procedure?").

Bye for now,
-- 
Laurence Withers, lwithers@xxxxxxxxxx
                http://www.lwithers.demon.co.uk/

Attachment: signature.asc
Description: PGP signature



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/