/programs/games/2048/Makefile |
---|
1,3 → 1,3 |
OUTFILE = 2048 |
OBJS = main.o game.o board.o cell.o rect.o defines.o |
OBJS = main.o game.o board.o paint.o cell.o rect.o defines.o |
include $(MENUETDEV)/makefiles/Makefile_for_program |
/programs/games/2048/Tupfile.lua |
---|
1,6 → 1,6 |
if tup.getconfig('NO_GCC') ~= "" then return end |
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../.." or tup.getconfig("HELPERDIR") |
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"} |
compile_gcc{"main.c", "defines.c", "rect.c", "paint.c", "cell.c", "board.c", "game.c"} |
link_gcc("2048") |
/programs/games/2048/board.c |
---|
3,7 → 3,6 |
rect base_cell = {0}; |
tile null_tile = {0}; |
struct { |
rect draw; // background rect |
rect cell_map[BOARD_MAP_SIZE]; // background cells array |
60,9 → 59,6 |
// 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; |
69,9 → 65,15 |
null_tile.value = 0; |
null_tile.animate = false; |
null_tile.ani_step = ANIM_STEP; |
null_tile.ani_step = ANI_APPEAR_STEP; |
null_tile.merged = false; |
board.score = 0; |
board.draw = *r; |
canvas_init(r); |
canvas_fill(BOARD_BG_COLOR); |
__u16 i = 0; |
for (i = 0; i < BOARD_MAP_SIZE; i++) |
{ |
88,6 → 90,11 |
board_redraw(); |
} |
void board_delete() |
{ |
canvas_delete(); |
} |
void board_redraw() |
{ |
__u16 i = 0; |
95,12 → 102,11 |
__u8 last_animate = false; |
do |
{ |
vsync(); |
rect_draw(&board.draw,BOARD_BG_COLOR); |
canvas_fill(BOARD_BG_COLOR); |
for (i = 0; i < BOARD_MAP_SIZE; i++) |
{ |
rect_draw(&board.cell_map[i],CELL_COLOR); |
canvas_draw_rect(&board.cell_map[i],CELL_COLOR); |
} |
animate = false; |
115,9 → 121,11 |
} |
} |
canvas_paint(); |
if (animate) |
{ |
__menuet__delay100(ANIM_DELAY); |
__menuet__delay100(ANI_DELAY); |
} |
} |
while (animate); |
333,7 → 341,7 |
av_tile->value = (random_u32(10) < 9) ? 2 : 4; |
av_tile->animate = true; |
av_tile->ani_step = 5; |
av_tile->ani_step = ANI_APPEAR_STEP; |
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; |
460,6 → 468,7 |
{ |
temp[to] = temp[from]; |
temp[to]->animate = true; |
temp[to]->ani_step = ANI_MOVE_STEP; |
temp[from] = 0; |
} |
/programs/games/2048/board.h |
---|
7,6 → 7,9 |
// Draw a new board |
void board_init(rect* r); |
// Free board resources |
void board_delete(); |
// Redraw board and all content (animation will started if needed) |
void board_redraw(); |
/programs/games/2048/cell.c |
---|
29,8 → 29,8 |
if (rect_transform(begin,end,t->ani_step)) |
t->animate = false; |
rect_draw(begin,bg_color); |
rect_draw_value(begin,t->value,txt_color); |
canvas_draw_rect(begin,bg_color); |
canvas_draw_value(begin,t->value,txt_color); |
if (t->merged) |
{ |
42,8 → 42,8 |
t->value *= 2; |
} |
rect_draw(&t->merged_rect,bg_color); |
rect_draw_value(&t->merged_rect,t->value,txt_color); |
canvas_draw_rect(&t->merged_rect,bg_color); |
canvas_draw_value(&t->merged_rect,t->value,txt_color); |
} |
} |
/programs/games/2048/cell.h |
---|
2,7 → 2,7 |
#define CELL_H |
#include "defines.h" |
#include "rect.h" |
#include "paint.h" |
typedef struct { |
rect cell; // current rect |
/programs/games/2048/defines.c |
---|
1,9 → 1,11 |
#include "defines.h" |
// Enable scancodes for event loop |
inline void enable_scancode() { |
__asm__ __volatile__("int $0x40"::"a"(66),"b"(1),"c"(1)); |
} |
// Clear key buffer |
inline void clear_key_buffer() { |
int i = 0; |
for (i = 0; i < 120; i++) |
10,6 → 12,7 |
__menuet__getkey(); |
} |
// Wait for screen draw (vertical sync) |
inline void vsync() { |
__asm__ __volatile__("int $0x40"::"a"(18),"b"(14)); |
} |
/programs/games/2048/defines.h |
---|
16,8 → 16,9 |
#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 ANI_DELAY (2) // time between animation redraw |
#define ANI_APPEAR_STEP (15) // default step for appear animation |
#define ANI_MOVE_STEP (25) // default step for move animation |
#define START_COUNT (2) // tiles count for new game |
/programs/games/2048/game.c |
---|
79,6 → 79,11 |
__menuet__window_redraw(2); |
} |
void game_exit() |
{ |
board_delete(); |
} |
void game_redraw() |
{ |
__menuet__get_process_table(&proc_info,PID_WHOAMI); |
86,7 → 91,6 |
// start redraw |
__menuet__window_redraw(1); |
vsync(); |
__menuet__define_window(0, // __u16 x1 : ignored |
0, // __u16 y1 : ignored |
0, // __u16 xsize : ignored |
/programs/games/2048/game.h |
---|
12,6 → 12,9 |
// Start a new game |
void game_init(); |
// Exit game |
void game_exit(); |
// Redraw game content |
void game_redraw(); |
/programs/games/2048/main.c |
---|
47,6 → 47,7 |
game_init(); |
break; |
default : // close |
game_exit(); |
return; |
} |
} |
/programs/games/2048/paint.c |
---|
0,0 → 1,133 |
#include "paint.h" |
typedef struct { |
char b; |
char g; |
char r; |
} rgb; |
struct { |
rect area; |
rgb* image; |
} canvas = {0}; |
__u32 canvas_index(__u16 row, __u16 column) { |
return column + row * canvas.area.width; |
} |
point canvas_position(__u32 index) { |
point p = { |
.x = index % canvas.area.width, |
.y = index / canvas.area.width |
}; |
return p; |
} |
void canvas_init(rect *r) |
{ |
canvas.area = *r; |
canvas_delete(); |
canvas.image = malloc(r->width * r->height * sizeof(rgb)); |
} |
void canvas_delete() |
{ |
if (canvas.image) |
free(canvas.image); |
} |
void canvas_fill(__u32 color) |
{ |
if (canvas.image) |
{ |
__u32 i = 0; |
__u32 len = canvas.area.width * canvas.area.height; |
for (i = 0; i < len; i++) |
{ |
canvas.image[i] = *((rgb*)(&color)); |
} |
} |
} |
void canvas_draw_rect(rect *r, __u32 color) |
{ |
if (canvas.image) |
{ |
__u32 row = 0; |
__u32 column = 0; |
rgb* c = (rgb*)(&color); |
for (row = 0; row < r->height; row++) |
{ |
for (column = 0; column < (r->width); column++) |
{ |
canvas.image[canvas_index(row + r->y - canvas.area.y, |
column + r->x - canvas.area.x)] = *c; |
} |
} |
} |
} |
void canvas_draw_text(rect* r, char* txt, __u32 len, __u32 color) |
{ |
__u16 x = r->x + (r->width - len * FONT_WIDTH - len) / 2 - canvas.area.x; |
__u16 y = r->y + (r->height - FONT_HEIGHT) / 2 - canvas.area.y; |
__u32 w; |
__u32 h; |
char* mem; |
h = FONT_HEIGHT; |
w = len * FONT_WIDTH + len; |
mem = malloc(sizeof(__u32) * 2 + h * w * sizeof(__u32)); |
memset(mem,0,sizeof(__u32) * 2 + h * w * sizeof(__u32)); |
((__u32*)mem)[0] = w; |
((__u32*)mem)[1] = h; |
__asm__ __volatile__("int $0x40":: |
"a"(4), |
"b"(0), |
"c"(color | (8 << 24)), |
"d"((__u32)txt), |
"S"(len), |
"D"((__u32)(mem))); |
int row = 0; |
int column = 0; |
__u32* __mem = (__u32*)(mem + 8); |
for (row = 0; row < h; row++) |
{ |
for (column = 0; column < w; column++) |
{ |
__u32 c = __mem[column + row * w]; |
if (c & 0xFF000000) |
{ |
canvas.image[canvas_index(row + y,column + x)] = *((rgb*)&c); |
} |
} |
} |
memset(mem,0,sizeof(__u32) * 2 + h * w * sizeof(__u32)); |
free(mem); |
} |
void canvas_draw_value(rect* r, __u32 v, __u32 color) |
{ |
char buffer[16] = {0}; |
__u32 length = strlen(itoa(v,buffer,10)); |
canvas_draw_text(r,buffer,length,color); |
} |
void canvas_paint() |
{ |
if (canvas.image) |
{ |
__menuet__putimage(canvas.area.x, |
canvas.area.y, |
canvas.area.width, |
canvas.area.height, |
(char*)canvas.image); |
} |
} |
/programs/games/2048/paint.h |
---|
0,0 → 1,17 |
#ifndef PAINT_H |
#define PAINT_H |
#include "defines.h" |
#include "rect.h" |
void canvas_init(rect* r); |
void canvas_delete(); |
void canvas_fill(__u32 color); |
void canvas_draw_rect(rect* r, __u32 color); |
void canvas_draw_text(rect* r, char* txt, __u32 len, __u32 color); |
void canvas_draw_value(rect *r, __u32 v, __u32 color); |
void canvas_paint(); |
#endif // PAINT_H |
/programs/games/2048/rect.c |
---|
9,45 → 9,45 |
{ |
if (from->width < to->width) |
{ |
from->width += (ANIM_STEP << 1); |
from->width += (step << 1); |
if (from->width > to->width) from->width = to->width; |
} |
else if (from->width > to->width) |
{ |
from->width -= (ANIM_STEP << 1); |
from->width -= (step << 1); |
if (from->width < to->width) from->width = to->width; |
} |
if (from->height < to->height) |
{ |
from->height += (ANIM_STEP << 1); |
from->height += (step << 1); |
if (from->height > to->height) from->height = to->height; |
} |
else if (from->height > to->height) |
{ |
from->height -= (ANIM_STEP << 1); |
from->height -= (step << 1); |
if (from->height < to->height) from->height = to->height; |
} |
if (from->x < to->x) |
{ |
from->x += ANIM_STEP; |
from->x += step; |
if (from->x > to->x) from->x = to->x; |
} |
else if (from->x > to->x) |
{ |
from->x -= ANIM_STEP; |
from->x -= step; |
if (from->x < to->x) from->x = to->x; |
} |
if (from->y < to->y) |
{ |
from->y += ANIM_STEP; |
from->y += step; |
if (from->y > to->y) from->y = to->y; |
} |
else if (from->y > to->y) |
{ |
from->y -= ANIM_STEP; |
from->y -= step; |
if (from->y < to->y) from->y = to->y; |
} |