[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