⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tetris.c

📁 SEAL是DOS 下的32位保护模式的GUI程序
💻 C
字号:
/******************************************************************
 * SEAL 2.0                                                       *
 * Copyright (c) 1999-2002 SEAL Developers. All Rights Reserved.  *
 *                                                                *
 * Web site: http://sealsystem.sourceforge.net/                   *
 * E-mail (current maintainer): orudge@users.sourceforge.net      *
 ******************************************************************/

/*
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/* SEAL Tetris 1.0
 * By Callum Lawson <callum@pmad.net>
 */

/* Revision History (as of 04/04/2002):
 *
 * 04/04/2002: Updated with new icon (orudge)
 */

#include <seal.h>
#include <menus.h>
#include <app.h>
#include <button.h>
#include <dialogs.h>
#include <iodlg.h>
#include "tetris.h"

SetInfoAppName("Tetris");
SetInfoDesciption("A very famous game!");
SetInfoCopyright("(c) Copyright 2001 SealSystem. All rights reserved");
SetInfoManufacturer("Callum Lawson");

#define MSG_GAMEOVER	100002


char figures[19][4][4]=
{{"X...",
  "X...",
  "X...",
  "X..."},
 {"XXXX",
  "....",
  "....",
  "...."},
 {"XXX.",
  "X...",
  "....",
  "...."},
 {"X...",
  "X...",
  "XX..",
  "...."},
 {"..X.",
  "XXX.",
  "....",
  "...."},
 {"XX..",
  ".X..",
  ".X..",
  "...."},
 {"XXX.",
  "..X.",
  "....",
  "...."},
 {"XX..",
  "X...",
  "X...",
  "...."},
 {"X...",
  "XXX.",
  "....",
  "...."},
 {".X..",
  ".X..",
  "XX..",
  "...."},
 {".X..",
  "XXX.",
  "....",
  "...."},
 {".X..",
  "XX..",
  ".X..",
  "...."},
 {"XXX.",
  ".X..",
  "....",
  "...."},
 {"X...",
  "XX..",
  "X...",
  "...."},
 {"X...",
  "XX..",
  ".X..",
  "...."},
 {".XX.",
  "XX..",
  "....",
  "...."},
 {".X..",
  "XX..",
  "X...",
  "...."},
 {"XX..",
  ".XX.",
  "....",
  "...."},
 {"XX..",
  "XX..",
  "....",
  "...."}};

int shift[19]={1,0,3,4,5,2,7,8,9,6,11,12,13,10,15,14,17,16,18};

int pot2[8]={128,64,32,16,8,4,2,1};

int board[10][15];
int ax,ay,akt,n;

l_bool isvalid (int x, int y, int shape)
{
 int i,j;
 for (i=0;i<4;i++)
  for (j=0;j<4;j++)
   if((figures[shape][i][j]=='X')&&((i+x>=10)||(j+y>=15)))
    return false;
 for (i=0;i<4;i++)
  for (j=0;j<4;j++)
   if((i+x<10)&&(j+y<15)&&(figures[shape][i][j]=='X')&&(board[i+x][j+y]!=0))
    return false;
 return true;
};

void tetris_draw (p_view o)
{
  t_rect  r = o->get_local_extent(o);
  t_point p;
  BITMAP *out = o->begin_paint(o, &p, r);
  void pr (int x, int y)
   {
    rectfill (out,p.x+10+20*(x-1),p.y+10+20*(y-1),p.x+8+20*x,p.y+8+20*y,makecol(191,31,0));
   };
  if ( out ) {
  int i,j;
  rectfill (out,p.x+r.a.x,p.y+r.a.y,p.x+r.b.x,p.y+r.b.y,COLOR(CO_BLUE));
  for (i=1;i<=10;i++)
   for (j=1;j<=15;j++)
    if(board[i-1][j-1]!=0)
     pr(i,j);
  };
  o->end_of_paint(o, r);
};

void ins (int shape, int x, int y)
{
 int i,j;
 for (i=0;i<4;i++)
  for (j=0;j<4;j++)
   if(figures[akt][i][j]=='X')
    board[x+i][y+j]=1;
};

void del (int shape, int x, int y)
{
 int i,j;
 for (i=0;i<4;i++)
  for (j=0;j<4;j++)
   if(figures[akt][i][j]=='X')
    board[x+i][y+j]=0;
};

l_bool full(int j)
{
 int i;
 for(i=0;i<10;i++)
  if(board[i][j]!=1) return false;
 return true;
}

void kasuj(void)
{
 int i,j,k;
 for (j=0;j<15;j++)
  if(full(j))
   for(k=j;k>0;k--)
    for(i=0;i<10;i++)
     board[i][k]=board[i][k-1];
}

l_bool gameover(void)
{
 int i;
 for(i=0;i<19;i++)
  if(!isvalid(0,0,i)) return true;
 return false;
}

static void callback (p_object s)
{
 n++; if(n==5)n=0;
 ins(akt,ax,ay);
 VIEW(s)->draw_view(VIEW(s));
 del(akt,ax,ay);
 if(n==0){
 if(isvalid(ax,ay+1,akt))
  {ay++;}
 else
  {ins(akt,ax,ay);ay=0;ax=0;akt=random()%19;
   if(gameover())
    {
 /* hang Seal trying to pass the close event to the application...
    to be fixed */
     p_event ev;
     clear_event(ev);
     set_event(ev, EV_MESSAGE, MSG_GAMEOVER, s);
     s->put_event(s,ev);
     clear_event(ev);
    };
  };
 kasuj();
 }
}

p_view tetris_init (p_view o, t_rect r)
{
 if ( !o ) return NULL;

 view_init(o, r);

 OBJECT(o)->process_tick = 50;
 OBJECT(o)->func_callback = &callback;

 o->draw = &tetris_draw;

 OBJECT(o)->set_options(OBJECT(o), OB_OF_SELECTABLE+OB_OF_ENABLE, false);
 OBJECT(o)->set_options(OBJECT(o), OB_OF_STILLPROCESS, true);

 VIEW(o)->brush.color = COLOR(CO_BLACK);

 return o;
};

static p_menu tetris_menu_init(void)
{
 p_menu menu = new_menu(
                new_sub_menu("Game",new_menu(
                  new_menu_item("About...", "", 0, MSG_ABOUT, NULL,
 			new_menu_item("Quit", "ALT+F4", TO_ALT(KB_F4), MSG_QUIT, NULL,
                NULL))),
               NULL));
 return menu;
}

void trans_ev (p_object o, p_event event)
{
 if (event->type & EV_KEYBOARD) {
  if (OBJECT(keyb)->state & KB_SF_KEYDOWN) {
   switch (KEY_TO(keyb->code)) {
    case KB_RIGHT:
     if(isvalid(ax+1,ay,akt)) ax++;
     clear_event(event);
     break;
    case KB_LEFT:
     if(isvalid(ax-1,ay,akt)) ax--;
     clear_event(event);
     break;
    case KB_UP:
     if(isvalid(ax,ay,shift[akt])) akt=shift[akt];
     clear_event(event);
     break;
    case KB_DOWN:
     if(isvalid(ax,ay+1,akt)) ay++;
     clear_event(event);
     break;
   }
  }
 }

 if (event->type == EV_MESSAGE) {
    switch (event->message) {
      case MSG_ABOUT: {
//         msgbox(MW_INFO, MB_OK, "         SEAL Tetris Game 2.0 for SEAL\n           by Callum Lawson <callum@pmad.net>\n\n       Copyright(c) SealSystem 2001\n            All Rights Reserved.\n\nThe simple game of Tetris!");
         seal2_app_about("Tetris", load_image("/system/bmp/tetris.ico,32"));
         clear_event(event);
       } break;

       case MSG_GAMEOVER: {
         p_event ev;
         msgbox(MW_INFO, MB_OK, "Game Over!");
         clear_event(ev);
         set_event(ev, EV_MESSAGE, MSG_CLOSE, o);
         o->put_event(o, ev);
         clear_event(ev);
       } break;

    }
  }

}

void welc_draw (p_view o)
{
  t_rect  r = o->get_local_extent(o);
  t_point p;

  BITMAP *out = o->begin_paint(o, &p, r);

  if ( out ) {
   int x,y,o; unsigned char c,d;
   o=0;
   for(y=0;y<85;y++)
    for(x=0;x<21;x++)
     {d=picture[o++];
      for(c=0;c<8;c++)
       if(d>=pot2[c]){d=d-pot2[c]; putpixel(out,p.x+8*x+c+20,p.y+y+10,COLOR(CO_BLACK));};
     };
  };

  o->end_of_paint(o, r);

};

p_view init_welcome(p_view o, t_rect r)
{
 if (!o) return NULL;
 view_init(o, r);
 o->draw = &welc_draw;
 return o;
};

p_object get_button(t_rect r, l_text str, l_dword msg, l_int flags)
{
 p_button  o = button_init(_malloc(sizeof(t_button)),r,str,msg,flags);
 return OBJECT(o);
}

void tetris_init_window (void)
{
 p_menuview menu;
 p_window hi;
 t_rect r,t;
 p_appwin w;
 int i,j;

 menu = NULL;

 r = rect_assign(200, 200, 400, 340);
 hi = win_init(malloc(sizeof(t_window)),r,TXT_WELCOME,0);
 r = VIEW(hi)->size_limits(VIEW(hi));
 r = rect_assign(r.a.x,r.a.y,r.b.x,r.b.y-20);
 OBJECT(hi)->insert(OBJECT(hi),OBJECT(init_welcome(_malloc(sizeof(t_view)),r)));
 r = VIEW(hi)->size_limits(VIEW(hi));
 r = rect_assign(r.a.x+50,r.b.y-19,r.b.x-50,r.b.y);
 OBJECT(hi)->insert(OBJECT(hi),get_button(r,"Start",MSG_CLOSE,BF_NORMAL));
 desktop->execute_view(desktop,VIEW(hi));

 r = rect_assign(100, 100, 330, 465);
 t = r;
 w = appwin_init(malloc(sizeof(t_appwin)),
                          r,
                          "Seal Tetris",
                          0,
                          ap_id,
                          &trans_ev);

 w->icon16 = load_image("/system/bmp/tetris.ico,16");

 for (i=0;i<10;i++)
  for (j=0;j<15;j++)
   board[i][j]=0;
 akt = random()%19; ax=0; ay=0; n=0;
 ins(akt,ax,ay);
 OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(w));
 r = VIEW(w)->size_limits(VIEW(w));
 r = rect_assign(r.a.x,r.a.y+1,r.b.x,r.a.y+20);
 menu = hormenu_init(_malloc(sizeof(t_menuview)),r,tetris_menu_init());
 OBJECT(w)->insert(OBJECT(w),OBJECT(menu));
 r = VIEW(w)->size_limits(VIEW(w));
 r = rect_assign(r.a.x,r.a.y+21,r.b.x,r.b.y);
 OBJECT(w)->insert(OBJECT(w), OBJECT(tetris_init(_malloc(sizeof(t_view)), r)));
};

app_begin (void) {
 switch(ap_process)
 {
  case AP_ALLOC:
   break;
  case AP_INIT:
   AP_SETNUMOFCALLS(1);
   tetris_init_window();
   break;
  case AP_FREE:
   break;
  case AP_DONE:
   break;
 }
} app_end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -