mahjongg.c 3.5 KB

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