From efb7aefdec3ab1174a3b1928f8b0285084a97c08 Mon Sep 17 00:00:00 2001 From: "qiuyiuestc@gmail.com" Date: Mon, 23 May 2011 13:36:26 +0000 Subject: reconstruct module examples git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1427 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- examples/module/rtgui_app/tetris/SConstruct | 31 + examples/module/rtgui_app/tetris/application.c | 30 + examples/module/rtgui_app/tetris/tetris.h | 61 ++ examples/module/rtgui_app/tetris/tetris_modal.c | 730 ++++++++++++++++++++++++ examples/module/rtgui_app/tetris/tetris_ui.c | 184 ++++++ examples/module/rtgui_app/tetris/tetris_view.c | 218 +++++++ examples/module/tetris/SConstruct | 31 - examples/module/tetris/application.c | 30 - examples/module/tetris/tetris.h | 61 -- examples/module/tetris/tetris_modal.c | 730 ------------------------ examples/module/tetris/tetris_ui.c | 184 ------ examples/module/tetris/tetris_view.c | 218 ------- 12 files changed, 1254 insertions(+), 1254 deletions(-) create mode 100644 examples/module/rtgui_app/tetris/SConstruct create mode 100644 examples/module/rtgui_app/tetris/application.c create mode 100644 examples/module/rtgui_app/tetris/tetris.h create mode 100644 examples/module/rtgui_app/tetris/tetris_modal.c create mode 100644 examples/module/rtgui_app/tetris/tetris_ui.c create mode 100644 examples/module/rtgui_app/tetris/tetris_view.c delete mode 100644 examples/module/tetris/SConstruct delete mode 100644 examples/module/tetris/application.c delete mode 100644 examples/module/tetris/tetris.h delete mode 100644 examples/module/tetris/tetris_modal.c delete mode 100644 examples/module/tetris/tetris_ui.c delete mode 100644 examples/module/tetris/tetris_view.c (limited to 'examples/module') diff --git a/examples/module/rtgui_app/tetris/SConstruct b/examples/module/rtgui_app/tetris/SConstruct new file mode 100644 index 0000000000..28b4ebd0a3 --- /dev/null +++ b/examples/module/rtgui_app/tetris/SConstruct @@ -0,0 +1,31 @@ +import os +import sys + +EXEC_PATH = '/home/shaolin/CodeSourcery/Sourcery_G++_Lite/bin' +RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +PREFIX = 'arm-none-eabi-' +env = Environment(tools = ['mingw'], + AS = PREFIX + 'gcc', + ASFLAGS = '', + CC = PREFIX + 'gcc', + CCFLAGS = '-mcpu=arm920t -O0 -fPIC' , + AR = PREFIX + 'ar', + ARFLAGS = '-rc', + LINK = PREFIX + 'ld', + LINKFLAGS = '-z max-page-size=0x4 -shared -fPIC -e rt_application_init -nostdlib -s', + CPPPATH = [ + RTT_ROOT + '/include', + RTT_ROOT + '/bsp/mini2440', + RTT_ROOT + '/components/rtgui/include', + RTT_ROOT + '/components/rgtui/common', + RTT_ROOT + '/components/rtgui/server', + RTT_ROOT + '/components/rtgui/widgets' + ]) +env.PrependENVPath('PATH', EXEC_PATH) + +target = 'tetris.so' +src = Glob('*.c') + +env.Program(target, src) + diff --git a/examples/module/rtgui_app/tetris/application.c b/examples/module/rtgui_app/tetris/application.c new file mode 100644 index 0000000000..d845346eb3 --- /dev/null +++ b/examples/module/rtgui_app/tetris/application.c @@ -0,0 +1,30 @@ +/* + * File : app.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-28 Yi.Qiu the first version + */ + +#include +#include +#include +#include +#include +#include "tetris.h" + +int rt_application_init(void) +{ + rt_thread_t tid; + + tid = rt_thread_create("tetris", tetris_ui_entry, RT_NULL, 2048, 20, 5); + if (tid != RT_NULL) rt_thread_startup(tid); + return 0; +} + diff --git a/examples/module/rtgui_app/tetris/tetris.h b/examples/module/rtgui_app/tetris/tetris.h new file mode 100644 index 0000000000..b5ef13785f --- /dev/null +++ b/examples/module/rtgui_app/tetris/tetris.h @@ -0,0 +1,61 @@ +/* + * File : tetris_modal.c + * This file is part of RTGUI in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-14 Yi.Qiu first version + */ + + #include + + struct rt_tetris; + typedef struct rt_tetris rt_tetris_t; + + struct rt_tetris_view; + typedef struct rt_tetris_view rt_tetris_view_t; + + typedef rt_err_t (*on_update)(rt_tetris_view_t* thiz, rt_tetris_t* tetris); + + struct rt_tetris_view + { + rt_uint32_t width; + rt_uint32_t height; + + on_update update; + on_update update_next_brick; + on_update update_level; + on_update update_score_and_lines; + void *private; + }; + + rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height); + rt_err_t rt_tetris_destory(rt_tetris_t* thiz); + rt_err_t rt_tetris_start(rt_tetris_t* thiz); + rt_err_t rt_tetris_pause(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_width(rt_tetris_t* thiz); + rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_level(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_score(rt_tetris_t* thiz); + rt_uint32_t rt_tetris_height(rt_tetris_t* thiz); + rt_bool_t rt_tetris_status(rt_tetris_t* thiz); + rt_err_t rt_tetris_down(rt_tetris_t* thiz); + rt_err_t rt_tetris_left(rt_tetris_t* thiz); + rt_err_t rt_tetris_right(rt_tetris_t* thiz); + rt_err_t rt_tetris_drop(rt_tetris_t* thiz); + rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction); + rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view); + rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view); + rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block); + + rt_tetris_view_t* rt_tetris_view_create(void* private); + rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz); + +void tetris_ui_entry(void* parameter); + diff --git a/examples/module/rtgui_app/tetris/tetris_modal.c b/examples/module/rtgui_app/tetris/tetris_modal.c new file mode 100644 index 0000000000..01b5850e96 --- /dev/null +++ b/examples/module/rtgui_app/tetris/tetris_modal.c @@ -0,0 +1,730 @@ +/* + * File : tetris_modal.c + * This file is part of RTGUI in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-14 Yi.Qiu first version + */ + +#include +#include +#include "tetris.h" + +struct rt_tetris +{ + rt_uint32_t width; /* the width of the tetris */ + rt_uint32_t height; /* the height of the tetris */ + rt_uint16_t* panel; /* the panel of the tetris */ + rt_uint32_t* brick; /* the current brick of the tetris */ + rt_uint32_t* next_brick; /* the next brick of the tetris */ + rt_tetris_view_t* view; /* the view on which the tetris show */ + rt_uint32_t level; /* game level */ + rt_uint32_t lines; /* released lines count */ + rt_uint32_t score; /* total scores statistic */ + rt_bool_t status; /* game status, pause or runing */ +}; + +static const rt_uint32_t g_brick[][4] = +{ + {23,7,8,22}, + {23,7,8,24}, + {24,7,8,25}, + {8,7,9,23}, + {8,7,9,24}, + {8,7,9,25}, + {7,6,8,9}, +}; + +static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_delete_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_is_reach_top(rt_tetris_t* thiz, rt_uint32_t brick[]); +static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz); + +/** + * this function create a tetris instance + * + * @param width the width of tetris. + * @param height the height of tetris. + * + * @return the tetris instance + */ +rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height) +{ + int index; + + rt_tetris_t* thiz = (rt_tetris_t*)rt_malloc(sizeof(rt_tetris_t)); + RT_ASSERT(thiz != RT_NULL); + + thiz->height = height; + thiz->width = width; + thiz->panel = rt_malloc(thiz->height * sizeof(rt_uint32_t)); + rt_memset(thiz->panel, 0, thiz->height * sizeof(rt_uint32_t)); + + thiz->brick = (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); + index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); + rt_memcpy(thiz->brick, g_brick[index], 4 * sizeof(rt_uint32_t)); + + thiz->next_brick= (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); + index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); + rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); + + thiz->view = RT_NULL; + thiz->level = 0; + thiz->lines = 0; + thiz->score = 0; + thiz->status = RT_FALSE; + + return thiz; +} + +/** + * this function destory a tetris instance + * + * @param thiz the tetris instance. + * + * @return RT_EOK + */ +rt_err_t rt_tetris_destory(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz->panel && thiz->brick && thiz->next_brick); + + rt_free(thiz->panel); + rt_free(thiz->brick); + rt_free(thiz->next_brick); + rt_free(thiz); + + return RT_EOK; +} + +/** + * this function start tetris game + * + * @param thiz the tetris instance. + * + * @return RT_EOK + */ +rt_err_t rt_tetris_start(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + /* update next brick on view */ + thiz->view->update_next_brick(thiz->view, thiz); + + /* update level */ + thiz->view->update_level(thiz->view, thiz); + + /* update lines and score */ + thiz->view->update_score_and_lines(thiz->view, thiz); + + thiz->status = RT_TRUE; + + return RT_EOK; +} + +/** + * this function pause tetris game + * + * @param thiz the tetris instance. + * + * @return RT_EOK + */ +rt_err_t rt_tetris_pause(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + thiz->status = RT_FALSE; + + return RT_EOK; +} + +/** + * this function get width of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the width of the tetris instance + */ +rt_uint32_t rt_tetris_width(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->width; +} + +/** + * this function get next brick of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the next brick of the tetris instance + */ +rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->next_brick; +} + +/** + * this function get level of the tetris instance + * + * @param thiz the tetris instance. + * + * @return the level of the tetris instance + */ +rt_uint32_t rt_tetris_level(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->level; +} + +/** + * this function get released lines of the tetris instance + * + * @param thiz the tetris instance. + * + * @return the released lines of the tetris instance + */ +rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->lines; +} + +/** + * this function get score of the tetris instance + * + * @param thiz the tetris instance. + * + * @return the score of the tetris instance + */ +rt_uint32_t rt_tetris_score(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->score; +} + +/** + * this function get height of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the height of the tetris instance + */ +rt_uint32_t rt_tetris_height(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->height; +} + +/** + * this function get status of a tetris instance + * + * @param thiz the tetris instance. + * + * @return the status of the tetris instance + */ +rt_bool_t rt_tetris_status(rt_tetris_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + return thiz->status; +} + +/** + * this function makes current brick move down + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_down(rt_tetris_t* thiz) +{ + int i; + + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + /* delete the brick from tetris panel */ + rt_tetris_delete_brick(thiz, thiz->brick); + + for(i=0; i<4; i++) + { + /* check collision and bottom*/ + if((thiz->brick[i] >= thiz->width * (thiz->height - 1)) + || rt_tetris_check_collision(thiz, thiz->brick[i] + thiz->width) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + + if(rt_tetris_is_reach_top(thiz, thiz->brick) == RT_EOK) + { + rt_memset(thiz->panel, 0xff, thiz->height * sizeof(rt_uint32_t)); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + /* game over */ + return -RT_ETIMEOUT; + } + + if(rt_tetris_release_lines(thiz, thiz->brick) == RT_EOK) + { + /* update view */ + thiz->view->update(thiz->view, thiz); + } + + rt_tetris_update_brick(thiz); + return -RT_ERROR; + } + } + + for(i=0; i<4; i++) + { + /* increase one line */ + thiz->brick[i] += thiz->width; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function makes current brick move left + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_left(rt_tetris_t* thiz) +{ + int i; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + /* delete the brick from tetris panel */ + rt_tetris_delete_brick(thiz, thiz->brick); + + for(i=0; i<4; i++) + { + /* check left board */ + if((thiz->brick[i] % thiz->width) == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + + if(rt_tetris_check_collision(thiz, thiz->brick[i] - 1) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + } + + for(i=0; i<4; i++) + { + /* move one step to left */ + thiz->brick[i] --;; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function makes current brick move right + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_right(rt_tetris_t* thiz) +{ + int i; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + /* delete the brick from tetris panel */ + rt_tetris_delete_brick(thiz, thiz->brick); + + for(i=0; i<4; i++) + { + /* check left board */ + if(((thiz->brick[i] + 1) % thiz->width) == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + + /* check collision */ + if(rt_tetris_check_collision(thiz, thiz->brick[i] + 1) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + } + + for(i=0; i<4; i++) + { + /* move one step to right */ + thiz->brick[i] ++;; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function makes current brick drop quickly + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_drop(rt_tetris_t* thiz) +{ + rt_err_t ret; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ETIMEOUT; + + /* move down until blocked */ + while((ret = rt_tetris_down(thiz)) == RT_EOK); + + return ret; +} + +/** + * this function makes current brick do rotation + * + * @param thiz the tetris instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction) +{ + int i; + rt_uint32_t tmp[4]; + RT_ASSERT(thiz != RT_NULL); + + if(thiz->status == RT_FALSE) return -RT_ERROR; + + rt_tetris_delete_brick(thiz, thiz->brick); + + tmp[0] = thiz->brick[0]; + for(i=1; i<4; i++) + { + int diff = thiz->brick[0] - thiz->brick[i]; + if(diff == 1) + { + tmp[i] = thiz->brick[0] - thiz->width; + } + else if(diff == -1) + { + tmp[i] = thiz->brick[0] + thiz->width; + } + else if(diff == 2) + { + tmp[i] = thiz->brick[0] - 2 * thiz->width; + } + else if(diff == -2) + { + tmp[i] = thiz->brick[0] + 2 * thiz->width; + } + else if(diff == thiz->width - 1) + { + tmp[i] = thiz->brick[0] + thiz->width + 1; + } + else if(diff == 1 - thiz->width) + { + tmp[i] = thiz->brick[0] - thiz->width - 1; + } + else if(diff == thiz->width) + { + if((thiz->brick[0] + 1) % thiz->width == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] + 1; + } + else if(diff == -1 * (thiz->width)) + { + if(thiz->brick[0] % thiz->width == 0) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] - 1; + } + else if(diff == thiz->width + 1) + { + tmp[i] = thiz->brick[0] - thiz->width + 1; + } + else if(diff == -1 - thiz->width) + { + tmp[i] = thiz->brick[0] + thiz->width - 1; + } + else if(diff == 2 * thiz->width) + { + if((thiz->brick[0] % thiz->width) >= (thiz->width - 2)) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] + 2; + } + else if(diff == -2 * thiz->width) + { + if((thiz->brick[0] % thiz->width) < 2) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + else tmp[i] = thiz->brick[0] - 2; + } + + if(tmp[i] > (thiz->height) * thiz->width) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + + if(rt_tetris_check_collision(thiz, tmp[i]) == RT_EOK) + { + /* restore the deleted brick */ + rt_tetris_append_brick(thiz, thiz->brick); + return -RT_ERROR; + } + } + + /* do roration */ + for(i=0; i<4; i++) + { + thiz->brick[i] = tmp[i]; + } + + /* append the brick to tetris panel */ + rt_tetris_append_brick(thiz, thiz->brick); + + /* update view */ + thiz->view->update(thiz->view, thiz); + + return RT_EOK; +} + +/** + * this function add a view to the tetris + * + * @param thiz the tetris instance. + * @param view the view instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ +rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view) +{ + RT_ASSERT(thiz != RT_NULL); + + /* Only suppurt single view now */ + thiz->view = view; + + return RT_EOK; +} + +/** + * this function delete a view from the tetris + * + * @param thiz the tetris instance. + * @param view the view instance. + * + * @return RT_EOK on success, -RT_ERROR on fail + */ + +rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view) +{ + RT_ASSERT(thiz != RT_NULL); + + thiz->view = RT_NULL; + + return RT_EOK; +} + +/** + * this function used to check collision + * + * @param thiz the tetris instance. + * @param block the block to be checked. + * + * @return RT_EOK on collision, -RT_ERROR on not collision + */ +rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block) +{ + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(block < thiz->height * thiz->width); + + if((thiz->panel[block/thiz->width] & (1 << (block % thiz->width))) + == (1 << (block % thiz->width))) + { + return RT_EOK; + } + else + { + return -RT_ERROR; + } +} + +static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz) +{ + int index; + + RT_ASSERT(thiz != RT_NULL); + + index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); + + rt_memcpy(thiz->brick, thiz->next_brick, 4 * sizeof(rt_uint32_t)); + rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); + + /* update next brick on view */ + thiz->view->update_next_brick(thiz->view, thiz); + + return RT_EOK; +} + +static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]) +{ + int i; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(brick != RT_NULL); + + for(i=0; i<4; i++) + { + int y = brick[i]/thiz->width; + int x = brick[i]%thiz->width; + + thiz->panel[y] |= (1<width; + int x = brick[i]%thiz->width; + + thiz->panel[y] &= ~(1<width == 0) + return RT_EOK; + } + + return -RT_ERROR; +} + +static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]) +{ + int i, j, check_line = 0; + rt_bool_t line_released = -RT_ERROR; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(brick != RT_NULL); + + for(i=0; i<4; i++) + { + /* choose a line */ + check_line = brick[i]/thiz->width; + if((thiz->panel[check_line]) == ((1 << thiz->width) - 1)) + { + for(j=check_line; j>0; j--) + { + thiz->panel[j] = thiz->panel[j-1]; + } + + /* clear the first line */ + thiz->panel[0] = 0; + + for(j=i+1; j<4; j++) + { + if(brick[j] < brick[i]) + { + brick[j] += thiz->width; + } + } + + thiz->lines++; + thiz->score += 100; + line_released = RT_EOK; + } + } + + if(line_released == RT_EOK) + { + /* update view */ + thiz->view->update_score_and_lines(thiz->view, thiz); + return RT_EOK; + } + else + { + return -RT_ERROR; + } +} + diff --git a/examples/module/rtgui_app/tetris/tetris_ui.c b/examples/module/rtgui_app/tetris/tetris_ui.c new file mode 100644 index 0000000000..808a713602 --- /dev/null +++ b/examples/module/rtgui_app/tetris/tetris_ui.c @@ -0,0 +1,184 @@ +/* + * File : tetris_ui.c + * This file is part of RTGUI in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-14 Yi.Qiu first version + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tetris.h" + +struct app_info +{ + struct rtgui_view* home_view; + struct rtgui_workbench* workbench; + rt_tetris_t * tetris; + rt_tetris_view_t* tetris_view; + rtgui_timer_t* _timer; +}; +typedef struct app_info app_info; +static app_info g_app_info; + +static void _game_over(void) +{ + rtgui_timer_stop(g_app_info._timer); + rt_tetris_pause(g_app_info.tetris); + rt_tetris_destory(g_app_info.tetris); + rt_tetris_view_destroy(g_app_info.tetris_view); + rtgui_view_destroy(g_app_info.home_view); + rtgui_workbench_close(g_app_info.workbench); + rt_kprintf("GAME OVER\n"); +} + +static rt_bool_t home_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +{ + if (event->type == RTGUI_EVENT_PAINT) + { + struct rtgui_dc* dc; + rtgui_rect_t rect; + + /* draw child */ + rtgui_view_event_handler(widget, event); + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + rect.x1 = 96; + rect.y1 = 0; + rect.x2 = 128; + rect.y2 = 16; + rtgui_dc_draw_text(dc, "next", &rect); + rect.y1 += 30; + rect.y2 = rect.y1 + 16; + rtgui_dc_draw_text(dc, "level", &rect); + rect.y1 += 22; + rect.y2 = rect.y1 + 16; + rtgui_dc_draw_text(dc, "lines", &rect); + rect.y1 += 22; + rect.y2 = rect.y1 + 16; + rtgui_dc_draw_text(dc, "score", &rect); + rtgui_dc_end_drawing(dc); + + /* start tetris game, removed later */ + rt_tetris_start(g_app_info.tetris); + return RT_FALSE; + } + else if ((event->type == RTGUI_EVENT_KBD)) + { + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; + + if (ekbd->type == RTGUI_KEYDOWN) + { + if (ekbd->key == RTGUIK_RIGHT) + { + rt_tetris_right(g_app_info.tetris); + } + else if (ekbd->key == RTGUIK_LEFT) + { + rt_tetris_left(g_app_info.tetris); + } + else if (ekbd->key == RTGUIK_UP) + { + rt_tetris_rotate(g_app_info.tetris, RT_EOK); + } + else if (ekbd->key == RTGUIK_DOWN) + { + if( rt_tetris_drop(g_app_info.tetris) == -RT_ETIMEOUT + && rt_tetris_status(g_app_info.tetris) != RT_FALSE) + { + _game_over(); + } + } + } + } + + return rtgui_view_event_handler(widget, event); +} + +static void _timer_timeout(rtgui_timer_t* timer, void* parameter) +{ + if( rt_tetris_down(g_app_info.tetris) == -RT_ETIMEOUT) + { + _game_over(); + } +} + +static rt_bool_t workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event) +{ + if (event->type == RTGUI_EVENT_KBD) + { + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; + if (((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME) + && !RTGUI_WORKBENCH_IS_MODAL_MODE(g_app_info.workbench)) + { + /* active home view */ + if (g_app_info.workbench->current_view != g_app_info.home_view) + { + rtgui_view_show(g_app_info.home_view, RT_FALSE); + return RT_TRUE; + } + } + } + + return rtgui_workbench_event_handler(widget, event); +} + +void tetris_ui_entry(void* parameter) +{ + rt_mq_t mq; + + mq = rt_mq_create("tetris_ui", 256, 4, RT_IPC_FLAG_FIFO); + rtgui_thread_register(rt_thread_self(), mq); + + g_app_info.workbench = rtgui_workbench_create("main", "workbench"); + if (g_app_info.workbench == RT_NULL) + { + rt_kprintf("can't find panel 'main'\n"); + return; + } + rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.workbench), workbench_event_handler); + + /* add home view */ + g_app_info.home_view = rtgui_view_create("Home"); + rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.home_view), home_view_event_handler); + + rtgui_workbench_add_view(g_app_info.workbench, g_app_info.home_view); + /* this view can be focused */ + RTGUI_WIDGET(g_app_info.home_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; + /* set widget focus */ + rtgui_widget_focus(RTGUI_WIDGET(g_app_info.home_view)); + RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(g_app_info.home_view)) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_view_show(g_app_info.home_view, RT_FALSE); + + /* create tetris modal instance */ + g_app_info.tetris = rt_tetris_create(16, 17); + + /* create tetris view instance */ + g_app_info.tetris_view = rt_tetris_view_create(RTGUI_WIDGET(g_app_info.home_view)); + + /* register tetris view to tetris modal */ + rt_tetris_add_view(g_app_info.tetris, g_app_info.tetris_view); + + g_app_info._timer = rtgui_timer_create(40, RT_TIMER_FLAG_PERIODIC, _timer_timeout, RT_NULL); + rtgui_timer_start(g_app_info._timer); + + rtgui_workbench_event_loop(g_app_info.workbench); + rtgui_workbench_destroy(g_app_info.workbench); + + rtgui_thread_deregister(rt_thread_self()); + rt_mq_delete(mq); +} + diff --git a/examples/module/rtgui_app/tetris/tetris_view.c b/examples/module/rtgui_app/tetris/tetris_view.c new file mode 100644 index 0000000000..dcb0cb312a --- /dev/null +++ b/examples/module/rtgui_app/tetris/tetris_view.c @@ -0,0 +1,218 @@ +/* + * File : tetris_view.c + * This file is part of RTGUI in RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-08-14 Yi.Qiu first version + */ + +#include +#include +#include +#include +#include +#include "tetris.h" + +static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris); +static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris); +static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris); +static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris); + +rt_tetris_view_t* rt_tetris_view_create(void* private) +{ + rt_tetris_view_t* thiz; + + RT_ASSERT(private != RT_NULL) + + thiz = (rt_tetris_view_t*)rt_malloc(sizeof(rt_tetris_view_t)); + thiz->width = 96; + thiz->height = 96; + + thiz->update = _rt_tetris_view_update; + thiz->update_next_brick = _rt_tetris_view_update_next_brick; + thiz->update_level = _rt_tetris_view_update_level; + thiz->update_score_and_lines = _rt_tetris_view_update_score_and_lines; + thiz->private = private; + + return thiz; +} + +rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz) +{ + RT_ASSERT(thiz != RT_NULL); + + rt_free(thiz); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rt_uint32_t width; + rt_uint32_t ppb, i; + rtgui_widget_t* widget; + rt_uint32_t* next_brick; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + next_brick = rt_tetris_next_brick(tetris); + widget = (rtgui_widget_t*)thiz->private; + width = rt_tetris_width(tetris); + /* pixel per block */ + ppb = thiz->width / width; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + rect.x1 = 100; + rect.x2 = rect.x1 + 4 * ppb; + rect.y1 = 16; + rect.y2 = rect.y1 + 2 * ppb; + + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + + for(i=0; i<4; i++) + { + rt_uint32_t y = next_brick[i] / width; + rt_uint32_t x = next_brick[i] % width; + + rect.x1 = 100 + ppb * (x - 6); + rect.x2 = rect.x1 + ppb - 1; + rect.y1 = 16 + ppb * y ; + rect.y2 = rect.y1 + ppb - 1; + + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_fill_rect(dc, &rect); + } + + rtgui_dc_end_drawing(dc); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rtgui_widget_t* widget; + char text[4]; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + widget = (rtgui_widget_t*)thiz->private; + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + rect.x1 = 96; + rect.y1 = 42; + rect.x2 = 128; + rect.y2 = rect.y1 + 10; + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + rt_sprintf(text, "%d", rt_tetris_level(tetris)); + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_draw_text(dc, text, &rect); + + /* Redraw panel */ + rtgui_dc_end_drawing(dc); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rtgui_widget_t* widget; + char text[4]; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + widget = (rtgui_widget_t*)thiz->private; + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + rect.x1 = 96; + rect.y1 = 64; + rect.x2 = 128; + rect.y2 = rect.y1 + 10; + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + rt_sprintf(text, "%d", rt_tetris_lines(tetris)); + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_draw_text(dc, text, &rect); + + rect.y1 += 22; + rect.y2 = rect.y1 + 10; + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); + rtgui_dc_fill_rect(dc, &rect); + rt_sprintf(text, "%d", rt_tetris_score(tetris)); + RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); + rtgui_dc_draw_text(dc, text, &rect); + + /* Redraw panel */ + rtgui_dc_end_drawing(dc); + + return RT_EOK; +} + +static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect; + rt_uint32_t width, height; + rt_uint32_t j,k, ppb; + rtgui_widget_t* widget; + + RT_ASSERT(thiz != RT_NULL); + RT_ASSERT(tetris != RT_NULL); + + widget = (rtgui_widget_t*)thiz->private; + width = rt_tetris_width(tetris); + height = rt_tetris_height(tetris); + ppb = thiz->width / width; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return -RT_ERROR; + + /* Redraw panel */ + for(j=0; j -#include -#include -#include -#include -#include "tetris.h" - -int rt_application_init(void) -{ - rt_thread_t tid; - - tid = rt_thread_create("tetris", tetris_ui_entry, RT_NULL, 2048, 20, 5); - if (tid != RT_NULL) rt_thread_startup(tid); - return 0; -} - diff --git a/examples/module/tetris/tetris.h b/examples/module/tetris/tetris.h deleted file mode 100644 index b5ef13785f..0000000000 --- a/examples/module/tetris/tetris.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * File : tetris_modal.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - - #include - - struct rt_tetris; - typedef struct rt_tetris rt_tetris_t; - - struct rt_tetris_view; - typedef struct rt_tetris_view rt_tetris_view_t; - - typedef rt_err_t (*on_update)(rt_tetris_view_t* thiz, rt_tetris_t* tetris); - - struct rt_tetris_view - { - rt_uint32_t width; - rt_uint32_t height; - - on_update update; - on_update update_next_brick; - on_update update_level; - on_update update_score_and_lines; - void *private; - }; - - rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height); - rt_err_t rt_tetris_destory(rt_tetris_t* thiz); - rt_err_t rt_tetris_start(rt_tetris_t* thiz); - rt_err_t rt_tetris_pause(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_width(rt_tetris_t* thiz); - rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_level(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_score(rt_tetris_t* thiz); - rt_uint32_t rt_tetris_height(rt_tetris_t* thiz); - rt_bool_t rt_tetris_status(rt_tetris_t* thiz); - rt_err_t rt_tetris_down(rt_tetris_t* thiz); - rt_err_t rt_tetris_left(rt_tetris_t* thiz); - rt_err_t rt_tetris_right(rt_tetris_t* thiz); - rt_err_t rt_tetris_drop(rt_tetris_t* thiz); - rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction); - rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view); - rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view); - rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block); - - rt_tetris_view_t* rt_tetris_view_create(void* private); - rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz); - -void tetris_ui_entry(void* parameter); - diff --git a/examples/module/tetris/tetris_modal.c b/examples/module/tetris/tetris_modal.c deleted file mode 100644 index 01b5850e96..0000000000 --- a/examples/module/tetris/tetris_modal.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * File : tetris_modal.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - -#include -#include -#include "tetris.h" - -struct rt_tetris -{ - rt_uint32_t width; /* the width of the tetris */ - rt_uint32_t height; /* the height of the tetris */ - rt_uint16_t* panel; /* the panel of the tetris */ - rt_uint32_t* brick; /* the current brick of the tetris */ - rt_uint32_t* next_brick; /* the next brick of the tetris */ - rt_tetris_view_t* view; /* the view on which the tetris show */ - rt_uint32_t level; /* game level */ - rt_uint32_t lines; /* released lines count */ - rt_uint32_t score; /* total scores statistic */ - rt_bool_t status; /* game status, pause or runing */ -}; - -static const rt_uint32_t g_brick[][4] = -{ - {23,7,8,22}, - {23,7,8,24}, - {24,7,8,25}, - {8,7,9,23}, - {8,7,9,24}, - {8,7,9,25}, - {7,6,8,9}, -}; - -static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_delete_brick(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_is_reach_top(rt_tetris_t* thiz, rt_uint32_t brick[]); -static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz); - -/** - * this function create a tetris instance - * - * @param width the width of tetris. - * @param height the height of tetris. - * - * @return the tetris instance - */ -rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height) -{ - int index; - - rt_tetris_t* thiz = (rt_tetris_t*)rt_malloc(sizeof(rt_tetris_t)); - RT_ASSERT(thiz != RT_NULL); - - thiz->height = height; - thiz->width = width; - thiz->panel = rt_malloc(thiz->height * sizeof(rt_uint32_t)); - rt_memset(thiz->panel, 0, thiz->height * sizeof(rt_uint32_t)); - - thiz->brick = (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); - index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); - rt_memcpy(thiz->brick, g_brick[index], 4 * sizeof(rt_uint32_t)); - - thiz->next_brick= (rt_uint32_t*)rt_malloc(4 * sizeof(rt_uint32_t)); - index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); - rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); - - thiz->view = RT_NULL; - thiz->level = 0; - thiz->lines = 0; - thiz->score = 0; - thiz->status = RT_FALSE; - - return thiz; -} - -/** - * this function destory a tetris instance - * - * @param thiz the tetris instance. - * - * @return RT_EOK - */ -rt_err_t rt_tetris_destory(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz->panel && thiz->brick && thiz->next_brick); - - rt_free(thiz->panel); - rt_free(thiz->brick); - rt_free(thiz->next_brick); - rt_free(thiz); - - return RT_EOK; -} - -/** - * this function start tetris game - * - * @param thiz the tetris instance. - * - * @return RT_EOK - */ -rt_err_t rt_tetris_start(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - /* update next brick on view */ - thiz->view->update_next_brick(thiz->view, thiz); - - /* update level */ - thiz->view->update_level(thiz->view, thiz); - - /* update lines and score */ - thiz->view->update_score_and_lines(thiz->view, thiz); - - thiz->status = RT_TRUE; - - return RT_EOK; -} - -/** - * this function pause tetris game - * - * @param thiz the tetris instance. - * - * @return RT_EOK - */ -rt_err_t rt_tetris_pause(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - thiz->status = RT_FALSE; - - return RT_EOK; -} - -/** - * this function get width of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the width of the tetris instance - */ -rt_uint32_t rt_tetris_width(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->width; -} - -/** - * this function get next brick of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the next brick of the tetris instance - */ -rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->next_brick; -} - -/** - * this function get level of the tetris instance - * - * @param thiz the tetris instance. - * - * @return the level of the tetris instance - */ -rt_uint32_t rt_tetris_level(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->level; -} - -/** - * this function get released lines of the tetris instance - * - * @param thiz the tetris instance. - * - * @return the released lines of the tetris instance - */ -rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->lines; -} - -/** - * this function get score of the tetris instance - * - * @param thiz the tetris instance. - * - * @return the score of the tetris instance - */ -rt_uint32_t rt_tetris_score(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->score; -} - -/** - * this function get height of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the height of the tetris instance - */ -rt_uint32_t rt_tetris_height(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->height; -} - -/** - * this function get status of a tetris instance - * - * @param thiz the tetris instance. - * - * @return the status of the tetris instance - */ -rt_bool_t rt_tetris_status(rt_tetris_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - return thiz->status; -} - -/** - * this function makes current brick move down - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_down(rt_tetris_t* thiz) -{ - int i; - - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - /* delete the brick from tetris panel */ - rt_tetris_delete_brick(thiz, thiz->brick); - - for(i=0; i<4; i++) - { - /* check collision and bottom*/ - if((thiz->brick[i] >= thiz->width * (thiz->height - 1)) - || rt_tetris_check_collision(thiz, thiz->brick[i] + thiz->width) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - - if(rt_tetris_is_reach_top(thiz, thiz->brick) == RT_EOK) - { - rt_memset(thiz->panel, 0xff, thiz->height * sizeof(rt_uint32_t)); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - /* game over */ - return -RT_ETIMEOUT; - } - - if(rt_tetris_release_lines(thiz, thiz->brick) == RT_EOK) - { - /* update view */ - thiz->view->update(thiz->view, thiz); - } - - rt_tetris_update_brick(thiz); - return -RT_ERROR; - } - } - - for(i=0; i<4; i++) - { - /* increase one line */ - thiz->brick[i] += thiz->width; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function makes current brick move left - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_left(rt_tetris_t* thiz) -{ - int i; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - /* delete the brick from tetris panel */ - rt_tetris_delete_brick(thiz, thiz->brick); - - for(i=0; i<4; i++) - { - /* check left board */ - if((thiz->brick[i] % thiz->width) == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - - if(rt_tetris_check_collision(thiz, thiz->brick[i] - 1) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - } - - for(i=0; i<4; i++) - { - /* move one step to left */ - thiz->brick[i] --;; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function makes current brick move right - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_right(rt_tetris_t* thiz) -{ - int i; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - /* delete the brick from tetris panel */ - rt_tetris_delete_brick(thiz, thiz->brick); - - for(i=0; i<4; i++) - { - /* check left board */ - if(((thiz->brick[i] + 1) % thiz->width) == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - - /* check collision */ - if(rt_tetris_check_collision(thiz, thiz->brick[i] + 1) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - } - - for(i=0; i<4; i++) - { - /* move one step to right */ - thiz->brick[i] ++;; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function makes current brick drop quickly - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_drop(rt_tetris_t* thiz) -{ - rt_err_t ret; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ETIMEOUT; - - /* move down until blocked */ - while((ret = rt_tetris_down(thiz)) == RT_EOK); - - return ret; -} - -/** - * this function makes current brick do rotation - * - * @param thiz the tetris instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction) -{ - int i; - rt_uint32_t tmp[4]; - RT_ASSERT(thiz != RT_NULL); - - if(thiz->status == RT_FALSE) return -RT_ERROR; - - rt_tetris_delete_brick(thiz, thiz->brick); - - tmp[0] = thiz->brick[0]; - for(i=1; i<4; i++) - { - int diff = thiz->brick[0] - thiz->brick[i]; - if(diff == 1) - { - tmp[i] = thiz->brick[0] - thiz->width; - } - else if(diff == -1) - { - tmp[i] = thiz->brick[0] + thiz->width; - } - else if(diff == 2) - { - tmp[i] = thiz->brick[0] - 2 * thiz->width; - } - else if(diff == -2) - { - tmp[i] = thiz->brick[0] + 2 * thiz->width; - } - else if(diff == thiz->width - 1) - { - tmp[i] = thiz->brick[0] + thiz->width + 1; - } - else if(diff == 1 - thiz->width) - { - tmp[i] = thiz->brick[0] - thiz->width - 1; - } - else if(diff == thiz->width) - { - if((thiz->brick[0] + 1) % thiz->width == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] + 1; - } - else if(diff == -1 * (thiz->width)) - { - if(thiz->brick[0] % thiz->width == 0) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] - 1; - } - else if(diff == thiz->width + 1) - { - tmp[i] = thiz->brick[0] - thiz->width + 1; - } - else if(diff == -1 - thiz->width) - { - tmp[i] = thiz->brick[0] + thiz->width - 1; - } - else if(diff == 2 * thiz->width) - { - if((thiz->brick[0] % thiz->width) >= (thiz->width - 2)) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] + 2; - } - else if(diff == -2 * thiz->width) - { - if((thiz->brick[0] % thiz->width) < 2) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - else tmp[i] = thiz->brick[0] - 2; - } - - if(tmp[i] > (thiz->height) * thiz->width) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - - if(rt_tetris_check_collision(thiz, tmp[i]) == RT_EOK) - { - /* restore the deleted brick */ - rt_tetris_append_brick(thiz, thiz->brick); - return -RT_ERROR; - } - } - - /* do roration */ - for(i=0; i<4; i++) - { - thiz->brick[i] = tmp[i]; - } - - /* append the brick to tetris panel */ - rt_tetris_append_brick(thiz, thiz->brick); - - /* update view */ - thiz->view->update(thiz->view, thiz); - - return RT_EOK; -} - -/** - * this function add a view to the tetris - * - * @param thiz the tetris instance. - * @param view the view instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ -rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view) -{ - RT_ASSERT(thiz != RT_NULL); - - /* Only suppurt single view now */ - thiz->view = view; - - return RT_EOK; -} - -/** - * this function delete a view from the tetris - * - * @param thiz the tetris instance. - * @param view the view instance. - * - * @return RT_EOK on success, -RT_ERROR on fail - */ - -rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view) -{ - RT_ASSERT(thiz != RT_NULL); - - thiz->view = RT_NULL; - - return RT_EOK; -} - -/** - * this function used to check collision - * - * @param thiz the tetris instance. - * @param block the block to be checked. - * - * @return RT_EOK on collision, -RT_ERROR on not collision - */ -rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block) -{ - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(block < thiz->height * thiz->width); - - if((thiz->panel[block/thiz->width] & (1 << (block % thiz->width))) - == (1 << (block % thiz->width))) - { - return RT_EOK; - } - else - { - return -RT_ERROR; - } -} - -static rt_err_t rt_tetris_update_brick(rt_tetris_t* thiz) -{ - int index; - - RT_ASSERT(thiz != RT_NULL); - - index = (int)(7.0 * rand()/(RAND_MAX + 1.0)); - - rt_memcpy(thiz->brick, thiz->next_brick, 4 * sizeof(rt_uint32_t)); - rt_memcpy(thiz->next_brick, g_brick[index], 4 * sizeof(rt_uint32_t)); - - /* update next brick on view */ - thiz->view->update_next_brick(thiz->view, thiz); - - return RT_EOK; -} - -static rt_err_t rt_tetris_append_brick(rt_tetris_t* thiz, rt_uint32_t brick[]) -{ - int i; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(brick != RT_NULL); - - for(i=0; i<4; i++) - { - int y = brick[i]/thiz->width; - int x = brick[i]%thiz->width; - - thiz->panel[y] |= (1<width; - int x = brick[i]%thiz->width; - - thiz->panel[y] &= ~(1<width == 0) - return RT_EOK; - } - - return -RT_ERROR; -} - -static rt_err_t rt_tetris_release_lines(rt_tetris_t* thiz, rt_uint32_t brick[]) -{ - int i, j, check_line = 0; - rt_bool_t line_released = -RT_ERROR; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(brick != RT_NULL); - - for(i=0; i<4; i++) - { - /* choose a line */ - check_line = brick[i]/thiz->width; - if((thiz->panel[check_line]) == ((1 << thiz->width) - 1)) - { - for(j=check_line; j>0; j--) - { - thiz->panel[j] = thiz->panel[j-1]; - } - - /* clear the first line */ - thiz->panel[0] = 0; - - for(j=i+1; j<4; j++) - { - if(brick[j] < brick[i]) - { - brick[j] += thiz->width; - } - } - - thiz->lines++; - thiz->score += 100; - line_released = RT_EOK; - } - } - - if(line_released == RT_EOK) - { - /* update view */ - thiz->view->update_score_and_lines(thiz->view, thiz); - return RT_EOK; - } - else - { - return -RT_ERROR; - } -} - diff --git a/examples/module/tetris/tetris_ui.c b/examples/module/tetris/tetris_ui.c deleted file mode 100644 index 808a713602..0000000000 --- a/examples/module/tetris/tetris_ui.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * File : tetris_ui.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "tetris.h" - -struct app_info -{ - struct rtgui_view* home_view; - struct rtgui_workbench* workbench; - rt_tetris_t * tetris; - rt_tetris_view_t* tetris_view; - rtgui_timer_t* _timer; -}; -typedef struct app_info app_info; -static app_info g_app_info; - -static void _game_over(void) -{ - rtgui_timer_stop(g_app_info._timer); - rt_tetris_pause(g_app_info.tetris); - rt_tetris_destory(g_app_info.tetris); - rt_tetris_view_destroy(g_app_info.tetris_view); - rtgui_view_destroy(g_app_info.home_view); - rtgui_workbench_close(g_app_info.workbench); - rt_kprintf("GAME OVER\n"); -} - -static rt_bool_t home_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) -{ - if (event->type == RTGUI_EVENT_PAINT) - { - struct rtgui_dc* dc; - rtgui_rect_t rect; - - /* draw child */ - rtgui_view_event_handler(widget, event); - - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - rect.x1 = 96; - rect.y1 = 0; - rect.x2 = 128; - rect.y2 = 16; - rtgui_dc_draw_text(dc, "next", &rect); - rect.y1 += 30; - rect.y2 = rect.y1 + 16; - rtgui_dc_draw_text(dc, "level", &rect); - rect.y1 += 22; - rect.y2 = rect.y1 + 16; - rtgui_dc_draw_text(dc, "lines", &rect); - rect.y1 += 22; - rect.y2 = rect.y1 + 16; - rtgui_dc_draw_text(dc, "score", &rect); - rtgui_dc_end_drawing(dc); - - /* start tetris game, removed later */ - rt_tetris_start(g_app_info.tetris); - return RT_FALSE; - } - else if ((event->type == RTGUI_EVENT_KBD)) - { - struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; - - if (ekbd->type == RTGUI_KEYDOWN) - { - if (ekbd->key == RTGUIK_RIGHT) - { - rt_tetris_right(g_app_info.tetris); - } - else if (ekbd->key == RTGUIK_LEFT) - { - rt_tetris_left(g_app_info.tetris); - } - else if (ekbd->key == RTGUIK_UP) - { - rt_tetris_rotate(g_app_info.tetris, RT_EOK); - } - else if (ekbd->key == RTGUIK_DOWN) - { - if( rt_tetris_drop(g_app_info.tetris) == -RT_ETIMEOUT - && rt_tetris_status(g_app_info.tetris) != RT_FALSE) - { - _game_over(); - } - } - } - } - - return rtgui_view_event_handler(widget, event); -} - -static void _timer_timeout(rtgui_timer_t* timer, void* parameter) -{ - if( rt_tetris_down(g_app_info.tetris) == -RT_ETIMEOUT) - { - _game_over(); - } -} - -static rt_bool_t workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event) -{ - if (event->type == RTGUI_EVENT_KBD) - { - struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; - if (((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME) - && !RTGUI_WORKBENCH_IS_MODAL_MODE(g_app_info.workbench)) - { - /* active home view */ - if (g_app_info.workbench->current_view != g_app_info.home_view) - { - rtgui_view_show(g_app_info.home_view, RT_FALSE); - return RT_TRUE; - } - } - } - - return rtgui_workbench_event_handler(widget, event); -} - -void tetris_ui_entry(void* parameter) -{ - rt_mq_t mq; - - mq = rt_mq_create("tetris_ui", 256, 4, RT_IPC_FLAG_FIFO); - rtgui_thread_register(rt_thread_self(), mq); - - g_app_info.workbench = rtgui_workbench_create("main", "workbench"); - if (g_app_info.workbench == RT_NULL) - { - rt_kprintf("can't find panel 'main'\n"); - return; - } - rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.workbench), workbench_event_handler); - - /* add home view */ - g_app_info.home_view = rtgui_view_create("Home"); - rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.home_view), home_view_event_handler); - - rtgui_workbench_add_view(g_app_info.workbench, g_app_info.home_view); - /* this view can be focused */ - RTGUI_WIDGET(g_app_info.home_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; - /* set widget focus */ - rtgui_widget_focus(RTGUI_WIDGET(g_app_info.home_view)); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(g_app_info.home_view)) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_view_show(g_app_info.home_view, RT_FALSE); - - /* create tetris modal instance */ - g_app_info.tetris = rt_tetris_create(16, 17); - - /* create tetris view instance */ - g_app_info.tetris_view = rt_tetris_view_create(RTGUI_WIDGET(g_app_info.home_view)); - - /* register tetris view to tetris modal */ - rt_tetris_add_view(g_app_info.tetris, g_app_info.tetris_view); - - g_app_info._timer = rtgui_timer_create(40, RT_TIMER_FLAG_PERIODIC, _timer_timeout, RT_NULL); - rtgui_timer_start(g_app_info._timer); - - rtgui_workbench_event_loop(g_app_info.workbench); - rtgui_workbench_destroy(g_app_info.workbench); - - rtgui_thread_deregister(rt_thread_self()); - rt_mq_delete(mq); -} - diff --git a/examples/module/tetris/tetris_view.c b/examples/module/tetris/tetris_view.c deleted file mode 100644 index dcb0cb312a..0000000000 --- a/examples/module/tetris/tetris_view.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * File : tetris_view.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-08-14 Yi.Qiu first version - */ - -#include -#include -#include -#include -#include -#include "tetris.h" - -static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris); -static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris); -static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris); -static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris); - -rt_tetris_view_t* rt_tetris_view_create(void* private) -{ - rt_tetris_view_t* thiz; - - RT_ASSERT(private != RT_NULL) - - thiz = (rt_tetris_view_t*)rt_malloc(sizeof(rt_tetris_view_t)); - thiz->width = 96; - thiz->height = 96; - - thiz->update = _rt_tetris_view_update; - thiz->update_next_brick = _rt_tetris_view_update_next_brick; - thiz->update_level = _rt_tetris_view_update_level; - thiz->update_score_and_lines = _rt_tetris_view_update_score_and_lines; - thiz->private = private; - - return thiz; -} - -rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz) -{ - RT_ASSERT(thiz != RT_NULL); - - rt_free(thiz); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rt_uint32_t width; - rt_uint32_t ppb, i; - rtgui_widget_t* widget; - rt_uint32_t* next_brick; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - next_brick = rt_tetris_next_brick(tetris); - widget = (rtgui_widget_t*)thiz->private; - width = rt_tetris_width(tetris); - /* pixel per block */ - ppb = thiz->width / width; - - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - rect.x1 = 100; - rect.x2 = rect.x1 + 4 * ppb; - rect.y1 = 16; - rect.y2 = rect.y1 + 2 * ppb; - - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - - for(i=0; i<4; i++) - { - rt_uint32_t y = next_brick[i] / width; - rt_uint32_t x = next_brick[i] % width; - - rect.x1 = 100 + ppb * (x - 6); - rect.x2 = rect.x1 + ppb - 1; - rect.y1 = 16 + ppb * y ; - rect.y2 = rect.y1 + ppb - 1; - - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_fill_rect(dc, &rect); - } - - rtgui_dc_end_drawing(dc); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rtgui_widget_t* widget; - char text[4]; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - widget = (rtgui_widget_t*)thiz->private; - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - rect.x1 = 96; - rect.y1 = 42; - rect.x2 = 128; - rect.y2 = rect.y1 + 10; - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - rt_sprintf(text, "%d", rt_tetris_level(tetris)); - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_draw_text(dc, text, &rect); - - /* Redraw panel */ - rtgui_dc_end_drawing(dc); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rtgui_widget_t* widget; - char text[4]; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - widget = (rtgui_widget_t*)thiz->private; - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - rect.x1 = 96; - rect.y1 = 64; - rect.x2 = 128; - rect.y2 = rect.y1 + 10; - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - rt_sprintf(text, "%d", rt_tetris_lines(tetris)); - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_draw_text(dc, text, &rect); - - rect.y1 += 22; - rect.y2 = rect.y1 + 10; - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff); - rtgui_dc_fill_rect(dc, &rect); - rt_sprintf(text, "%d", rt_tetris_score(tetris)); - RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00); - rtgui_dc_draw_text(dc, text, &rect); - - /* Redraw panel */ - rtgui_dc_end_drawing(dc); - - return RT_EOK; -} - -static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect; - rt_uint32_t width, height; - rt_uint32_t j,k, ppb; - rtgui_widget_t* widget; - - RT_ASSERT(thiz != RT_NULL); - RT_ASSERT(tetris != RT_NULL); - - widget = (rtgui_widget_t*)thiz->private; - width = rt_tetris_width(tetris); - height = rt_tetris_height(tetris); - ppb = thiz->width / width; - - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return -RT_ERROR; - - /* Redraw panel */ - for(j=0; j