mahjongg.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <event.h>
  5. #include <stdio.h>
  6. #include "mahjongg.h"
  7. #define MJDIR "/sys/games/lib/mahjongg/"
  8. char *Border = MJDIR "images/border.bit";
  9. char *Mask = MJDIR "images/mask.bit";
  10. char *Gameover = MJDIR "images/gameover.bit";
  11. char *deftileset= MJDIR "tilesets/default.tileset";
  12. char *defbackgr = MJDIR "backgrounds/default.bit";
  13. char *deflayout = MJDIR "layouts/default.layout";
  14. ulong defchan;
  15. int trace;
  16. char *buttons[] =
  17. {
  18. "deselect",
  19. "new",
  20. "restart",
  21. "resize",
  22. "exit",
  23. 0
  24. };
  25. Menu menu =
  26. {
  27. buttons
  28. };
  29. void
  30. usage(void)
  31. {
  32. fprint(2, "usage: %s [-cf] [-b bg] [-l layout] [-t tileset]\n", argv0);
  33. exits("usage");
  34. }
  35. Image *
  36. eallocimage(Rectangle r, int repl, uint chan, uint color)
  37. {
  38. Image *tmp;
  39. tmp = allocimage(display, r, chan, repl, color);
  40. if(tmp == nil)
  41. sysfatal("cannot allocate buffer image: %r");
  42. return tmp;
  43. }
  44. Image *
  45. eloadfile(char *path)
  46. {
  47. Image *img;
  48. int fd;
  49. fd = open(path, OREAD);
  50. if(fd < 0) {
  51. fprint(2, "cannot open image file %s: %r\n", path);
  52. exits("image");
  53. }
  54. img = readimage(display, fd, 0);
  55. if(img == nil)
  56. sysfatal("cannot load image: %r");
  57. close(fd);
  58. return img;
  59. }
  60. void
  61. allocimages(void)
  62. {
  63. Rectangle one = Rect(0, 0, 1, 1);
  64. selected = eallocimage(one, 1, RGBA32, setalpha(DPalebluegreen, 0x5f));
  65. litbrdr = eallocimage(one, 1, RGBA32, DGreen);
  66. img = eallocimage(Rect(0, 0, Sizex, Sizey), 0,
  67. defchan? defchan: screen->chan, DBlack);
  68. textcol = eallocimage(one, 1, RGBA32, DWhite);
  69. background = eloadfile(defbackgr);
  70. replclipr(background, 1, img->r);
  71. mask = eloadfile(Mask);
  72. gameover = eloadfile(Gameover);
  73. tileset = eloadfile(deftileset);
  74. }
  75. void
  76. eresized(int new)
  77. {
  78. if(new && getwindow(display, Refnone) < 0)
  79. sysfatal("can't reattach to window");
  80. drawlevel();
  81. }
  82. void
  83. main(int argc, char **argv)
  84. {
  85. int clickety = 0;
  86. Mouse m;
  87. Event e;
  88. Point origin = Pt(Bord, Bord);
  89. ARGBEGIN{
  90. case 'b':
  91. defbackgr = EARGF(usage());
  92. break;
  93. case 'c':
  94. defchan = RGBA32;
  95. break;
  96. case 'f':
  97. trace = 1;
  98. break;
  99. case 'l':
  100. deflayout = EARGF(usage());
  101. break;
  102. case 't':
  103. deftileset = EARGF(usage());
  104. break;
  105. default:
  106. usage();
  107. }ARGEND
  108. if(argc > 0)
  109. usage();
  110. if(! parse(deflayout)) {
  111. fprint(2, "usage: %s [levelfile]\n", argv[0]);
  112. exits("usage");
  113. }
  114. if(initdraw(nil, nil, "mahjongg") < 0)
  115. sysfatal("initdraw failed: %r");
  116. einit(Emouse|Ekeyboard);
  117. allocimages();
  118. /* resize to the size of the current level */
  119. resize(img->r.max);
  120. generate(time(0));
  121. drawlevel();
  122. for(;;) {
  123. if(level.remaining == 0 && !level.done)
  124. done();
  125. switch(event(&e)) {
  126. case Emouse:
  127. m = e.mouse;
  128. if(m.buttons&1) {
  129. if(level.done)
  130. break;
  131. if(!clickety && level.remaining > 0) {
  132. clickety = 1;
  133. clicked(subpt(m.xy, addpt(screen->r.min,
  134. origin)));
  135. }
  136. } else {
  137. clickety = 0;
  138. if(trace)
  139. light(subpt(m.xy, addpt(screen->r.min,
  140. origin)));
  141. }
  142. if(m.buttons&2) {
  143. /* nothing here for the moment */
  144. }
  145. if(m.buttons&4)
  146. switch(emenuhit(3, &m, &menu)) {
  147. case 0:
  148. deselect();
  149. break;
  150. case 1:
  151. generate(time(0));
  152. drawlevel();
  153. break;
  154. case 2:
  155. level = orig;
  156. drawlevel();
  157. break;
  158. case 3:
  159. resize(img->r.max);
  160. break;
  161. case 4:
  162. exits(nil);
  163. }
  164. break;
  165. case 2:
  166. switch(e.kbdc) {
  167. case 127:
  168. case 'q':
  169. case 'Q':
  170. exits(nil);
  171. case 'h':
  172. case 'H':
  173. if(!level.done)
  174. hint();
  175. break;
  176. case 'n':
  177. case 'N':
  178. /* new */
  179. generate(time(0));
  180. drawlevel();
  181. break;
  182. case 'r':
  183. case 'R':
  184. level = orig;
  185. drawlevel();
  186. break;
  187. case 'c':
  188. case 'C':
  189. if(!level.done) {
  190. clearlevel();
  191. done();
  192. }
  193. break;
  194. case 8:
  195. case 'u':
  196. case 'U':
  197. if(level.done) {
  198. level.done = 0;
  199. drawlevel();
  200. }
  201. undo();
  202. break;
  203. }
  204. break;
  205. }
  206. }
  207. }