[vlc-devel] [PATCH 2/7] Puzzle: main drawing functions

Vianney Boyer vlcvboyer at gmail.com
Mon Apr 15 14:14:09 CEST 2013


From: Vianney BOYER <vlcvboyer at gmail.com>
Date: Sun, 14 Apr 2013 12:24:55 +0200
Subject: [PATCH 2/7] Puzzle: main drawing functions

---
  modules/video_filter/puzzle_lib.c |  290 
+++++++++++++++++++++++++++++++++++++
  modules/video_filter/puzzle_lib.h |   64 ++++++++
  2 files changed, 354 insertions(+)
  create mode 100644 modules/video_filter/puzzle_lib.c
  create mode 100644 modules/video_filter/puzzle_lib.h

diff --git a/modules/video_filter/puzzle_lib.c 
b/modules/video_filter/puzzle_lib.c
new file mode 100644
index 0000000..0790c55
--- /dev/null
+++ b/modules/video_filter/puzzle_lib.c
@@ -0,0 +1,290 @@
+/*****************************************************************************
+ * puzzle_lib.c : Useful functions used by puzzle game filter
+ 
*****************************************************************************
+ * Copyright (C) 2005-2009 VLC authors and VideoLAN
+ * Copyright (C) 2013      Vianney Boyer
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+ *          Vianney Boyer <vlcvboyer -at- gmail -dot- com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ 
*****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ 
*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <math.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_filter.h>
+#include <vlc_rand.h>
+
+#include "filter_picture.h"
+
+#include "puzzle_lib.h"
+
+const char *ppsz_shuffle_button[SHUFFLE_LINES] =
+{
+"ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"oooooooooooooo  oooooooooooooooooooooooooooo   oooooooo   oooooo 
ooooooooooooooo",
+"oooooooooooooo  ooooooooooooooooooooooooooo  ooooooooo  oooooooo 
ooooooooooooooo",
+"oooooooooooooo  ooooooooooooooooooooooooooo  ooooooooo  oooooooo 
ooooooooooooooo",
+"oo     ooooooo  o    ooooooo  oooo  oooooo     oooooo     oooooo 
oooooooo    ooo",
+"o  oooo oooooo   ooo  oooooo  oooo  ooooooo  ooooooooo  oooooooo 
ooooooo  oo  oo",
+"o  ooooooooooo  oooo  oooooo  oooo  ooooooo  ooooooooo  oooooooo 
oooooo  oooo  o",
+"o      ooooooo  oooo  oooooo  oooo  ooooooo  ooooooooo  oooooooo 
oooooo        o",
+"oo      oooooo  oooo  oooooo  oooo  ooooooo  ooooooooo  oooooooo 
oooooo  ooooooo",
+"oooooo  oooooo  oooo  oooooo  oooo  ooooooo  ooooooooo  oooooooo 
oooooo  ooooooo",
+"o oooo  oooooo  oooo  oooooo  ooo   ooooooo  ooooooooo  oooooooo 
ooooooo  oooo o",
+"oo     ooooooo  oooo  ooooooo    o  ooooooo  ooooooooo  oooooooo 
oooooooo     oo",
+"ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
+};
+
+const char *ppsz_rot_arrow_sign[ARROW_LINES] =
+{
+"    .ooo.    ",
+"   .o. .oo.  ",
+"  .o.    .o. ",
+" .o.      .o.",
+" o.        .o",
+".o          .",
+".o   .       ",
+" o. .o.      ",
+" .o..o.      ",
+"  o..o       ",
+"   .o.       ",
+"ooooo.       ",
+"  ..         "
+};
+
+const char *ppsz_mir_arrow_sign[ARROW_LINES] =
+{
+"             ",
+"             ",
+"    .   .    ",
+"  .o.   .o.  ",
+" .o.     .o. ",
+".o.       .o.",
+"ooooooooooooo",
+".o.       .o.",
+" .o.     .o. ",
+"  .o.   .o.  ",
+"    .   .    ",
+"             ",
+"             "
+};
+
+/*****************************************************************************
+ * fill target image (clean memory)
+ 
*****************************************************************************/
+void puzzle_preset_desk_background( picture_t *p_pic_out, uint8_t Y, 
uint8_t U, uint8_t V)
+{
+    uint8_t i_c;
+
+    for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
+        if (i_plane == Y_PLANE)
+            i_c = Y;
+        else if (i_plane == U_PLANE)
+            i_c = U;
+        else if (i_plane == V_PLANE)
+            i_c = V;
+
+        const int32_t i_dst_pitch = p_pic_out->p[i_plane].i_pitch;
+        const int32_t i_dst_lines = p_pic_out->p[i_plane].i_lines;
+
+        uint8_t *p_dst = p_pic_out->p[i_plane].p_pixels;
+
+        for (int32_t y = 0; y < i_dst_lines; y++)
+            memset(&p_dst[y * i_dst_pitch], i_c, i_dst_pitch);
+    }
+}
+
+/*****************************************************************************
+ * draw the borders around the visible desk
+ 
*****************************************************************************/
+void puzzle_draw_borders( filter_t *p_filter, picture_t *p_pic_in, 
picture_t *p_pic_out)
+{
+    filter_sys_t *p_sys = p_filter->p_sys;
+
+    for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
+        const int32_t i_in_pitch      = 
p_sys->ps_pict_planes[i_plane].i_pitch;
+        const int32_t i_out_pitch     = 
p_sys->ps_desk_planes[i_plane].i_pitch;
+        const int32_t i_lines         = 
p_sys->ps_desk_planes[i_plane].i_lines;
+        const int32_t i_visible_pitch = 
p_sys->ps_desk_planes[i_plane].i_visible_pitch;
+        const int32_t i_border_pitch  = 
p_sys->ps_desk_planes[i_plane].i_border_width * 
p_sys->ps_desk_planes[i_plane].i_pixel_pitch;
+        const int32_t i_border_lines  = 
p_sys->ps_desk_planes[i_plane].i_border_lines;
+
+        uint8_t *p_src = p_pic_in->p[i_plane].p_pixels;
+        uint8_t *p_dst = p_pic_out->p[i_plane].p_pixels;
+
+        for (int32_t y = 0 ; y < i_border_lines; y++)
+            memcpy( &p_dst[y * i_out_pitch], &p_src[y * i_in_pitch], 
i_visible_pitch);
+
+        for (int32_t y = i_lines - i_border_lines ; y < i_lines; y++)
+            memcpy( &p_dst[y * i_out_pitch], &p_src[y * i_in_pitch], 
i_visible_pitch);
+
+        for (int32_t y = i_border_lines ; y < i_lines - i_border_lines; 
y++) {
+            memcpy( &p_dst[y * i_out_pitch], &p_src[y * i_in_pitch], 
i_border_pitch);
+            memcpy( &p_dst[y * i_out_pitch + i_visible_pitch - 
i_border_pitch], &p_src[y * i_in_pitch + i_visible_pitch - 
i_border_pitch], i_border_pitch);
+        }
+    }
+}
+
+/*****************************************************************************
+ * draw preview in a corner of the desk
+ 
*****************************************************************************/
+void puzzle_draw_preview( filter_t *p_filter, picture_t *p_pic_in, 
picture_t *p_pic_out)
+{
+    filter_sys_t *p_sys = p_filter->p_sys;
+
+    for( uint8_t  i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
+        int32_t i_preview_offset = 0;
+        int32_t i_preview_width  = 
p_sys->ps_desk_planes[i_plane].i_width * 
p_sys->s_current_param.i_preview_size / 100;
+        int32_t i_preview_lines  = 
p_pic_out->p[i_plane].i_visible_lines * 
p_sys->s_current_param.i_preview_size / 100;
+        int32_t i_pixel_pitch    = p_pic_out->p[i_plane].i_pixel_pitch;
+
+        const int32_t i_src_pitch  = p_pic_in->p[i_plane].i_pitch;
+        const int32_t i_dst_pitch  = p_pic_out->p[i_plane].i_pitch;
+
+        uint8_t *p_src = p_pic_in->p[i_plane].p_pixels;
+        uint8_t *p_dst = p_pic_out->p[i_plane].p_pixels;
+
+        switch ( p_sys->i_preview_pos ) {
+        case 0:
+            i_preview_offset = 0;
+            break;
+        case 1:
+            i_preview_offset =
+                (p_sys->ps_desk_planes[i_plane].i_width - 1 - 
i_preview_width) * i_pixel_pitch;
+            break;
+        case 2:
+            i_preview_offset =
+                (p_sys->ps_desk_planes[i_plane].i_width - 1 - 
i_preview_width) * i_pixel_pitch
+                + ((int32_t) ( p_sys->ps_desk_planes[i_plane].i_lines - 
1 - i_preview_lines )) * i_dst_pitch;
+            break;
+        case 3:
+            i_preview_offset = ((int32_t) ( 
p_sys->ps_desk_planes[i_plane].i_lines - 1 - i_preview_lines )) * 
i_dst_pitch;
+            break;
+        default:
+            i_preview_offset = 0;
+            break;
+        }
+
+        for ( int32_t y = 0; y < i_preview_lines; y++ )
+            for ( int32_t x = 0; x < i_preview_width; x++ )
+                memcpy( &p_dst[ y * i_dst_pitch + x * i_pixel_pitch + 
i_preview_offset ],
+                        &p_src[ ( y * 100 / 
p_sys->s_current_param.i_preview_size ) * i_src_pitch
+                                + ( x * 100 / 
p_sys->s_current_param.i_preview_size ) * i_pixel_pitch ],
+                        i_pixel_pitch );
+    }
+}
+
+/*****************************************************************************
+ * draw sign/icon/symbol in the output picture
+ 
*****************************************************************************/
+void puzzle_draw_sign(picture_t *p_pic_out, int32_t i_x, int32_t i_y, 
int32_t i_width, int32_t i_lines, const char **ppsz_sign, bool b_reverse)
+{
+    plane_t *p_out = &p_pic_out->p[Y_PLANE];
+    int32_t i_pixel_pitch    = p_pic_out->p[Y_PLANE].i_pixel_pitch;
+
+    uint8_t i_Y;
+
+    i_Y = ( p_out->p_pixels[ i_y * p_out->i_pitch + i_x ] >= 0x7F ) ? 
0x00 : 0xFF;
+
+    for( int32_t y = 0; y < i_lines ; y++ )
+        for( int32_t x = 0; x < i_width; x++ ) {
+            int32_t i_dst_x = ( x + i_x ) * i_pixel_pitch;
+            int32_t i_dst_y = y + i_y;
+            if ( ppsz_sign[y][b_reverse?i_width-1-x:x] == 'o' ) {
+                if ((i_dst_x < p_out->i_visible_pitch) && (i_dst_y < 
p_out->i_visible_lines) && (i_dst_x >= 0 ) && (i_dst_y >= 0))
+                    memset( &p_out->p_pixels[ i_dst_y * p_out->i_pitch 
+ i_dst_x ],   i_Y,  p_out->i_pixel_pitch );
+            }
+            else if ( ppsz_sign[y][b_reverse?i_width-1-x:x] == '.' ) {
+                if ((i_dst_x < p_out->i_visible_pitch) && (i_dst_y < 
p_out->i_visible_lines) && (i_dst_x >= 0 ) && (i_dst_y >= 0))
+                    p_out->p_pixels[ i_dst_y * p_out->i_pitch + i_dst_x 
] = p_out->p_pixels[ i_dst_y * p_out->i_pitch + i_dst_x ] / 2 + i_Y / 2;
+            }
+        }
+}
+
+/*****************************************************************************
+ * draw outline rectangle in output picture
+ 
*****************************************************************************/
+void puzzle_draw_rectangle(picture_t *p_pic_out, int32_t i_x, int32_t 
i_y, int32_t i_w, int32_t i_h, uint8_t i_Y, uint8_t i_U, uint8_t i_V )
+{
+    uint8_t i_c;
+
+    for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
+        plane_t *p_oyp = &p_pic_out->p[i_plane];
+        int32_t i_pixel_pitch    = p_pic_out->p[i_plane].i_pixel_pitch;
+
+        if (i_plane == Y_PLANE)
+            i_c = i_Y;
+        else if (i_plane == U_PLANE)
+            i_c = i_U;
+        else if (i_plane == V_PLANE)
+            i_c = i_V;
+
+        int32_t i_x_min = (      i_x    * p_oyp->i_visible_pitch / 
p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
+        int32_t i_x_max = ( (i_x + i_w) * p_oyp->i_visible_pitch / 
p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
+        int32_t i_y_min =        i_y    * p_oyp->i_visible_lines / 
p_pic_out->p[0].i_visible_lines;
+        int32_t i_y_max =   (i_y + i_h) * p_oyp->i_visible_lines / 
p_pic_out->p[0].i_visible_lines;
+
+        /* top line */
+        memset( &p_oyp->p_pixels[i_y_min * p_oyp->i_pitch + i_x_min], 
i_c,  i_x_max - i_x_min);
+
+        /* left and right */
+        for( int32_t i_dy = 1; i_dy < i_y_max - i_y_min - 1; i_dy++ ) {
+            memset( &p_oyp->p_pixels[ (i_y_min + i_dy) * p_oyp->i_pitch 
+ i_x_min ],   i_c,  p_oyp->i_pixel_pitch );
+            memset( &p_oyp->p_pixels[(i_y_min + i_dy) * p_oyp->i_pitch 
+ i_x_max - 1], i_c,  p_oyp->i_pixel_pitch );
+        }
+
+        /* bottom line */
+        memset( &p_oyp->p_pixels[(i_y_max - 1) * p_oyp->i_pitch + 
i_x_min], i_c,  i_x_max - i_x_min);
+    }
+}
+
+/*****************************************************************************
+ * draw bold rectangle in output picture
+ 
*****************************************************************************/
+void puzzle_fill_rectangle(picture_t *p_pic_out, int32_t i_x, int32_t 
i_y, int32_t i_w, int32_t i_h, uint8_t i_Y, uint8_t i_U, uint8_t i_V )
+{
+    uint8_t i_c;
+
+    for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
+        plane_t *p_oyp = &p_pic_out->p[i_plane];
+        int32_t i_pixel_pitch    = p_pic_out->p[i_plane].i_pixel_pitch;
+
+        if (i_plane == Y_PLANE)
+            i_c = i_Y;
+        else if (i_plane == U_PLANE)
+            i_c = i_U;
+        else if (i_plane == V_PLANE)
+            i_c = i_V;
+
+        int32_t i_x_min = (     i_x     * p_oyp->i_visible_pitch / 
p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
+        int32_t i_x_max = ( (i_x + i_w) * p_oyp->i_visible_pitch / 
p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
+        int32_t i_y_min =       i_y     * p_oyp->i_visible_lines / 
p_pic_out->p[0].i_visible_lines;
+        int32_t i_y_max =   (i_y + i_h) * p_oyp->i_visible_lines / 
p_pic_out->p[0].i_visible_lines;
+
+        for( int32_t i_dy = 0; i_dy < i_y_max - i_y_min; i_dy++ )
+            memset( &p_oyp->p_pixels[(i_y_min + i_dy) * p_oyp->i_pitch 
+ i_x_min], i_c,  i_x_max - i_x_min);
+    }
+}
diff --git a/modules/video_filter/puzzle_lib.h 
b/modules/video_filter/puzzle_lib.h
new file mode 100644
index 0000000..5160920
--- /dev/null
+++ b/modules/video_filter/puzzle_lib.h
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * puzzle_lib.h : Useful functions used by puzzle game filter
+ 
*****************************************************************************
+ * Copyright (C) 2005-2009 VLC authors and VideoLAN
+ * Copyright (C) 2013      Vianney Boyer
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
+ *          Vianney Boyer <vlcvboyer -at- gmail -dot- com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ 
*****************************************************************************/
+
+#ifndef VLC_LIB_PUZZLE_H
+#define VLC_LIB_PUZZLE_H 1
+
+
+/*****************************************************************************
+ * Preamble
+ 
*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <math.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_filter.h>
+#include <vlc_rand.h>
+
+#include "puzzle.h"
+
+void puzzle_preset_desk_background(picture_t *p_pic_out, uint8_t Y, 
uint8_t U, uint8_t V);
+void puzzle_draw_borders( filter_t *p_filter, picture_t *p_pic_in, 
picture_t *p_pic_out);
+void puzzle_draw_preview( filter_t *p_filter, picture_t *p_pic_in, 
picture_t *p_pic_out);
+void puzzle_draw_sign(picture_t *p_pic_out, int32_t i_x, int32_t i_y, 
int32_t i_width, int32_t i_lines, const char **ppsz_sign, bool b_reverse);
+void puzzle_draw_rectangle(picture_t *p_pic_out, int32_t x, int32_t y, 
int32_t i_w, int32_t i_h, uint8_t Y, uint8_t U, uint8_t V );
+void puzzle_fill_rectangle(picture_t *p_pic_out, int32_t x, int32_t y, 
int32_t i_w, int32_t i_h, uint8_t Y, uint8_t U, uint8_t V );
+static inline int32_t init_countdown(int32_t init_val) {
+    return ( ( __MAX( 1, 30000 - init_val)/20 ) / 2 + ((unsigned) 
vlc_mrand48() ) % ( __MAX( 1, ((30000 - init_val)/20) ) ) ); }
+
+#define SHUFFLE_WIDTH 81
+#define SHUFFLE_LINES 13
+extern const char *ppsz_shuffle_button[SHUFFLE_LINES];
+
+#define ARROW_WIDTH 13
+#define ARROW_LINES 13
+extern const char *ppsz_rot_arrow_sign[ARROW_LINES];
+extern const char *ppsz_mir_arrow_sign[ARROW_LINES];
+
+#endif
-- 
1.7.9.5





More information about the vlc-devel mailing list