src/render/software/SDL_blendline.c
author Sam Lantinga
Fri, 04 Feb 2011 19:50:56 -0800
changeset 5184 d976b67150c5
parent 5166 4d39eeaad00b
child 5226 710d00cb3a6a
permissions -rwxr-xr-x
Restored SDL_BLENDMODE_MOD for MAME
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_draw.h"
    25 #include "SDL_blendline.h"
    26 #include "SDL_blendpoint.h"
    27 
    28 
    29 static void
    30 SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2,
    31                    SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
    32                    SDL_bool draw_end)
    33 {
    34     const SDL_PixelFormat *fmt = dst->format;
    35     unsigned r, g, b, a, inva;
    36 
    37     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
    38         r = DRAW_MUL(_r, _a);
    39         g = DRAW_MUL(_g, _a);
    40         b = DRAW_MUL(_b, _a);
    41         a = _a;
    42     } else {
    43         r = _r;
    44         g = _g;
    45         b = _b;
    46         a = _a;
    47     }
    48     inva = (a ^ 0xff);
    49 
    50     if (y1 == y2) {
    51         switch (blendMode) {
    52         case SDL_BLENDMODE_BLEND:
    53             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
    54             break;
    55         case SDL_BLENDMODE_ADD:
    56             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
    57             break;
    58         case SDL_BLENDMODE_MOD:
    59             HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
    60             break;
    61         default:
    62             HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
    63             break;
    64         }
    65     } else if (x1 == x2) {
    66         switch (blendMode) {
    67         case SDL_BLENDMODE_BLEND:
    68             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
    69             break;
    70         case SDL_BLENDMODE_ADD:
    71             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
    72             break;
    73         case SDL_BLENDMODE_MOD:
    74             VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
    75             break;
    76         default:
    77             VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
    78             break;
    79         }
    80     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
    81         switch (blendMode) {
    82         case SDL_BLENDMODE_BLEND:
    83             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
    84             break;
    85         case SDL_BLENDMODE_ADD:
    86             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
    87             break;
    88         case SDL_BLENDMODE_MOD:
    89             DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
    90             break;
    91         default:
    92             DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
    93             break;
    94         }
    95     } else {
    96         switch (blendMode) {
    97         case SDL_BLENDMODE_BLEND:
    98             AALINE(x1, y1, x2, y2,
    99                    DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
   100                    draw_end);
   101             break;
   102         case SDL_BLENDMODE_ADD:
   103             AALINE(x1, y1, x2, y2,
   104                    DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB,
   105                    draw_end);
   106             break;
   107         case SDL_BLENDMODE_MOD:
   108             AALINE(x1, y1, x2, y2,
   109                    DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB,
   110                    draw_end);
   111             break;
   112         default:
   113             AALINE(x1, y1, x2, y2,
   114                    DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
   115                    draw_end);
   116             break;
   117         }
   118     }
   119 }
   120 
   121 static void
   122 SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   123                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   124                      SDL_bool draw_end)
   125 {
   126     const SDL_PixelFormat *fmt = dst->format;
   127     unsigned r, g, b, a, inva;
   128 
   129     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   130         r = DRAW_MUL(_r, _a);
   131         g = DRAW_MUL(_g, _a);
   132         b = DRAW_MUL(_b, _a);
   133         a = _a;
   134     } else {
   135         r = _r;
   136         g = _g;
   137         b = _b;
   138         a = _a;
   139     }
   140     inva = (a ^ 0xff);
   141 
   142     if (y1 == y2) {
   143         switch (blendMode) {
   144         case SDL_BLENDMODE_BLEND:
   145             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
   146             break;
   147         case SDL_BLENDMODE_ADD:
   148             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
   149             break;
   150         case SDL_BLENDMODE_MOD:
   151             HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
   152             break;
   153         default:
   154             HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
   155             break;
   156         }
   157     } else if (x1 == x2) {
   158         switch (blendMode) {
   159         case SDL_BLENDMODE_BLEND:
   160             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
   161             break;
   162         case SDL_BLENDMODE_ADD:
   163             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
   164             break;
   165         case SDL_BLENDMODE_MOD:
   166             VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
   167             break;
   168         default:
   169             VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
   170             break;
   171         }
   172     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   173         switch (blendMode) {
   174         case SDL_BLENDMODE_BLEND:
   175             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
   176             break;
   177         case SDL_BLENDMODE_ADD:
   178             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
   179             break;
   180         case SDL_BLENDMODE_MOD:
   181             DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
   182             break;
   183         default:
   184             DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
   185             break;
   186         }
   187     } else {
   188         switch (blendMode) {
   189         case SDL_BLENDMODE_BLEND:
   190             AALINE(x1, y1, x2, y2,
   191                    DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
   192                    draw_end);
   193             break;
   194         case SDL_BLENDMODE_ADD:
   195             AALINE(x1, y1, x2, y2,
   196                    DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555,
   197                    draw_end);
   198             break;
   199         case SDL_BLENDMODE_MOD:
   200             AALINE(x1, y1, x2, y2,
   201                    DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555,
   202                    draw_end);
   203             break;
   204         default:
   205             AALINE(x1, y1, x2, y2,
   206                    DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
   207                    draw_end);
   208             break;
   209         }
   210     }
   211 }
   212 
   213 static void
   214 SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   215                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   216                      SDL_bool draw_end)
   217 {
   218     const SDL_PixelFormat *fmt = dst->format;
   219     unsigned r, g, b, a, inva;
   220 
   221     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   222         r = DRAW_MUL(_r, _a);
   223         g = DRAW_MUL(_g, _a);
   224         b = DRAW_MUL(_b, _a);
   225         a = _a;
   226     } else {
   227         r = _r;
   228         g = _g;
   229         b = _b;
   230         a = _a;
   231     }
   232     inva = (a ^ 0xff);
   233 
   234     if (y1 == y2) {
   235         switch (blendMode) {
   236         case SDL_BLENDMODE_BLEND:
   237             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
   238             break;
   239         case SDL_BLENDMODE_ADD:
   240             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
   241             break;
   242         case SDL_BLENDMODE_MOD:
   243             HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
   244             break;
   245         default:
   246             HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
   247             break;
   248         }
   249     } else if (x1 == x2) {
   250         switch (blendMode) {
   251         case SDL_BLENDMODE_BLEND:
   252             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
   253             break;
   254         case SDL_BLENDMODE_ADD:
   255             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
   256             break;
   257         case SDL_BLENDMODE_MOD:
   258             VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
   259             break;
   260         default:
   261             VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
   262             break;
   263         }
   264     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   265         switch (blendMode) {
   266         case SDL_BLENDMODE_BLEND:
   267             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
   268             break;
   269         case SDL_BLENDMODE_ADD:
   270             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
   271             break;
   272         case SDL_BLENDMODE_MOD:
   273             DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
   274             break;
   275         default:
   276             DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
   277             break;
   278         }
   279     } else {
   280         switch (blendMode) {
   281         case SDL_BLENDMODE_BLEND:
   282             AALINE(x1, y1, x2, y2,
   283                    DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
   284                    draw_end);
   285             break;
   286         case SDL_BLENDMODE_ADD:
   287             AALINE(x1, y1, x2, y2,
   288                    DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565,
   289                    draw_end);
   290             break;
   291         case SDL_BLENDMODE_MOD:
   292             AALINE(x1, y1, x2, y2,
   293                    DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565,
   294                    draw_end);
   295             break;
   296         default:
   297             AALINE(x1, y1, x2, y2,
   298                    DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
   299                    draw_end);
   300             break;
   301         }
   302     }
   303 }
   304 
   305 static void
   306 SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   307                    SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   308                    SDL_bool draw_end)
   309 {
   310     const SDL_PixelFormat *fmt = dst->format;
   311     unsigned r, g, b, a, inva;
   312 
   313     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   314         r = DRAW_MUL(_r, _a);
   315         g = DRAW_MUL(_g, _a);
   316         b = DRAW_MUL(_b, _a);
   317         a = _a;
   318     } else {
   319         r = _r;
   320         g = _g;
   321         b = _b;
   322         a = _a;
   323     }
   324     inva = (a ^ 0xff);
   325 
   326     if (y1 == y2) {
   327         switch (blendMode) {
   328         case SDL_BLENDMODE_BLEND:
   329             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
   330             break;
   331         case SDL_BLENDMODE_ADD:
   332             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
   333             break;
   334         case SDL_BLENDMODE_MOD:
   335             HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
   336             break;
   337         default:
   338             HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
   339             break;
   340         }
   341     } else if (x1 == x2) {
   342         switch (blendMode) {
   343         case SDL_BLENDMODE_BLEND:
   344             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
   345             break;
   346         case SDL_BLENDMODE_ADD:
   347             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
   348             break;
   349         case SDL_BLENDMODE_MOD:
   350             VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
   351             break;
   352         default:
   353             VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
   354             break;
   355         }
   356     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   357         switch (blendMode) {
   358         case SDL_BLENDMODE_BLEND:
   359             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
   360             break;
   361         case SDL_BLENDMODE_ADD:
   362             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
   363             break;
   364         case SDL_BLENDMODE_MOD:
   365             DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
   366             break;
   367         default:
   368             DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
   369             break;
   370         }
   371     } else {
   372         switch (blendMode) {
   373         case SDL_BLENDMODE_BLEND:
   374             AALINE(x1, y1, x2, y2,
   375                    DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
   376                    draw_end);
   377             break;
   378         case SDL_BLENDMODE_ADD:
   379             AALINE(x1, y1, x2, y2,
   380                    DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB,
   381                    draw_end);
   382             break;
   383         case SDL_BLENDMODE_MOD:
   384             AALINE(x1, y1, x2, y2,
   385                    DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB,
   386                    draw_end);
   387             break;
   388         default:
   389             AALINE(x1, y1, x2, y2,
   390                    DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
   391                    draw_end);
   392             break;
   393         }
   394     }
   395 }
   396 
   397 static void
   398 SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   399                     SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   400                     SDL_bool draw_end)
   401 {
   402     const SDL_PixelFormat *fmt = dst->format;
   403     unsigned r, g, b, a, inva;
   404 
   405     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   406         r = DRAW_MUL(_r, _a);
   407         g = DRAW_MUL(_g, _a);
   408         b = DRAW_MUL(_b, _a);
   409         a = _a;
   410     } else {
   411         r = _r;
   412         g = _g;
   413         b = _b;
   414         a = _a;
   415     }
   416     inva = (a ^ 0xff);
   417 
   418     if (y1 == y2) {
   419         switch (blendMode) {
   420         case SDL_BLENDMODE_BLEND:
   421             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
   422             break;
   423         case SDL_BLENDMODE_ADD:
   424             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
   425             break;
   426         case SDL_BLENDMODE_MOD:
   427             HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
   428             break;
   429         default:
   430             HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
   431             break;
   432         }
   433     } else if (x1 == x2) {
   434         switch (blendMode) {
   435         case SDL_BLENDMODE_BLEND:
   436             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
   437             break;
   438         case SDL_BLENDMODE_ADD:
   439             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
   440             break;
   441         case SDL_BLENDMODE_MOD:
   442             VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
   443             break;
   444         default:
   445             VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
   446             break;
   447         }
   448     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   449         switch (blendMode) {
   450         case SDL_BLENDMODE_BLEND:
   451             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
   452             break;
   453         case SDL_BLENDMODE_ADD:
   454             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
   455             break;
   456         case SDL_BLENDMODE_MOD:
   457             DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
   458             break;
   459         default:
   460             DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
   461             break;
   462         }
   463     } else {
   464         switch (blendMode) {
   465         case SDL_BLENDMODE_BLEND:
   466             AALINE(x1, y1, x2, y2,
   467                    DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
   468                    draw_end);
   469             break;
   470         case SDL_BLENDMODE_ADD:
   471             AALINE(x1, y1, x2, y2,
   472                    DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA,
   473                    draw_end);
   474             break;
   475         case SDL_BLENDMODE_MOD:
   476             AALINE(x1, y1, x2, y2,
   477                    DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA,
   478                    draw_end);
   479             break;
   480         default:
   481             AALINE(x1, y1, x2, y2,
   482                    DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
   483                    draw_end);
   484             break;
   485         }
   486     }
   487 }
   488 
   489 static void
   490 SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   491                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   492                      SDL_bool draw_end)
   493 {
   494     const SDL_PixelFormat *fmt = dst->format;
   495     unsigned r, g, b, a, inva;
   496 
   497     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   498         r = DRAW_MUL(_r, _a);
   499         g = DRAW_MUL(_g, _a);
   500         b = DRAW_MUL(_b, _a);
   501         a = _a;
   502     } else {
   503         r = _r;
   504         g = _g;
   505         b = _b;
   506         a = _a;
   507     }
   508     inva = (a ^ 0xff);
   509 
   510     if (y1 == y2) {
   511         switch (blendMode) {
   512         case SDL_BLENDMODE_BLEND:
   513             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
   514             break;
   515         case SDL_BLENDMODE_ADD:
   516             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
   517             break;
   518         case SDL_BLENDMODE_MOD:
   519             HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
   520             break;
   521         default:
   522             HLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
   523             break;
   524         }
   525     } else if (x1 == x2) {
   526         switch (blendMode) {
   527         case SDL_BLENDMODE_BLEND:
   528             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
   529             break;
   530         case SDL_BLENDMODE_ADD:
   531             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
   532             break;
   533         case SDL_BLENDMODE_MOD:
   534             VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
   535             break;
   536         default:
   537             VLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
   538             break;
   539         }
   540     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   541         switch (blendMode) {
   542         case SDL_BLENDMODE_BLEND:
   543             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
   544             break;
   545         case SDL_BLENDMODE_ADD:
   546             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
   547             break;
   548         case SDL_BLENDMODE_MOD:
   549             DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
   550             break;
   551         default:
   552             DLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
   553             break;
   554         }
   555     } else {
   556         switch (blendMode) {
   557         case SDL_BLENDMODE_BLEND:
   558             AALINE(x1, y1, x2, y2,
   559                    DRAW_SETPIXELXY_BLEND_RGB888, DRAW_SETPIXELXY_BLEND_RGB888,
   560                    draw_end);
   561             break;
   562         case SDL_BLENDMODE_ADD:
   563             AALINE(x1, y1, x2, y2,
   564                    DRAW_SETPIXELXY_ADD_RGB888, DRAW_SETPIXELXY_ADD_RGB888,
   565                    draw_end);
   566             break;
   567         case SDL_BLENDMODE_MOD:
   568             AALINE(x1, y1, x2, y2,
   569                    DRAW_SETPIXELXY_MOD_RGB888, DRAW_SETPIXELXY_MOD_RGB888,
   570                    draw_end);
   571             break;
   572         default:
   573             AALINE(x1, y1, x2, y2,
   574                    DRAW_SETPIXELXY_RGB888, DRAW_SETPIXELXY_BLEND_RGB888,
   575                    draw_end);
   576             break;
   577         }
   578     }
   579 }
   580 
   581 static void
   582 SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   583                        SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   584                        SDL_bool draw_end)
   585 {
   586     const SDL_PixelFormat *fmt = dst->format;
   587     unsigned r, g, b, a, inva;
   588 
   589     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   590         r = DRAW_MUL(_r, _a);
   591         g = DRAW_MUL(_g, _a);
   592         b = DRAW_MUL(_b, _a);
   593         a = _a;
   594     } else {
   595         r = _r;
   596         g = _g;
   597         b = _b;
   598         a = _a;
   599     }
   600     inva = (a ^ 0xff);
   601 
   602     if (y1 == y2) {
   603         switch (blendMode) {
   604         case SDL_BLENDMODE_BLEND:
   605             HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
   606             break;
   607         case SDL_BLENDMODE_ADD:
   608             HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
   609             break;
   610         case SDL_BLENDMODE_MOD:
   611             HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
   612             break;
   613         default:
   614             HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
   615             break;
   616         }
   617     } else if (x1 == x2) {
   618         switch (blendMode) {
   619         case SDL_BLENDMODE_BLEND:
   620             VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
   621             break;
   622         case SDL_BLENDMODE_ADD:
   623             VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
   624             break;
   625         case SDL_BLENDMODE_MOD:
   626             VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
   627             break;
   628         default:
   629             VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
   630             break;
   631         }
   632     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   633         switch (blendMode) {
   634         case SDL_BLENDMODE_BLEND:
   635             DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
   636             break;
   637         case SDL_BLENDMODE_ADD:
   638             DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
   639             break;
   640         case SDL_BLENDMODE_MOD:
   641             DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
   642             break;
   643         default:
   644             DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
   645             break;
   646         }
   647     } else {
   648         switch (blendMode) {
   649         case SDL_BLENDMODE_BLEND:
   650             AALINE(x1, y1, x2, y2,
   651                    DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
   652                    draw_end);
   653             break;
   654         case SDL_BLENDMODE_ADD:
   655             AALINE(x1, y1, x2, y2,
   656                    DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888,
   657                    draw_end);
   658             break;
   659         case SDL_BLENDMODE_MOD:
   660             AALINE(x1, y1, x2, y2,
   661                    DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888,
   662                    draw_end);
   663             break;
   664         default:
   665             AALINE(x1, y1, x2, y2,
   666                    DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
   667                    draw_end);
   668             break;
   669         }
   670     }
   671 }
   672 
   673 typedef void (*BlendLineFunc) (SDL_Surface * dst,
   674                                int x1, int y1, int x2, int y2,
   675                                SDL_BlendMode blendMode,
   676                                Uint8 r, Uint8 g, Uint8 b, Uint8 a,
   677                                SDL_bool draw_end);
   678 
   679 static BlendLineFunc
   680 SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt)
   681 {
   682     switch (fmt->BytesPerPixel) {
   683     case 2:
   684         if (fmt->Rmask == 0x7C00) {
   685             return SDL_BlendLine_RGB555;
   686         } else if (fmt->Rmask == 0xF800) {
   687             return SDL_BlendLine_RGB565;
   688         } else {
   689             return SDL_BlendLine_RGB2;
   690         }
   691         break;
   692     case 4:
   693         if (fmt->Rmask == 0x00FF0000) {
   694             if (fmt->Amask) {
   695                 return SDL_BlendLine_ARGB8888;
   696             } else {
   697                 return SDL_BlendLine_RGB888;
   698             }
   699         } else {
   700             if (fmt->Amask) {
   701                 return SDL_BlendLine_RGBA4;
   702             } else {
   703                 return SDL_BlendLine_RGB4;
   704             }
   705         }
   706     }
   707     return NULL;
   708 }
   709 
   710 int
   711 SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   712               SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   713 {
   714     BlendLineFunc func;
   715 
   716     if (!dst) {
   717         SDL_SetError("SDL_BlendLine(): Passed NULL destination surface");
   718         return -1;
   719     }
   720 
   721     func = SDL_CalculateBlendLineFunc(dst->format);
   722     if (!func) {
   723         SDL_SetError("SDL_BlendLine(): Unsupported surface format");
   724         return -1;
   725     }
   726 
   727     /* Perform clipping */
   728     /* FIXME: We don't actually want to clip, as it may change line slope */
   729     if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
   730         return 0;
   731     }
   732 
   733     func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE);
   734     return 0;
   735 }
   736 
   737 int
   738 SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count,
   739                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   740 {
   741     int i;
   742     int x1, y1;
   743     int x2, y2;
   744     SDL_bool draw_end;
   745     BlendLineFunc func;
   746 
   747     if (!dst) {
   748         SDL_SetError("SDL_BlendLines(): Passed NULL destination surface");
   749         return -1;
   750     }
   751 
   752     func = SDL_CalculateBlendLineFunc(dst->format);
   753     if (!func) {
   754         SDL_SetError("SDL_BlendLines(): Unsupported surface format");
   755         return -1;
   756     }
   757 
   758     for (i = 1; i < count; ++i) {
   759         x1 = points[i-1].x;
   760         y1 = points[i-1].y;
   761         x2 = points[i].x;
   762         y2 = points[i].y;
   763 
   764         /* Perform clipping */
   765         /* FIXME: We don't actually want to clip, as it may change line slope */
   766         if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
   767             continue;
   768         }
   769 
   770         /* Draw the end if it was clipped */
   771         draw_end = (x2 != points[i].x || y2 != points[i].y);
   772 
   773         func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end);
   774     }
   775     if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
   776         SDL_BlendPoint(dst, points[count-1].x, points[count-1].y,
   777                        blendMode, r, g, b, a);
   778     }
   779     return 0;
   780 }
   781 
   782 /* vi: set ts=4 sw=4 expandtab: */