/programs/games/2048/Makefile |
---|
0,0 → 1,3 |
OUTFILE = 2048 |
OBJS = main.o game.o board.o cell.o rect.o defines.o |
include $(MENUETDEV)/makefiles/Makefile_for_program |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/programs/games/2048/Tupfile.lua |
---|
0,0 → 1,6 |
if tup.getconfig('NO_GCC') ~= "" then return end |
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../.." or tup.getconfig("HELPERDIR") |
tup.include(HELPERDIR .. "/use_gcc.lua") |
tup.include(HELPERDIR .. "/use_menuetlibc.lua") |
compile_gcc{"main.c" "defines.c" "rect.c" "cell.c" "board.c" "game.c"} |
link_gcc("2048") |
/programs/games/2048/board.c |
---|
0,0 → 1,476 |
#include "board.h" |
rect base_cell = {0}; |
tile null_tile = {0}; |
struct { |
rect draw; // background rect |
rect cell_map[BOARD_MAP_SIZE]; // background cells array |
tile tile_map[BOARD_MAP_SIZE]; // tiles array |
__u16 empty_index[BOARD_MAP_SIZE];// empty cells indexes |
__u16 empty_count; // empty cells count |
__u32 score; |
} board = {0}; |
// Get tile index for row and column |
__u16 board_index(__u16 row, __u16 column) { |
return column + row * BOARD_COUNT; |
} |
// Get tile position (as point with eow and column) for index |
point board_position(__u16 index) { |
point p = { |
.x = index % BOARD_COUNT, |
.y = index / BOARD_COUNT |
}; |
return p; |
} |
// Calculate cell rect for row and column |
rect position2cell(point p) { |
rect c = {0}; |
c.width = base_cell.width; |
c.height = base_cell.height; |
c.x = board.draw.x + BOARD_SPACING + p.x * (c.width + BOARD_SPACING); |
c.y = board.draw.y + BOARD_SPACING + p.y * (c.height + BOARD_SPACING); |
return c; |
} |
// Update information about empty cells |
void board_update_empty_info(); |
// Represent tile array as pointers array |
void board_to_tempboard(tile* temp[]); |
// Fill tile array with tiles from pointers array |
void board_from_tempboard(tile* temp[], __u8 forward); |
// Move tile inside a pointer array |
void tempboard_move_tile(tile* temp[], __u16 from, __u16 to); |
// Merge tiles inside a pointer array |
void tempboard_merge_tile(tile* temp[], __u16 from, __u16 to); |
// Random number generator |
__u32 random_u32(__u32 max); |
void board_init(rect* r) |
{ |
// seed for random number generator |
srand(__menuet__getsystemclock()); |
board.score = 0; |
board.draw = *r; |
__u16 cell_size = (r->width - BOARD_SPACING * (BOARD_COUNT + 1)) / BOARD_COUNT; |
base_cell.width = cell_size; |
base_cell.height = cell_size; |
null_tile.value = 0; |
null_tile.animate = false; |
null_tile.ani_step = ANIM_STEP; |
null_tile.merged = false; |
__u16 i = 0; |
for (i = 0; i < BOARD_MAP_SIZE; i++) |
{ |
board.cell_map[i] = position2cell(board_position(i)); |
board.tile_map[i] = null_tile; |
} |
i = 0; |
for (i = 0; i < START_COUNT; i++) |
{ |
board_add_random_tile(); |
} |
board_redraw(); |
} |
void board_redraw() |
{ |
__u16 i = 0; |
__u8 animate = false; |
__u8 last_animate = false; |
do |
{ |
vsync(); |
rect_draw(&board.draw,BOARD_BG_COLOR); |
for (i = 0; i < BOARD_MAP_SIZE; i++) |
{ |
rect_draw(&board.cell_map[i],CELL_COLOR); |
} |
animate = false; |
last_animate = false; |
for (i = 0; i < BOARD_MAP_SIZE; i++) |
{ |
tile* t = &board.tile_map[i]; |
last_animate = tile_draw(t); |
if (last_animate) |
{ |
animate = last_animate; |
} |
} |
if (animate) |
{ |
__menuet__delay100(ANIM_DELAY); |
} |
} |
while (animate); |
} |
__u8 board_up() |
{ |
__u8 moved = false; |
__u16 row = 0; |
__u16 column = 0; |
__u16 ind = 0; |
__u16 preind = 0; |
tile* indtile = 0; |
tile* pretile = 0; |
tile* temp_board[BOARD_MAP_SIZE] = {0}; |
board_to_tempboard(temp_board); |
for (column = 0; column < BOARD_COUNT; column++) |
{ |
for (row = 0; row < BOARD_COUNT; row++) |
{ |
if (row > 0) |
{ |
ind = board_index(row,column); |
indtile = temp_board[ind]; |
if (indtile) |
{ |
preind = board_index(row - 1,column); |
pretile = temp_board[preind]; |
if (!pretile) |
{ |
moved = true; |
tempboard_move_tile(temp_board,ind,preind); |
row = 0; |
} |
else if (tile_mergeable(indtile,pretile)) |
{ |
moved = true; |
board.score += indtile->value * 2; |
tempboard_merge_tile(temp_board,ind,preind); |
row = 0; |
} |
} |
} |
} |
} |
board_from_tempboard(temp_board,true); |
return moved; |
} |
__u8 board_down() |
{ |
__u8 moved = false; |
__u16 row = 0; |
__u16 column = 0; |
__u16 ind = 0; |
__u16 preind = 0; |
tile* indtile = 0; |
tile* pretile = 0; |
tile* temp_board[BOARD_MAP_SIZE] = {0}; |
board_to_tempboard(temp_board); |
for (column = 0; column < BOARD_COUNT; column++) |
{ |
row = BOARD_COUNT; |
while (row--) |
{ |
if ((BOARD_COUNT - row) > 1) |
{ |
ind = board_index(row,column); |
indtile = temp_board[ind]; |
if (indtile) |
{ |
preind = board_index(row + 1,column); |
pretile = temp_board[preind]; |
if (!pretile) |
{ |
moved = true; |
tempboard_move_tile(temp_board,ind,preind); |
row = BOARD_COUNT; |
} |
else if (tile_mergeable(indtile,pretile)) |
{ |
moved = true; |
board.score += indtile->value * 2; |
tempboard_merge_tile(temp_board,ind,preind); |
row = BOARD_COUNT; |
} |
} |
} |
} |
} |
board_from_tempboard(temp_board,false); |
return moved; |
} |
__u8 board_left() |
{ |
__u8 moved = false; |
__u16 row = 0; |
__u16 column = 0; |
__u16 ind = 0; |
__u16 preind = 0; |
tile* indtile = 0; |
tile* pretile = 0; |
tile* temp_board[BOARD_MAP_SIZE] = {0}; |
board_to_tempboard(temp_board); |
for (row = 0; row < BOARD_COUNT; row++) |
{ |
for (column = 0; column < BOARD_COUNT; column++) |
{ |
if (column > 0) |
{ |
ind = board_index(row,column); |
indtile = temp_board[ind]; |
if (indtile) |
{ |
preind = board_index(row,column - 1); |
pretile = temp_board[preind]; |
if (!pretile) |
{ |
moved = true; |
tempboard_move_tile(temp_board,ind,preind); |
column = 0; |
} |
else if (tile_mergeable(indtile,pretile)) |
{ |
moved = true; |
board.score += indtile->value * 2; |
tempboard_merge_tile(temp_board,ind,preind); |
column = 0; |
} |
} |
} |
} |
} |
board_from_tempboard(temp_board,true); |
return moved; |
} |
__u8 board_right() |
{ |
__u8 moved = false; |
__u16 row = 0; |
__u16 column = 0; |
__u16 ind = 0; |
__u16 preind = 0; |
tile* indtile = 0; |
tile* pretile = 0; |
tile* temp_board[BOARD_MAP_SIZE] = {0}; |
board_to_tempboard(temp_board); |
for (row = 0; row < BOARD_COUNT; row++) |
{ |
column = BOARD_COUNT; |
while (column--) |
{ |
if ((BOARD_COUNT - column) > 1) |
{ |
ind = board_index(row,column); |
indtile = temp_board[ind]; |
if (indtile) |
{ |
preind = board_index(row,column + 1); |
pretile = temp_board[preind]; |
if (!pretile) |
{ |
moved = true; |
tempboard_move_tile(temp_board,ind,preind); |
column = BOARD_COUNT; |
} |
else if (tile_mergeable(indtile,pretile)) |
{ |
moved = true; |
board.score += indtile->value * 2; |
tempboard_merge_tile(temp_board,ind,preind); |
column = BOARD_COUNT; |
} |
} |
} |
} |
} |
board_from_tempboard(temp_board,false); |
return moved; |
} |
__u8 board_add_random_tile() |
{ |
board_update_empty_info(); |
if (board.empty_count) |
{ |
__u16 rnd_av = random_u32(board.empty_count); |
rnd_av = board.empty_index[rnd_av]; |
tile* av_tile = &board.tile_map[rnd_av]; |
av_tile->value = (random_u32(10) < 9) ? 2 : 4; |
av_tile->animate = true; |
av_tile->ani_step = 5; |
av_tile->transition = position2cell(board_position(rnd_av)); |
av_tile->cell.x = av_tile->transition.x + base_cell.width / 2; |
av_tile->cell.y = av_tile->transition.y + base_cell.height / 2; |
av_tile->cell.width = 0; |
av_tile->cell.height = 0; |
} |
return board.empty_count; |
} |
__u8 board_has_moves() |
{ |
__u16 ind = 0; |
__u16 next = 0; |
__u16 step = 0; |
__u16 pos = 0; |
for (step = 0; step < BOARD_COUNT; step++) |
{ |
for (pos = 0; pos < BOARD_COUNT; pos++) |
{ |
// check horizontal |
ind = board_index(step,pos); |
next = board_index(step,pos + 1); |
if (!board.tile_map[ind].value || |
(((pos + 1) < BOARD_COUNT) && |
(!board.tile_map[next].value || |
(board.tile_map[ind].value == board.tile_map[next].value) |
) |
) |
) |
return true; |
// check vertical |
ind = board_index(pos,step); |
next = board_index(pos + 1,step); |
if (!board.tile_map[ind].value || |
(((pos + 1) < BOARD_COUNT) && |
(!board.tile_map[next].value || |
(board.tile_map[ind].value == board.tile_map[next].value) |
) |
) |
) |
return true; |
} |
} |
return false; |
} |
__u32 board_score() |
{ |
return board.score; |
} |
void board_update_empty_info() |
{ |
board.empty_count = 0; |
__u16 i = 0; |
for (i = 0; i < BOARD_MAP_SIZE; i++) |
{ |
if (!board.tile_map[i].value) |
{ |
board.empty_index[board.empty_count] = i; |
board.empty_count++; |
} |
} |
} |
void board_to_tempboard(tile* temp[]) |
{ |
__u16 ind = 0; |
for (ind = 0; ind < BOARD_MAP_SIZE; ind++) |
{ |
tile* bt = &board.tile_map[ind]; |
if (bt->value) |
{ |
temp[ind] = bt; |
} |
} |
} |
void board_from_tempboard(tile *temp[], __u8 forward) |
{ |
__u16 ind = 0; |
if (forward) |
{ |
for (ind = 0; ind < BOARD_MAP_SIZE; ind++) |
{ |
tile* bt = &board.tile_map[ind]; |
tile* tt = temp[ind]; |
if (tt) |
{ |
*bt = *tt; |
bt->transition = position2cell(board_position(ind)); |
} |
else |
{ |
*bt = null_tile; |
} |
} |
} |
else |
{ |
ind = BOARD_MAP_SIZE; |
while (ind--) |
{ |
tile* bt = &board.tile_map[ind]; |
tile* tt = temp[ind]; |
if (tt) |
{ |
*bt = *tt; |
bt->transition = position2cell(board_position(ind)); |
} |
else |
{ |
*bt = null_tile; |
} |
} |
} |
} |
void tempboard_move_tile(tile* temp[], __u16 from, __u16 to) |
{ |
temp[to] = temp[from]; |
temp[to]->animate = true; |
temp[from] = 0; |
} |
void tempboard_merge_tile(tile* temp[], __u16 from, __u16 to) |
{ |
temp[from]->merged = true; |
temp[from]->merged_rect = temp[to]->cell; |
tempboard_move_tile(temp,from,to); |
} |
__u32 random_u32(__u32 max) |
{ |
return ((rand() * 1.0) / RAND_MAX) * max; |
} |
/programs/games/2048/board.h |
---|
0,0 → 1,40 |
#ifndef BOARD_H |
#define BOARD_H |
#include "defines.h" |
#include "cell.h" |
// Draw a new board |
void board_init(rect* r); |
// Redraw board and all content (animation will started if needed) |
void board_redraw(); |
// Add one tile with 2 or 4 value in a random cell place |
// Return true if tile added, false - if no more place for tile |
__u8 board_add_random_tile(); |
// Check for available moves |
// Return true if board has moves, false - if not |
__u8 board_has_moves(); |
// Get score |
__u32 board_score(); |
// Try to move all tiles up |
// Will return true if something moved or false - if not |
__u8 board_up(); |
// Try to move all tiles down |
// Will return true if something moved or false - if not |
__u8 board_down(); |
// Try to move all tiles left |
// Will return true if something moved or false - if not |
__u8 board_left(); |
// Try to move all tiles right |
// Will return true if something moved or false - if not |
__u8 board_right(); |
#endif // BOARD_H |
/programs/games/2048/cell.c |
---|
0,0 → 1,58 |
#include "cell.h" |
__u8 tile_draw(tile* t) |
{ |
if (t->value) |
{ |
__u32 bg_color = 0; |
__u32 txt_color = 0; |
switch (t->value) |
{ |
case 0 : bg_color = CELL_COLOR; break; |
case 2 : bg_color = 0xEEE4DA; txt_color = 0x776E65; break; |
case 4 : bg_color = 0xEDE0C8; txt_color = 0x776E65; break; |
case 8 : bg_color = 0xF2B179; txt_color = 0xF9F6F2; break; |
case 16 : bg_color = 0xF59563; txt_color = 0xF9F6F2; break; |
case 32 : bg_color = 0xF67C5F; txt_color = 0xF9F6F2; break; |
case 64 : bg_color = 0xF65E3B; txt_color = 0xF9F6F2; break; |
case 128 : bg_color = 0xEDCF72; txt_color = 0xF9F6F2; break; |
case 256 : bg_color = 0xEDCC61; txt_color = 0xF9F6F2; break; |
case 512 : bg_color = 0xEDC850; txt_color = 0xF9F6F2; break; |
case 1024 : bg_color = 0xEDC53F; txt_color = 0xF9F6F2; break; |
case 2048 : bg_color = 0xEDC22E; txt_color = 0xF9F6F2; break; |
default : bg_color = 0x3C3A32; txt_color = 0xF9F6F2; break; |
} |
rect* begin = &t->cell; |
rect* end = &t->transition; |
if (rect_transform(begin,end,t->ani_step)) |
t->animate = false; |
rect_draw(begin,bg_color); |
rect_draw_value(begin,t->value,txt_color); |
if (t->merged) |
{ |
if (rect_transform(&t->merged_rect,end,t->ani_step) && |
(t->animate == false)) |
{ |
t->animate = true; |
t->merged = false; |
t->value *= 2; |
} |
rect_draw(&t->merged_rect,bg_color); |
rect_draw_value(&t->merged_rect,t->value,txt_color); |
} |
} |
return t->animate; |
} |
__u8 tile_mergeable(tile* from, tile* to) |
{ |
return (from && !from->merged && |
to && !to->merged && |
(from->value == to->value)); |
} |
/programs/games/2048/cell.h |
---|
0,0 → 1,23 |
#ifndef CELL_H |
#define CELL_H |
#include "defines.h" |
#include "rect.h" |
typedef struct { |
rect cell; // current rect |
__u32 value; // value, 0 - do not draw a tile |
__u8 animate; // animation needed: true or false |
__u16 ani_step; // step for animation |
rect transition; // destination rect for animation |
__u8 merged; // merge flag |
rect merged_rect;// rect for drawing merged tile |
} tile; |
// Draw a tile (animation will started if needed) |
__u8 tile_draw(tile* t); |
// Check two tiles for merging |
__u8 tile_mergeable(tile* from, tile* to); |
#endif // CELL_H |
/programs/games/2048/defines.c |
---|
0,0 → 1,15 |
#include "defines.h" |
inline void enable_scancode() { |
__asm__ __volatile__("int $0x40"::"a"(66),"b"(1),"c"(1)); |
} |
inline void clear_key_buffer() { |
int i = 0; |
for (i = 0; i < 120; i++) |
__menuet__getkey(); |
} |
inline void vsync() { |
__asm__ __volatile__("int $0x40"::"a"(18),"b"(14)); |
} |
/programs/games/2048/defines.h |
---|
0,0 → 1,39 |
#ifndef DEFINES_H |
#define DEFINES_H |
#include <string.h> |
#include <stdlib.h> |
#include <keys.h> |
#include <menuet/gui.h> |
inline void enable_scancode(); |
inline void clear_key_buffer(); |
inline void vsync(); |
#define false (0) |
#define true (1) |
#define FONT_WIDTH (5) |
#define FONT_HEIGHT (9) |
#define ANIM_DELAY (5) // time between animation redraw |
#define ANIM_STEP (25) // default step for animation |
#define START_COUNT (2) // tiles count for new game |
#define WND_WIDTH (400) // main window width |
#define WND_HEIGHT (400) // main window height |
#define GAME_BORDER (30) // minimum border size around board |
#define GAME_BG_COLOR (0x34FAF8EF) // main window background color |
#define SCORE_HEIGHT (21) // minimum height for score text |
#define BOARD_SPACING (10) // spacing between cells |
#define BOARD_COUNT (4) // row and column count |
#define BOARD_MAP_SIZE (16) // cells total count (row * column) |
#define BOARD_BG_COLOR (0xBBADA0) // board color |
#define CELL_COLOR (0xCDC0B4) // cell color |
#endif // DEFINES_H |
/programs/games/2048/game.c |
---|
0,0 → 1,155 |
#include "game.h" |
struct { |
rect new_game_button;// new game button place |
rect score_rect; // score place |
__u8 over; // flag for game over |
} game; |
void game_draw_top() |
{ |
if (game.over) |
{ |
__menuet__make_button(game.new_game_button.x, |
game.new_game_button.y, |
game.new_game_button.width, |
game.new_game_button.height, |
NEW_GAME_BUTTON, |
BOARD_BG_COLOR); |
rect_draw_text(&game.new_game_button,"NEW GAME",8,GAME_BG_COLOR); |
} |
rect_draw(&game.score_rect,BOARD_BG_COLOR); |
rect_draw_value(&game.score_rect,board_score(),GAME_BG_COLOR); |
} |
void game_init() |
{ |
game.over = false; |
// place window at the center of screen |
__u16 screen_w = 0; |
__u16 screen_h = 0; |
__menuet__get_screen_max(&screen_w,&screen_h); |
__menuet__window_redraw(1); |
__menuet__define_window((screen_w - WND_WIDTH) / 2, |
(screen_h - WND_HEIGHT) / 2, |
WND_WIDTH, |
WND_HEIGHT, |
GAME_BG_COLOR, |
0, |
(__u32)header); |
// find info about window client area |
__menuet__get_process_table(&proc_info,PID_WHOAMI); |
// calc board |
rect av_area = {0}; |
av_area.x = GAME_BORDER; |
av_area.y = (SCORE_HEIGHT > GAME_BORDER) ? SCORE_HEIGHT : GAME_BORDER; |
av_area.width = proc_info.client_width - av_area.x * 2; |
av_area.height = proc_info.client_height - av_area.y - GAME_BORDER; |
// minimal square |
if (av_area.width < av_area.height) |
{ |
av_area.y += (av_area.height - av_area.width) / 2; |
av_area.height = av_area.width; |
} |
else // if (av_area.height < av_area.width) |
{ |
av_area.x += (av_area.width - av_area.height) / 2; |
av_area.width = av_area.height; |
} |
board_init(&av_area); |
game.new_game_button.x = av_area.x; |
game.new_game_button.y = (av_area.y - SCORE_HEIGHT) / 2; |
game.new_game_button.width = (av_area.width - BOARD_SPACING) / 2; |
game.new_game_button.height = SCORE_HEIGHT; |
game.score_rect.x = av_area.x + (av_area.width + BOARD_SPACING) / 2; |
game.score_rect.y = (av_area.y - SCORE_HEIGHT) / 2; |
game.score_rect.width = (av_area.width - BOARD_SPACING) / 2; |
game.score_rect.height = SCORE_HEIGHT; |
game_draw_top(); |
__menuet__window_redraw(2); |
} |
void game_redraw() |
{ |
__menuet__get_process_table(&proc_info,PID_WHOAMI); |
// start redraw |
__menuet__window_redraw(1); |
vsync(); |
__menuet__define_window(0, // __u16 x1 : ignored |
0, // __u16 y1 : ignored |
0, // __u16 xsize : ignored |
0, // __u16 ysize : ignored |
GAME_BG_COLOR, // __u32 body_color |
0, // __u32 grab_color |
(__u32)header); // __u32 frame_color or header |
game_draw_top(); |
board_redraw(); |
// end redraw |
__menuet__window_redraw(2); |
} |
void game_move_up() |
{ |
if (board_up()) |
{ |
board_redraw(); |
__u8 added = board_add_random_tile(); |
board_redraw(); |
game.over = !added || !board_has_moves(); |
game_draw_top(); |
} |
} |
void game_move_down() |
{ |
if (board_down()) |
{ |
board_redraw(); |
__u8 added = board_add_random_tile(); |
board_redraw(); |
game.over = !added || !board_has_moves(); |
game_draw_top(); |
} |
} |
void game_move_left() |
{ |
if (board_left()) |
{ |
board_redraw(); |
__u8 added = board_add_random_tile(); |
board_redraw(); |
game.over = !added || !board_has_moves(); |
game_draw_top(); |
} |
} |
void game_move_right() |
{ |
if (board_right()) |
{ |
board_redraw(); |
__u8 added = board_add_random_tile(); |
board_redraw(); |
game.over = !added || !board_has_moves(); |
game_draw_top(); |
} |
} |
/programs/games/2048/game.h |
---|
0,0 → 1,30 |
#ifndef GAME_H |
#define GAME_H |
#include "defines.h" |
#include "board.h" |
static const char header[] = "2048"; |
static struct process_table_entry proc_info = {0}; |
#define NEW_GAME_BUTTON (0xFF) |
// Start a new game |
void game_init(); |
// Redraw game content |
void game_redraw(); |
// Move Up |
void game_move_up(); |
// Move Down |
void game_move_down(); |
// Move Left |
void game_move_left(); |
// Move Right |
void game_move_right(); |
#endif // GAME_H |
/programs/games/2048/main.c |
---|
0,0 → 1,54 |
#include "game.h" |
#define KEY_RELEASED 0x80 |
void main() |
{ |
enable_scancode(); |
game_init(); |
for(;;) |
{ |
int ev = __menuet__wait_for_event(); |
switch (ev) |
{ |
case 1 : // EVENT_REDRAW: |
game_redraw(); |
break; |
case 2 : // EVENT_KEY: |
{ |
ev = __menuet__getkey() & 0xFF; |
switch (ev) |
{ |
case ((K_Up & 0xFF) | KEY_RELEASED) : // key Up released |
game_move_up(); |
clear_key_buffer(); |
break; |
case ((K_Down & 0xFF) | KEY_RELEASED) : // key Down released |
game_move_down(); |
clear_key_buffer(); |
break; |
case ((K_Left & 0xFF) | KEY_RELEASED) : // key Left released |
game_move_left(); |
clear_key_buffer(); |
break; |
case ((K_Right & 0xFF) | KEY_RELEASED) : // key Right released |
game_move_right(); |
clear_key_buffer(); |
break; |
} |
break; |
} |
case 3 : // EVENT_BUTTON |
ev = __menuet__get_button_id(); |
switch (ev) |
{ |
case NEW_GAME_BUTTON : |
game_init(); |
break; |
default : // close |
return; |
} |
} |
} |
} |
/programs/games/2048/rect.c |
---|
0,0 → 1,98 |
#include "rect.h" |
void rect_draw(rect* r, __u32 color) |
{ |
__menuet__bar(r->x,r->y,r->width,r->height,color); |
} |
__u8 rect_transform(rect* from, rect* to, __u16 step) |
{ |
if (from->width < to->width) |
{ |
from->width += (ANIM_STEP << 1); |
if (from->width > to->width) from->width = to->width; |
} |
else if (from->width > to->width) |
{ |
from->width -= (ANIM_STEP << 1); |
if (from->width < to->width) from->width = to->width; |
} |
if (from->height < to->height) |
{ |
from->height += (ANIM_STEP << 1); |
if (from->height > to->height) from->height = to->height; |
} |
else if (from->height > to->height) |
{ |
from->height -= (ANIM_STEP << 1); |
if (from->height < to->height) from->height = to->height; |
} |
if (from->x < to->x) |
{ |
from->x += ANIM_STEP; |
if (from->x > to->x) from->x = to->x; |
} |
else if (from->x > to->x) |
{ |
from->x -= ANIM_STEP; |
if (from->x < to->x) from->x = to->x; |
} |
if (from->y < to->y) |
{ |
from->y += ANIM_STEP; |
if (from->y > to->y) from->y = to->y; |
} |
else if (from->y > to->y) |
{ |
from->y -= ANIM_STEP; |
if (from->y < to->y) from->y = to->y; |
} |
return (from->x == to->x) && |
(from->y == to->y) && |
(from->width == to->width) && |
(from->height == to->height); |
} |
void rect_draw_text(rect *r, char *txt, __u32 len, __u32 color) |
{ |
__menuet__write_text(r->x + 1 + (r->width - len * FONT_WIDTH - len) / 2, |
r->y + 1 + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x - 1 + (r->width - len * FONT_WIDTH - len) / 2, |
r->y - 1 + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x - 1 + (r->width - len * FONT_WIDTH - len) / 2, |
r->y + 1 + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x + 1 + (r->width - len * FONT_WIDTH - len) / 2, |
r->y - 1 + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x + 1 + (r->width - len * FONT_WIDTH - len) / 2, |
r->y + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x - 1 + (r->width - len * FONT_WIDTH - len) / 2, |
r->y + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x + (r->width - len * FONT_WIDTH - len) / 2, |
r->y + 1 + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x + (r->width - len * FONT_WIDTH - len) / 2, |
r->y - 1 + (r->height - FONT_HEIGHT) / 2, |
0xFFFFFF,txt,len); |
__menuet__write_text(r->x + (r->width - len * FONT_WIDTH - len) / 2, |
r->y + (r->height - FONT_HEIGHT) / 2, |
0,txt,len); |
} |
void rect_draw_value(rect *r, __u32 v, __u32 color) |
{ |
char buffer[16] = {0}; |
__u32 length = strlen(itoa(v,buffer,10)); |
rect_draw_text(r,buffer,length,color); |
} |
/programs/games/2048/rect.h |
---|
0,0 → 1,32 |
#ifndef RECT_H |
#define RECT_H |
#include "defines.h" |
typedef struct { |
short x; |
short y; |
short width; |
short height; |
} rect; |
typedef struct { |
short x; |
short y; |
} point; |
// Draw rect filled with color |
void rect_draw(rect* r, __u32 color); |
// Make transformation step |
// Rect 'from' will be changed |
// Return 'true' if transformation ends ('from' == 'to') |
__u8 rect_transform(rect* from, rect* to, __u16 step); |
// Draw text at the rect center |
void rect_draw_text(rect* r, char* txt, __u32 len, __u32 color); |
// Draw value as text at the rect center |
void rect_draw_value(rect* r, __u32 v, __u32 color); |
#endif // RECT_H |