--- makefile.mgw (revision 7808) +++ makefile.mgw (local) @@ -202,8 +202,9 @@ ifdef ALLEGRO_USE_C # ------ build a C-only version ------ VPATH += src/c -MY_OBJECTS = $(C_OBJECTS) cmiscs +MY_OBJECTS = $(C_OBJECTS) CFLAGS += -DALLEGRO_NO_ASM +SFLAGS += -DALLEGRO_NO_ASM else --- src/win/asmlock.s (revision 7808) +++ src/win/asmlock.s (local) @@ -24,6 +24,10 @@ .text +#if !defined(ALLEGRO_NO_ASM) + + + /* gfx_directx_write_bank: * edx = bitmap * eax = line @@ -91,9 +95,9 @@ FUNC (gfx_directx_write_bank_win) pushl %ecx /* clobber the line */ - movl GLOBL(wd_dirty_lines), %ecx + movl GLOBL(_al_wd_dirty_lines), %ecx addl BMP_YOFFSET(%edx), %ecx - movb $1, (%ecx,%eax) /* wd_dirty_lines[line] = 1; (line has changed) */ + movb $1, (%ecx,%eax) /* _al_wd_dirty_lines[line] = 1; (line has changed) */ /* check whether bitmap is already locked */ testl $BMP_ID_LOCKED, BMP_ID(%edx) @@ -198,29 +202,29 @@ update_dirty_lines: movl $0, RECT_LEFT movl BMP_W(%edx), %ecx /* ecx = dd_frontbuffer->w */ movl %ecx, RECT_RIGHT - movl GLOBL(wd_dirty_lines), %ebx /* ebx = wd_dirty_lines */ - movl BMP_H(%edx), %esi /* esi = dd_frontbuffer->h */ + movl GLOBL(_al_wd_dirty_lines), %ebx /* ebx = _al_wd_dirty_lines */ + movl BMP_H(%edx), %esi /* esi = dd_frontbuffer->h */ movl $0, %edi _align_ next_line: - movb (%ebx,%edi), %al /* al = wd_dirty_lines[edi] */ + movb (%ebx,%edi), %al /* al = _al_wd_dirty_lines[edi] */ testb %al, %al /* is dirty? */ jz test_end /* no ! */ movl %edi, RECT_TOP _align_ loop_dirty_lines: - movb $0, (%ebx,%edi) /* wd_dirty_lines[edi] = 0 */ + movb $0, (%ebx,%edi) /* _al_wd_dirty_lines[edi] = 0 */ incl %edi - movb (%ebx,%edi), %al /* al = wd_dirty_lines[edi] */ + movb (%ebx,%edi), %al /* al = _al_wd_dirty_lines[edi] */ testb %al, %al /* is still dirty? */ jnz loop_dirty_lines /* yes ! */ movl %edi, RECT_BOTTOM leal RECT_LEFT, %eax pushl %eax - call *GLOBL(update_window) + call *GLOBL(_al_wd_update_window) popl %eax _align_ @@ -297,3 +301,7 @@ FUNC (gfx_gdi_unwrite_bank) No_unlock_gdi: ret + + + +#endif /* !defined(ALLEGRO_NO_ASM) */ --- src/win/wddlock.c (revision 7808) +++ src/win/wddlock.c (local) @@ -23,11 +23,113 @@ #define PREFIX_E "al-wddlock ERROR: " + +/* If custom (asm) calling conversions are used, then the code in asmlock.s is + * used instead. + */ +#if defined(ALLEGRO_NO_ASM) + +static void update_dirty_lines(BITMAP *bmp) +{ + RECT rect; + int i; + + /* The width is always the full bitmap width, because we have no + * mechanism for measuring the X range of the update. + */ + rect.left = 0; + rect.right = bmp->w; + for (i = 0; i < bmp->h; i++) { + if (_al_wd_dirty_lines[i]) { + int j = i+1; + rect.top = i; + /* consecutive dirty lines are combined into ranges of Y values */ + while (_al_wd_dirty_lines[j]) + j++; + rect.bottom = j; + _al_wd_update_window(&rect); + i = j+1; + } + } +} + + + +uintptr_t gfx_directx_write_bank(BITMAP *bmp, int line) +{ + if (!(bmp->id & BMP_ID_LOCKED)) + gfx_directx_autolock(bmp); + + return (uintptr_t) bmp->line[line]; +} + + + +void gfx_directx_unwrite_bank(BITMAP *bmp) +{ + if (!(bmp->id & BMP_ID_AUTOLOCK)) + return; + + gfx_directx_unlock(bmp); + bmp->id &= ~ BMP_ID_AUTOLOCK; +} + + + +uintptr_t gfx_directx_write_bank_win(BITMAP *bmp, int line) +{ + _al_wd_dirty_lines[bmp->y_ofs+line] = 1; + + if (!(bmp->id & BMP_ID_LOCKED)) + gfx_directx_autolock(bmp); + + return (uintptr_t) bmp->line[line]; +} + + + +void gfx_directx_unwrite_bank_win(BITMAP *bmp) +{ + if (!(bmp->id & BMP_ID_AUTOLOCK)) + return; + + gfx_directx_unlock(bmp); + bmp->id &= ~BMP_ID_AUTOLOCK; + + /* Update dirty lines: this is safe because autolocking is guaranteed to + * be the only level of locking. (Or at least, that's what it says in + * asmlock.s) + */ + update_dirty_lines(gfx_directx_forefront_bitmap); +} + + + +void gfx_directx_unlock_win(BITMAP *bmp) +{ + gfx_directx_unlock(bmp); + + /* forefront_bitmap may still be locked in case of nested locking */ + if (!(gfx_directx_forefront_bitmap->id & BMP_ID_LOCKED)) + update_dirty_lines(gfx_directx_forefront_bitmap); +} + + + +#else /* !defined(ALLEGRO_NO_ASM) */ + + + +/* asmlock.s requires these two variables */ void (*ptr_gfx_directx_autolock) (BITMAP* bmp) = gfx_directx_autolock; void (*ptr_gfx_directx_unlock) (BITMAP* bmp) = gfx_directx_unlock; +#endif /* !defined(ALLEGRO_NO_ASM) */ + + + /* gfx_directx_switch_out: * Arranges for drawing requests to pause when we are in the background. */ --- src/win/wddraw.h (revision 7808) +++ src/win/wddraw.h (local) @@ -116,18 +116,23 @@ AL_FUNC(int, gfx_directx_update_color_fo AL_FUNC(int, set_video_mode, (int w, int h, int v_w, int v_h, int color_depth)); -/* bitmap locking (from wddlock.c and asmlock.s) */ +/* bitmap locking (from wddlock.c and wgdi.c and possibly asmlock.s) */ AL_FUNC(void, gfx_directx_lock, (BITMAP *bmp)); AL_FUNC(void, gfx_directx_autolock, (BITMAP* bmp)); AL_FUNC(void, gfx_directx_unlock, (BITMAP *bmp)); AL_FUNC(void, gfx_directx_unlock_win, (BITMAP *bmp)); AL_FUNC(void, gfx_directx_release_lock, (BITMAP * bmp)); -AL_FUNC(void, gfx_directx_write_bank, (void)); -AL_FUNC(void, gfx_directx_unwrite_bank, (void)); -AL_FUNC(void, gfx_directx_write_bank_win, (void)); -AL_FUNC(void, gfx_directx_unwrite_bank_win, (void)); -AL_FUNCPTR(void, ptr_gfx_directx_autolock, (BITMAP* bmp)); -AL_FUNCPTR(void, ptr_gfx_directx_unlock, (BITMAP* bmp)); +AL_FUNC(uintptr_t, gfx_directx_write_bank, (BITMAP *bmp, int line)); +AL_FUNC(void, gfx_directx_unwrite_bank, (BITMAP *bmp)); +AL_FUNC(uintptr_t, gfx_directx_write_bank_win, (BITMAP *bmp, int line)); +AL_FUNC(void, gfx_directx_unwrite_bank_win, (BITMAP *bmp)); +AL_FUNC(void, gfx_gdi_autolock, (struct BITMAP* bmp)); +AL_FUNC(void, gfx_gdi_unlock, (struct BITMAP* bmp)); +AL_FUNC(uintptr_t, gfx_gdi_write_bank, (BITMAP *bmp, int line)); +AL_FUNC(void, gfx_gdi_unwrite_bank, (BITMAP *bmp)); +/* dirty window updating (from wddwin.c, used in wddlock.c or asmlock.s) */ +AL_VAR(char *, _al_wd_dirty_lines); +AL_FUNCPTR(void, _al_wd_update_window, (RECT *rect)); /* bitmap creation (from wddbmp.c) */ --- src/win/wddwin.c (revision 7808) +++ src/win/wddwin.c (local) @@ -25,9 +25,8 @@ #define PREFIX_E "al-wddwin ERROR: " -/* exported only for asmlock.s */ -char *wd_dirty_lines = NULL; /* used in WRITE_BANK() */ -void (*update_window) (RECT *rect) = NULL; /* window updater */ +char *_al_wd_dirty_lines = NULL; /* used in WRITE_BANK() */ +void (*_al_wd_update_window) (RECT *rect) = NULL; /* window updater */ static void gfx_directx_set_palette_win(AL_CONST struct RGB *p, int from, int to, int vsync); @@ -206,7 +205,7 @@ static void paint_win(RECT *rect) rect->right = MIN(rect->right, gfx_directx_win.w); rect->bottom = MIN(rect->bottom, gfx_directx_win.h); - update_window(rect); + _al_wd_update_window(rect); } @@ -499,7 +498,7 @@ static int gfx_directx_show_video_bitmap /* display the new contents */ if (_wait_for_vsync) gfx_directx_sync(); - update_window(NULL); + _al_wd_update_window(NULL); return 0; } @@ -519,7 +518,7 @@ static void gfx_directx_set_palette_win_ for (n = from; n <= to; n++) cmap[n] = _win_desktop_rgb_map.data[p[n].r>>1][p[n].g>>1][p[n].b>>1]; - update_window(NULL); + _al_wd_update_window(NULL); } @@ -535,7 +534,7 @@ static void gfx_directx_set_palette_win( /* for the direct updating mode */ _set_colorconv_palette(p, from, to); - update_window(NULL); + _al_wd_update_window(NULL); } @@ -570,7 +569,7 @@ static int verify_color_depth (int color if ((gfx_directx_compare_color_depth(color_depth) == 0) && (color_depth != 8)) { /* the color depths match */ - update_window = update_matching_window; + _al_wd_update_window = update_matching_window; } else { /* disallow cross-conversion between 15-bit and 16-bit colors */ @@ -583,7 +582,7 @@ static int verify_color_depth (int color if (!colorconv_blit) return -1; - update_window = update_colorconv_window; + _al_wd_update_window = update_colorconv_window; /* read direct updating configuration variable */ ddu = get_config_string(uconvert_ascii("graphics", tmp1), @@ -763,9 +762,9 @@ static struct BITMAP *init_directx_win(i gfx_directx_forefront_bitmap->write_bank = gfx_directx_write_bank_win; /* the last flag serves as end of loop delimiter */ - wd_dirty_lines = _AL_MALLOC_ATOMIC((h+1) * sizeof(char)); - ASSERT(wd_dirty_lines); - memset(wd_dirty_lines, 0, (h+1) * sizeof(char)); + _al_wd_dirty_lines = _AL_MALLOC_ATOMIC((h+1) * sizeof(char)); + ASSERT(_al_wd_dirty_lines); + memset(_al_wd_dirty_lines, 0, (h+1) * sizeof(char)); /* connect to the system driver */ win_gfx_driver = &win_gfx_driver_windowed; @@ -807,9 +806,9 @@ static void gfx_directx_win_exit(struct win_gfx_driver = NULL; /* destroy dirty lines array */ - if (wd_dirty_lines) { - _AL_FREE(wd_dirty_lines); - wd_dirty_lines = NULL; + if (_al_wd_dirty_lines) { + _AL_FREE(_al_wd_dirty_lines); + _al_wd_dirty_lines = NULL; } /* destroy the offscreen backbuffer */ --- src/win/wgdi.c (revision 7808) +++ src/win/wgdi.c (local) @@ -32,18 +32,61 @@ #define PREFIX_E "al-wgdi ERROR: " -/* function from asmlock.s */ -extern void gfx_gdi_write_bank(void); -extern void gfx_gdi_unwrite_bank(void); - -/* exported only for asmlock.s */ static void gfx_gdi_autolock(struct BITMAP* bmp); static void gfx_gdi_unlock(struct BITMAP* bmp); -void (*ptr_gfx_gdi_autolock) (struct BITMAP* bmp) = gfx_gdi_autolock; -void (*ptr_gfx_gdi_unlock) (struct BITMAP* bmp) = gfx_gdi_unlock; + +/* This is used only in asmlock.s and this file. */ char *gdi_dirty_lines = NULL; /* used in WRITE_BANK() */ + +/* If custom (asm) calling conversions are used, then the code in asmlock.s is + * used instead. + */ +#if defined(ALLEGRO_NO_ASM) + + + +uintptr_t gfx_gdi_write_bank(BITMAP *bmp, int line) +{ + gdi_dirty_lines[bmp->y_ofs] = 1; + + if (!(bmp->id & BMP_ID_LOCKED)) + gfx_gdi_autolock(bmp); + + return (uintptr_t) bmp->line[line]; +} + + + +void gfx_gdi_unwrite_bank(BITMAP *bmp) +{ + if (!(bmp->id & BMP_ID_AUTOLOCK)) + return; + + gfx_gdi_unlock(bmp); + bmp->id &= ~ BMP_ID_AUTOLOCK; +} + + + +#else /* !defined(ALLEGRO_NO_ASM) */ + + + +/* asmlock.s requires these two variables */ +void (*ptr_gfx_gdi_autolock)(struct BITMAP* bmp) = gfx_gdi_autolock; +void (*ptr_gfx_gdi_unlock)(struct BITMAP* bmp) = gfx_gdi_unlock; + +/* wddraw.h, despite its name, includes the exports from asmlock.s */ +#include "wddraw.h" + + + +#endif /* !defined(ALLEGRO_NO_ASM) */ + + + static struct BITMAP *gfx_gdi_init(int w, int h, int v_w, int v_h, int color_depth); static void gfx_gdi_exit(struct BITMAP *b); static void gfx_gdi_set_palette(AL_CONST struct RGB *p, int from, int to, int vsync);