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

📄 cruel.c

📁 SEAL是DOS 下的32位保护模式的GUI程序
💻 C
字号:
/****************************************************************/
/*                                                              */
/*                          cruel.c                             */
/*                                                              */
/*              The "Cruel" card game for Seal 2                */
/*                                                              */
/*                     Copyright (c) 2002                       */
/*                      Tobias Johansson                        */
/*                    All Rights Reserved                       */
/*                                                              */
/* mail:  tobbe_snodd@hotmail.com                               */
/* web:   http://hem.passagen.se/sealfiles                      */
/*                                                              */
/* Cruel 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, or (at your option) any later version.                    */
/*                                                              */
/* Cruel 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 Cruel; see the file COPYING.  If not,     */
/* write to the Free Software Foundation, 675 Mass Ave,         */
/* Cambridge, MA 02139, USA.                                    */
/*                                                              */
/****************************************************************/


#include <seal.h>
#include <app.h>
#include <view.h>
#include <cards.h>
#include <menus.h>
#include <button.h>
#include <helpsys.h>

#define MSG_CRUEL_NEW     100001
#define MSG_CRUEL_HELP    100002
#define MSG_CARDS_ABOUT   100003
#define MSG_CRUEL_SELGAME 100004
#define MSG_DEAL_CARDS    100005


p_appwin   winMain;
p_view     vGame;
p_menuview gameMenu;

t_card deck[53];
t_card piles[16][13];     // 0-11 is the lower piles, 12-15 suite piles
l_int  piles_count[16];

l_int fromPile, curGame, wasDoubleClicked = 0;


SetInfoAppName      ("Cruel");
SetInfoDesciption   ("Simple cardgame for Seal 2.");
SetInfoCopyright    ("(c) Copyright 2001 Tobias Johansson. All rights reserved.");
SetInfoManufacturer ("Tobias Johansson");


void   redraw_win_title (void);
void   init_game        (void);
void   move_card        (l_int fPile, l_int tPile);
void   deselect_all     (void);
void   deal_cards       (void);
void   redraw_vGame     (p_view v);
void   trans_event      (p_object o, p_event event);
p_menu create_game_menu (void);



void redraw_win_title(void) {
   // Redraws the title of the window to show
   // which game is currently selected.
   if (winMain) {
      _free(WINDOW(winMain)->caption);
      WINDOW(winMain)->caption = set_format_text(NULL, "Cruel - game %d", curGame);

      TEST_SUB_VIEWS(VIEW(winMain), WINDOW(winMain)->draw_title(WINDOW(winMain)));
  };
};



void init_game(void) {
   l_int  curCard, curPile;
   l_int  curSuitePile = 12;

   fromPile = 0;
   redraw_win_title();

   for (curPile=0 ; curPile<=15 ; curPile++) piles_count[curPile] = 0;

   // Move all the aces from the deck to the suite piles
   curPile = 0;
   for (curCard=1; curCard<53 ; curCard++) {
      deck[curCard].showFace = true;
      if (cards_get_value(deck[curCard]) == 1) {
         piles[curSuitePile][0] = deck[curCard];
         piles_count[curSuitePile] = 1;
         curSuitePile++;
      } else {
         if (piles_count[curPile] == 4) curPile++;
         piles[curPile][piles_count[curPile]] = deck[curCard];
         piles_count[curPile]++;
      };
   };
};



void move_card(l_int fPile, l_int tPile) {
   piles_count[tPile]++;
   piles[tPile][piles_count[tPile]-1] = piles[fPile][piles_count[fPile]-1];
   piles_count[fPile]--;
};



void deselect_all(void) {
   l_int cp, cc;
   for (cp=0 ; cp<16 ; cp++) {
      for (cc=0 ; cc<piles_count[cp] ; cc++) {
         piles[cp][cc].selected = false;
      };
   };
   fromPile = 0;
};



void deal_cards(void) {
   l_int cp, cc, numCards = 0;
   deselect_all();
   cards_init_deck(deck);

   for (cp=0 ; cp<12 ; cp++) {
      for (cc=0 ; cc<piles_count[cp] ; cc++) {
         numCards++;
         deck[numCards] = piles[cp][cc];
         deck[numCards].showFace = true;
      };
   };

   for (cp=0 ; cp<12 ; cp++) piles_count[cp] = 0;

   cp = 0;
   cc = 1;
   while (cc<=numCards) {
      piles_count[cp]++;
      piles[cp][piles_count[cp]-1] = deck[cc];
      if (piles_count[cp] == 4 && cp+1<12) cp++;
      cc++;
   };   
};



void redraw_vGame(p_view v) {
   t_point p;
   l_int   cPile;
   t_rect  r = v->size_limits(v); 
   BITMAP  *out = v->begin_paint(v, &p, r);
   if (out) {
      // Draw green background.
      rectfill(out, p.x, p.y, p.x+600, p.y+400, COLOR(CO_GREEN));

      // Draw the four suite piles
      for (cPile=0 ; cPile<4 ; cPile++) 
         cards_blit_card(out, 
                         p.x + 30 + ((CARD_WIDTH + 15) * cPile), 
                         p.y + 12, 
                         piles[12+cPile][piles_count[12+cPile]-1]);

      for (cPile=0 ; cPile<6 ; cPile++) 
         if (piles_count[cPile])
            cards_blit_card(out, 
                            p.x + 30 + ((CARD_WIDTH + 15) * cPile), 
                            p.y + CARD_HEIGHT + 40, 
                            piles[cPile][piles_count[cPile]-1]);

      for (cPile=6 ; cPile<12 ; cPile++) 
         cards_blit_card(out, 
                         p.x + 30 + ((CARD_WIDTH + 15) * (cPile - 6)), 
                         p.y + (2 * CARD_HEIGHT) + 55, 
                         piles[cPile][piles_count[cPile]-1]);

      cards_blit_symbol(out, 
                        p.x + 460, 
                        p.y + 12, 
                        C_CIRCLE);

      textout_printf(out, v->font, -1, 
                     p.x + 462, p.y + 95, 
                     p.x + 460 + CARD_WIDTH, p.y + 120, 
                     TX_ALIGN_CENTER, COLOR(CO_BLACK), 
                     TX_NOCOLOR, 0, "DEAL");
      
   };
   v->end_of_paint(v, r);
};



void trans_event(p_object o, p_event event) {
   l_int cPile, cp, selGame;
   t_point p;
   RETVIEW(o, event);
   if (event->type & EV_MOUSE) {
      p = VIEW(vGame)->get_local_point(VIEW(vGame), mouse->where);

      if (OBJECT(mouse)->state & MO_SF_MOUSELUP) {

         if (wasDoubleClicked) {
            wasDoubleClicked = 0;
            deselect_all();
         } else

         // A "suite pile" was clicked
         if (p.x>29 && p.x<359 && p.y>12 && p.y<108) {
            cPile = (int) (p.x - 29) / (CARD_WIDTH + 15);
            cPile += 12;
            if (fromPile && (cards_get_value(piles[fromPile-1][piles_count[fromPile-1]-1]) == cards_get_value(piles[cPile][piles_count[cPile]-1]) + 1) && (cards_get_suite(piles[fromPile-1][piles_count[fromPile-1]-1]) == cards_get_suite(piles[cPile][piles_count[cPile]-1]))) {
               move_card(fromPile-1, cPile);
               deselect_all();
            } else deselect_all();
         } else

         // Another pile was clicked
         if (p.x>29 && p.x<531 && p.y>135 && p.y<343) {
            cPile = (int) (p.x - 29) / (CARD_WIDTH + 15);
            if (p.y>240) cPile+=6;

            if (fromPile && (cards_get_value(piles[fromPile-1][piles_count[fromPile-1]-1]) == cards_get_value(piles[cPile][piles_count[cPile]-1]) - 1) && (cards_get_suite(piles[fromPile-1][piles_count[fromPile-1]-1]) == cards_get_suite(piles[cPile][piles_count[cPile]-1]))) { 
               move_card(fromPile-1, cPile);
               deselect_all();
            } else if (piles_count[cPile] && !fromPile) {
               piles[cPile][piles_count[cPile]-1].selected = true;
               fromPile = cPile+1;
            } else deselect_all();
         } else

         // Deal symbol was clicked
         if (p.x>459 && p.x<531 && p.y>12 && p.y<108) {
            deal_cards();
         } else deselect_all();

         if (piles_count[12]+piles_count[13]+piles_count[14]+piles_count[15] == 52) 
            msgbox(MW_INFO, MB_OK, "Well done! You won!");

         redraw_vGame(vGame);
         clear_event(event);
      };

      if (OBJECT(mouse)->state & MO_SF_MOUSELDOUBLE) {

         // One of the twelve "play piles" was double clicked
         if (p.x>29 && p.x<531 && p.y>135 && p.y<343) {
            cPile = (int) (p.x - 29) / (CARD_WIDTH + 15);
            if (p.y>240) cPile+=6;
            for (cp=12 ; cp<16 ; cp++) {
               if (piles_count[cPile] && (cards_get_value(piles[cPile][piles_count[cPile]-1]) == cards_get_value(piles[cp][piles_count[cp]-1]) + 1) && cards_get_suite(piles[cp][piles_count[cp]-1]) == cards_get_suite(piles[cPile][piles_count[cPile]-1])) {
                  move_card(cPile, cp);
               };               
            };
         };
         wasDoubleClicked = 1;
         deselect_all();
         redraw_vGame(vGame);
         clear_event(event);
      };
   }; 

   if (event->type == EV_MESSAGE) {
      switch (event->message) {
         case MSG_DEAL_CARDS: {
            deal_cards();
            redraw_vGame(vGame);
            clear_event(event);
         }; break;
         case MSG_CLOSE: {
            cards_uninit_deck();
         }; break;
         case MSG_CRUEL_SELGAME: {
            cards_init_deck(deck);
            selGame = cards_game_select(curGame);
            if (selGame) {
               curGame = selGame;
               cards_shuffle_deck_select(deck, curGame);
               init_game();
               redraw_win_title();
            };
            redraw_vGame(vGame);
            clear_event(event);
         }; break;
         case MSG_CRUEL_NEW: {
            cards_init_deck(deck);
            curGame = cards_shuffle_deck_ex(deck);
            init_game();
            redraw_vGame(vGame);
            clear_event(event);
         }; break;
         case MSG_CRUEL_HELP: {
            open_help("./help/cruel.hlp");
            clear_event(event);
         }; break;
         case MSG_ABOUT: {
            msgbox(MW_INFO, MB_OK, "\"Cruel\" cardgame for Seal 2\n\n(c) 2002 Tobias Johansson\n\nEmail:   tobbe_snodd@hotmail.com\nWeb:   http://hem.passagen.se/sealfiles\n");
            clear_event(event);
         }; break;
         case MSG_CARDS_ABOUT: {
            cards_about();
            clear_event(event);
         }; break;
      };
   };
};



p_menu create_game_menu(void) {
   p_menu menu;
   menu = new_menu(
                 new_sub_menu("Game", new_menu(
                    new_menu_item("Random game", "", 0, MSG_CRUEL_NEW, NULL,
                    new_menu_item("Select game", "", 0, MSG_CRUEL_SELGAME, NULL,
                    new_menu_line(
                    new_menu_item("Exit", "ALT+F4", 0, MSG_CLOSE, NULL, 
                    NULL))))),
                 new_sub_menu("Help", new_menu(
                    new_menu_item("Help", "", 0, MSG_CRUEL_HELP, NULL,
                    new_menu_line(
                    new_menu_item("About Cruel", "", 0, MSG_ABOUT, NULL, 
                    new_menu_item("About \"cards.xdl\"", "", 0, MSG_CARDS_ABOUT, NULL, 
                    NULL))))), 
                 NULL))
              );
   return menu;
};



void create_window(void) {
  t_rect r;
  winMain = appwin_init(_malloc(sizeof(t_appwin)), 
                        rect_assign(0, 0, 570, 415), 
                        "Cruel", 
                        WF_MINIMIZE|WF_ABOUT|WF_SYSMENU, 
                        ap_id, &trans_event);
  if (winMain) VIEW(winMain)->align |= TX_ALIGN_CENTER;
  winMain->icon16 = load_image("bmp/cruel.ico,16");
  OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(winMain));

  r = VIEW(winMain)->size_limits(VIEW(winMain));
  gameMenu = hormenu_init(_malloc(sizeof(t_menuview)), 
                          rect_assign(r.a.x, r.a.y + 1, r.a.x, r.a.y + 20), 
                          create_game_menu());
  OBJECT(winMain)->insert(OBJECT(winMain), OBJECT(gameMenu));

  vGame = view_init(_malloc(sizeof(t_view)),
                    rect_assign(3, 45, 565, 410));
  VIEW(vGame)->draw = &redraw_vGame;
  OBJECT(winMain)->insert(OBJECT(winMain), OBJECT(vGame));

};



app_begin(void) {
   if (ap_process == AP_INIT) {
      cards_init_deck(deck);
      curGame = cards_shuffle_deck_ex(deck);
      init_game();
      create_window();
      redraw_win_title();
   };
} app_end;

⌨️ 快捷键说明

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