PageRenderTime 59ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/CS/migrated/tags/R0_16_001/plugins/csstdldr/stdparse.y

#
Happy | 1116 lines | 1006 code | 110 blank | 0 comment | 0 complexity | 3ba65885405efc3c64d2703a3ef5ca41 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. The Crystal Space world file parser definition
  3. Copyright (C) 2000 by Andrew Zabolotny <bit@eltech.ru>
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. %{ /* Startup C++ code */
  17. #include "cssysdef.h"
  18. #include "stdldr.h"
  19. #include "csutil/cscolor.h"
  20. #include "csgeom/math2d.h"
  21. #include "csgeom/math3d.h"
  22. #include "iworld.h"
  23. #include "itxtmgr.h"
  24. #include "isector.h"
  25. #include "ipolyset.h"
  26. #include "ipolygon.h"
  27. #include "ithing.h"
  28. /* Define this to debug parser */
  29. //#define YYDEBUG 1
  30. /* yyparse is a member function */
  31. #define yyparse csStandardLoader::yyparse
  32. /* Provide detailed info about parse errors */
  33. #define YYERROR_VERBOSE 1
  34. /* Avoid some "signed vs unsigned comparison" warnings */
  35. #define sizeof (int)sizeof
  36. // Macros for accessing yylval as different data types
  37. #define CSCOLOR(x) (*(csColor *)&x)
  38. #define CSVECTOR2(x) (*(csVector2 *)&x)
  39. #define CSVECTOR3(x) (*(csVector3 *)&x)
  40. #define CSMATRIX3(x) (*(csMatrix3 *)&x)
  41. // More shortcuts
  42. #define TEX storage.tex
  43. #define CAMERA storage.camera
  44. #define PLANE storage.plane
  45. #define SECTOR storage.sector
  46. #define ABORTMSG \
  47. { yyerror ("loading error, aborting"); YYABORT; }
  48. #define YYERROR_EXTENDED(msg) \
  49. if (yychar == STRING) \
  50. { \
  51. msg = (char *) realloc(msg, size += 14 + strlen (yylval.string)); \
  52. sprintf (strchr (msg, 0), " (value = `%s')", yylval.string); \
  53. } \
  54. else if (yychar == NUMBER) \
  55. { \
  56. msg = (char *) realloc(msg, size += 14 + 20); \
  57. sprintf (strchr (msg, 0), " (value = `%g')", yylval.fval); \
  58. }
  59. %} /* Definition for all tokens */
  60. /* Tell Bison to build a table with all token names */
  61. %token_table
  62. /* We want a re-enterant parser */
  63. %pure_parser
  64. /* Define the top-level non-terminal symbol */
  65. %start input
  66. /* Possible values for tokens returned by yylex()
  67. * NOTE: We can't use csColor or csVector3 inside the union since classes
  68. * with constructors are not allowed there. However, if we carefully place
  69. * structure members, we can typecast our union to either of the above
  70. * types (see macros above)
  71. */
  72. %union
  73. {
  74. // Just a number
  75. float fval;
  76. // A integer number
  77. int ival;
  78. // A boolean value
  79. bool bval;
  80. // A string value
  81. char *string;
  82. // A color
  83. csPColor color;
  84. // A 2D point
  85. csPVector2 vect2;
  86. // A 3D point
  87. csPVector3 vect;
  88. // A transformation matrix
  89. csMatrix3 *matrix;
  90. // A transformation matrix/vector
  91. csStandardLoader::yystorage *transform;
  92. }
  93. /*
  94. Terminal symbols -- keywords
  95. The alphabetical order of these is not crucial, but doing so will
  96. cause less initialization work on the parser (during startup the
  97. list of keywords is QuickSort'ed). Thus it is still advisable to
  98. store them in alphabetical order here.
  99. WARNING: Max 256-3 tokens are allowed. More tokens would require
  100. slight changes to tokenizer. Currently only 130 are used.
  101. */
  102. %token KW_ACTION
  103. %token KW_ACTIVATE
  104. %token KW_ADD
  105. %token KW_ALPHA
  106. %token KW_ATTENUATION
  107. %token KW_BEZIER
  108. %token KW_CAMERA
  109. %token KW_CENTER
  110. %token KW_CIRCLE
  111. %token KW_CLIP
  112. %token KW_COLLECTION
  113. %token KW_COLOR
  114. %token KW_COLORS
  115. %token KW_CONVEX
  116. %token KW_COPY
  117. %token KW_COSFACT
  118. %token KW_CURVECENTER
  119. %token KW_CURVECONTROL
  120. %token KW_CURVESCALE
  121. %token KW_DETAIL
  122. %token KW_DITHER
  123. %token KW_DYNAMIC
  124. %token KW_F
  125. %token KW_FILE
  126. %token KW_FIRST
  127. %token KW_FIRST_LEN
  128. %token KW_FLATCOL
  129. %token KW_FOG
  130. %token KW_FOR_2D
  131. %token KW_FOR_3D
  132. %token KW_FORWARD
  133. %token KW_FRAME
  134. %token KW_GOURAUD
  135. %token KW_HALO
  136. %token KW_HEIGHTMAP
  137. %token KW_IDENTITY
  138. %token KW_KEY
  139. %token KW_KEYCOLOR
  140. %token KW_LEN
  141. %token KW_LIBRARY
  142. %token KW_LIGHT
  143. %token KW_LIGHTING
  144. %token KW_LIMB
  145. %token KW_MATRIX
  146. %token KW_MERGE_NORMALS
  147. %token KW_MERGE_TEXELS
  148. %token KW_MERGE_VERTICES
  149. %token KW_MIPMAP
  150. %token KW_MIRROR
  151. %token KW_MIXMODE
  152. %token KW_MOVE
  153. %token KW_MOVEABLE
  154. %token KW_MULTIPLY
  155. %token KW_MULTIPLY2
  156. %token KW_NODE
  157. %token KW_ORIG
  158. %token KW_PLANE
  159. %token KW_POLYGON
  160. %token KW_PORTAL
  161. %token KW_POSITION
  162. %token KW_RADIUS
  163. %token KW_ROT
  164. %token KW_ROT_X
  165. %token KW_ROT_Y
  166. %token KW_ROT_Z
  167. %token KW_SCALE
  168. %token KW_SCALE_X
  169. %token KW_SCALE_Y
  170. %token KW_SCALE_Z
  171. %token KW_SCRIPT
  172. %token KW_SECOND
  173. %token KW_SECOND_LEN
  174. %token KW_SECTOR
  175. %token KW_SKELETON
  176. %token KW_SKYDOME
  177. %token KW_SOUND
  178. %token KW_SOUNDS
  179. %token KW_SPRITE
  180. %token KW_SPRITE2D
  181. %token KW_START
  182. %token KW_STATBSP
  183. %token KW_STATIC
  184. %token KW_TEMPLATE
  185. %token KW_TERRAIN
  186. %token KW_TEX
  187. %token KW_TEXLEN
  188. %token KW_TEXNR
  189. %token KW_TEXTURE
  190. %token KW_TEXTURES
  191. %token KW_TEXTURE_LIGHTING
  192. %token KW_TEXTURE_MIPMAP
  193. %token KW_TEXTURE_SCALE
  194. %token KW_TEX_SET
  195. %token KW_TEX_SET_SELECT
  196. %token KW_THING
  197. %token KW_TRANSFORM
  198. %token KW_TRANSPARENT
  199. %token KW_TRIANGLE
  200. %token KW_TRIGGER
  201. %token KW_UPWARD
  202. %token KW_UV
  203. %token KW_UVA
  204. %token KW_UVEC
  205. %token KW_UV_SHIFT
  206. %token KW_V
  207. %token KW_VERTEX
  208. %token KW_VERTICES
  209. %token KW_VVEC
  210. %token KW_W
  211. %token KW_WARP
  212. %token KW_WORLD
  213. /* yes/no tokens */
  214. %token KW_yes
  215. %token KW_no
  216. /* light attenuation tokens */
  217. %token KW_none
  218. %token KW_linear
  219. %token KW_inverse
  220. %token KW_realistic
  221. /* This should be the last keyword.
  222. * It is used to check the version of tokenized binary files
  223. */
  224. %token PARSER_VERSION
  225. /* Terminal symbols not recognized as keywords by yylex() */
  226. %token <string> STRING /* A string ('string' or without quotes) */
  227. %token <fval> NUMBER /* A floating-point number */
  228. /* Non-terminal symbol types */
  229. %type <string> name
  230. %type <ival> yesno
  231. %type <color> color
  232. %type <vect> vect_idx
  233. %type <vect> vector
  234. %type <vect2> vector2
  235. %type <matrix> matrix
  236. %type <transform> move
  237. %% /* Grammar */
  238. /*-- Input stream ------------------------------------------------------------*/
  239. input:
  240. KW_WORLD name '('
  241. { world->SelectLibrary (storage.cur_library = $2); }
  242. world_ops ')'
  243. | KW_LIBRARY name '('
  244. { world->SelectLibrary (storage.cur_library = $2); }
  245. world_ops ')'
  246. ;
  247. /*-- Grammar -----------------------------------------------------------------*/
  248. world_ops:
  249. /* empty world */
  250. | world_ops world_op
  251. ;
  252. world_op:
  253. KW_TEXTURES '(' textures ')'
  254. | KW_TEX_SET name '('
  255. { storage.tex_prefix = $2; }
  256. textures ')'
  257. { storage.tex_prefix = NULL; }
  258. | KW_LIBRARY '(' STRING ')'
  259. { if (!RecursiveLoad ($3)) YYABORT; }
  260. | KW_SOUNDS '(' sounds ')'
  261. { printf ("SOUNDS\n"); }
  262. | KW_START '(' STRING ',' vector ')'
  263. {
  264. if (!world->CreateCamera ("Start", $3,
  265. (csVector3 &)$5, csVector3 (0, 0, 1), csVector3 (0, 1, 0)))
  266. YYABORT;
  267. }
  268. | KW_CAMERA name '('
  269. { InitCamera ($2); }
  270. camera_ops ')'
  271. { if (!CreateCamera ()) YYABORT; }
  272. | KW_PLANE name '('
  273. {
  274. PLANE.mode = pmNONE;
  275. polygon.first_len = polygon.second_len = 0.0;
  276. }
  277. plane_ops ')'
  278. { if (!CreatePlane ($2)) YYABORT; }
  279. | KW_SECTOR name '('
  280. {
  281. SECTOR.object = world->CreateSector ($2);
  282. SECTOR.polyset = QUERY_INTERFACE (SECTOR.object, iPolygonSet);
  283. if (!SECTOR.polyset)
  284. {
  285. SECTOR.object->DecRef ();
  286. yyerror ("engine created an invalid iSector object!");
  287. YYABORT;
  288. }
  289. SECTOR.texname = NULL;
  290. SECTOR.texlen = 1.0;
  291. SECTOR.statbsp = false;
  292. }
  293. sector_ops ')'
  294. {
  295. SECTOR.polyset->CompressVertices ();
  296. if (SECTOR.statbsp) SECTOR.object->CreateBSP ();
  297. SECTOR.polyset->DecRef ();
  298. SECTOR.object->DecRef ();
  299. }
  300. | KW_KEY STRING '(' STRING ')'
  301. { if (!world->CreateKey ($2, $4)) ABORTMSG; }
  302. | KW_COLLECTION name '(' collection_ops ')'
  303. { printf ("COLLECTION [%s]\n", $2); }
  304. | KW_SCRIPT name '(' STRING ':' STRING ')'
  305. { printf ("SCRIPT '%s' (%s: %s)\n", $2, $4, $6); }
  306. | KW_THING name '(' thing_tpl_ops ')'
  307. { printf ("THING_tpl [%s]\n", $2); }
  308. | KW_SPRITE name '(' sprite_tpl_ops ')'
  309. { printf ("SPRITE [%s]\n", $2); }
  310. ;
  311. /*--------*/
  312. textures:
  313. /* empty */
  314. | textures texture
  315. ;
  316. texture:
  317. KW_TEXTURE name '('
  318. { InitTexture ($2); }
  319. texture_ops ')'
  320. { if (!CreateTexture ()) ABORTMSG; }
  321. ;
  322. texture_ops:
  323. /* empty */
  324. | texture_ops texture_op
  325. ;
  326. texture_op:
  327. KW_MIPMAP '(' yesno ')' { printf ("MIPMAP (%d)\n", $3); }
  328. {
  329. if ($3)
  330. TEX.flags = (TEX.flags & ~CS_TEXTURE_NOMIPMAPS);
  331. else
  332. TEX.flags |= CS_TEXTURE_NOMIPMAPS;
  333. }
  334. | KW_DITHER '(' yesno ')'
  335. {
  336. if ($3)
  337. TEX.flags |= CS_TEXTURE_DITHER;
  338. else
  339. TEX.flags = (TEX.flags & ~CS_TEXTURE_DITHER);
  340. }
  341. | KW_FILE '(' STRING ')'
  342. { TEX.filename = $3; }
  343. | KW_TRANSPARENT '(' color ')'
  344. { TEX.transp = $3; TEX.do_transp = true; }
  345. | KW_FOR_3D '(' yesno ')'
  346. {
  347. if ($3)
  348. TEX.flags |= CS_TEXTURE_3D;
  349. else
  350. TEX.flags = (TEX.flags & ~CS_TEXTURE_3D);
  351. }
  352. | KW_FOR_2D '(' yesno ')'
  353. {
  354. if ($3)
  355. TEX.flags |= CS_TEXTURE_2D;
  356. else
  357. TEX.flags = (TEX.flags & ~CS_TEXTURE_2D);
  358. }
  359. ;
  360. /*--------*/
  361. sounds:
  362. /* empty */
  363. | sounds sound
  364. ;
  365. sound:
  366. KW_SOUND name '(' sound_ops ')'
  367. ;
  368. sound_ops:
  369. /* empty */
  370. | sound_ops sound_op
  371. ;
  372. sound_op:
  373. KW_FILE '(' STRING ')' { printf ("FILE (%s)\n", $3); }
  374. ;
  375. /*--------*/
  376. sector_ops:
  377. sector_op
  378. | sector_ops sector_op
  379. ;
  380. sector_op:
  381. KW_VERTEX '(' vector ')'
  382. { SECTOR.polyset->CreateVertex (CSVECTOR3 ($3)); }
  383. | KW_POLYGON name '('
  384. {
  385. polygon.object = SECTOR.polyset->CreatePolygon ($2);
  386. polygon.texname = SECTOR.texname;
  387. polygon.texlen = SECTOR.texlen;
  388. }
  389. polygon_ops ')'
  390. {
  391. if (!CreateTexturePlane (polygon.object))
  392. { polygon.object->DecRef (); YYABORT; }
  393. polygon.object->DecRef ();
  394. }
  395. | KW_TEXNR '(' STRING ')'
  396. { SECTOR.texname = $3; }
  397. | KW_TEXLEN '(' NUMBER ')'
  398. { SECTOR.texlen = $3; }
  399. | KW_ACTIVATE '(' STRING ')'
  400. { printf ("ACTIVATE (%s)\n", $3); }
  401. | KW_TRIGGER '(' STRING ',' STRING ')'
  402. { printf ("TRIGGER (%s, %s)\n", $3, $5); }
  403. | KW_STATBSP noargs
  404. { SECTOR.statbsp = true; }
  405. | KW_THING name '('
  406. {
  407. thing.object = world->CreateThing ($2, SECTOR.object);
  408. thing.polyset = QUERY_INTERFACE (thing.object, iPolygonSet);
  409. if (!thing.polyset)
  410. {
  411. thing.object->DecRef ();
  412. yyerror ("engine created an invalid iThing object!");
  413. YYABORT;
  414. }
  415. thing.texname = NULL;
  416. thing.texlen = 1.0;
  417. }
  418. thing_ops ')'
  419. {
  420. thing.polyset->DecRef ();
  421. thing.object->DecRef ();
  422. }
  423. | KW_LIGHT name '(' light_ops ')'
  424. { printf ("LIGHT '%s' (...)\n", $2); }
  425. | KW_SPRITE name '(' sprite_ops ')'
  426. { printf ("SPRITE '%s' (...)\n", $2); }
  427. | KW_FOG '(' color NUMBER ')'
  428. { printf ("FOG (%g,%g,%g : %g)\n", $3.red, $3.green, $3.blue, $4); }
  429. | KW_CIRCLE '(' vector ':' vector NUMBER ')'
  430. /* <coordinate> ':' <radius> <num-verts> */
  431. { printf ("CIRCLE (...)\n"); }
  432. | KW_SKYDOME '(' skydome_ops ')'
  433. { printf ("SKYDOME (...)\n"); }
  434. | KW_KEY STRING '(' STRING ')'
  435. { if (!SECTOR.polyset->CreateKey ($2, $4)) ABORTMSG; }
  436. | KW_NODE '(' node_ops ')'
  437. { printf ("NODE (...)\n"); }
  438. ;
  439. skydome_ops:
  440. skydome_op
  441. | skydome_ops skydome_op
  442. ;
  443. skydome_op:
  444. KW_RADIUS '(' NUMBER ')'
  445. { printf ("RADIUS (%g)\n", $3); }
  446. | KW_VERTICES '(' vertex_indices ')'
  447. { printf ("VERTICES (...)\n"); }
  448. | KW_LIGHTING '(' yesno ')'
  449. { printf ("LIGHTING (%d)\n", $3); }
  450. ;
  451. vertex_indices:
  452. /* none */
  453. | vertex_indices NUMBER
  454. { }
  455. ;
  456. node_ops:
  457. node_op
  458. | node_ops node_op
  459. ;
  460. node_op:
  461. KW_POSITION '(' vector ')'
  462. { printf ("POSITION (...)\n"); }
  463. | KW_KEY '(' STRING ',' STRING ')'
  464. { printf ("KEY ('%s', '%s')\n", $3, $5); }
  465. ;
  466. /*--------*/
  467. plane_ops:
  468. plane_op
  469. | plane_ops plane_op
  470. ;
  471. plane_op:
  472. KW_ORIG '(' vect_idx ')'
  473. {
  474. PLANE.mode |= pmORIGIN;
  475. PLANE.origin.Set ($3);
  476. }
  477. | KW_FIRST '(' vect_idx ')'
  478. {
  479. PLANE.mode |= pmFIRSTSECOND;
  480. PLANE.first.Set ($3);
  481. }
  482. | KW_SECOND '(' vect_idx ')'
  483. {
  484. PLANE.mode |= pmFIRSTSECOND;
  485. PLANE.second.Set ($3);
  486. }
  487. | KW_FIRST_LEN '(' NUMBER ')'
  488. {
  489. PLANE.mode |= pmFIRSTSECOND;
  490. PLANE.first_len = $3;
  491. }
  492. | KW_SECOND_LEN '(' NUMBER ')'
  493. {
  494. PLANE.mode |= pmFIRSTSECOND;
  495. PLANE.second_len = $3;
  496. }
  497. | KW_UVEC '(' vector ')'
  498. {
  499. PLANE.mode |= pmVECTORS;
  500. PLANE.first = $3;
  501. PLANE.first_len = 1.0;
  502. }
  503. | KW_VVEC '(' vector ')'
  504. {
  505. PLANE.mode |= pmVECTORS;
  506. PLANE.second = $3;
  507. PLANE.second_len = 1.0;
  508. }
  509. | KW_MATRIX '(' matrix ')'
  510. {
  511. PLANE.mode |= pmMATRIX;
  512. PLANE.matrix.Set (*$3);
  513. }
  514. | KW_V '(' vector ')'
  515. {
  516. PLANE.mode |= pmMATRIX;
  517. PLANE.origin.Set ($3);
  518. }
  519. ;
  520. /*--------*/
  521. light_ops:
  522. light_op
  523. | light_ops light_op
  524. ;
  525. light_op:
  526. vector ':' NUMBER color NUMBER
  527. /* <pos> <radius> <color> <dynamic-flag> */
  528. { printf ("<pos> <radius> <color> <dynamic-flag>\n"); }
  529. | KW_CENTER '(' vector ')'
  530. { printf ("CENTER (...)\n"); }
  531. | KW_RADIUS '(' NUMBER ')'
  532. { printf ("RADIUS (%g)\n", $3); }
  533. | KW_DYNAMIC noargs
  534. { printf ("DYNAMIC ()\n"); }
  535. | KW_COLOR '(' color ')'
  536. { printf ("COLOR ( ... )\n"); }
  537. | KW_HALO '(' NUMBER NUMBER ')'
  538. { printf ("HALO (%g,%g)\n", $3, $4); }
  539. | KW_ATTENUATION '(' attenuation_op ')'
  540. ;
  541. attenuation_op:
  542. KW_none
  543. | KW_linear
  544. | KW_inverse
  545. | KW_realistic
  546. ;
  547. /*--------*/
  548. collection_ops:
  549. collection_op
  550. | collection_ops collection_op
  551. ;
  552. collection_op:
  553. KW_THING '(' STRING ')'
  554. { printf ("THING ('%s')\n", $3); }
  555. | KW_COLLECTION '(' STRING ')'
  556. { printf ("COLLECTION ('%s')\n", $3); }
  557. | KW_LIGHT '(' STRING ',' NUMBER ')'
  558. { printf ("LIGHT ('%s':%g)\n", $3, $5); }
  559. | KW_TRIGGER '(' STRING ',' STRING '-' '>' STRING ')'
  560. { printf ("TRIGGER ('%s', '%s' -> '%s')\n", $3, $5, $8); }
  561. | KW_SECTOR '(' STRING ')'
  562. { printf ("SECTOR ('%s')\n", $3); }
  563. ;
  564. /*--------*/
  565. thing_tpl_ops:
  566. thing_tpl_op
  567. | thing_tpl_ops thing_tpl_op
  568. ;
  569. thing_tpl_op:
  570. KW_POLYGON name '('
  571. {
  572. polygon.object = thing.polyset->CreatePolygon ($2);
  573. polygon.texname = thing.texname;
  574. polygon.texlen = thing.texlen;
  575. }
  576. polygon_ops ')'
  577. {
  578. if (!CreateTexturePlane (polygon.object))
  579. { polygon.object->DecRef (); YYABORT; }
  580. polygon.object->DecRef ();
  581. }
  582. | KW_VERTEX '(' vector ')'
  583. { thing.polyset->CreateVertex (CSVECTOR3 ($3)); }
  584. | KW_TEXNR '(' STRING ')'
  585. { thing.texname = $3; }
  586. | KW_TEXLEN '(' NUMBER ')'
  587. { thing.texlen = $3; }
  588. | KW_MOVE '(' move ')'
  589. {
  590. if ($3->matrix_valid)
  591. thing.object->SetTransform (CSMATRIX3 ($3->matrix));
  592. if ($3->vector_valid)
  593. thing.object->SetPosition (CSVECTOR3 ($3->vector));
  594. }
  595. | KW_FOG '(' color NUMBER ')'
  596. { printf ("FOG (%g,%g,%g : %g)\n", $3.red, $3.green, $3.blue, $4); }
  597. | KW_CONVEX noargs
  598. { printf ("CONVEX ()\n"); }
  599. | KW_CIRCLE '(' vector ':' vector NUMBER ')'
  600. /* <coordinate> ':' <radius> <num-verts> */
  601. { printf ("CIRCLE (...)\n"); }
  602. | KW_BEZIER name '(' bezier_ops ')'
  603. { printf ("BEZIER '%s' (...)\n", $2); }
  604. | KW_CURVECENTER '(' vector ')'
  605. { printf ("CURVECENTER (...)\n"); }
  606. | KW_CURVESCALE '(' NUMBER ')'
  607. { printf ("CURVESCALE (%g)\n", $3); }
  608. | KW_CURVECONTROL '(' vector ':' vector2 ')'
  609. { printf ("CURVECONTROL (...)\n"); }
  610. ;
  611. thing_ops:
  612. thing_op
  613. | thing_ops thing_op
  614. ;
  615. thing_op:
  616. thing_tpl_op
  617. | KW_KEY '(' STRING ',' STRING ')'
  618. { printf ("KEY ('%s', '%s')\n", $3, $5); }
  619. | KW_ACTIVATE '(' STRING ')'
  620. { printf ("ACTIVATE (%s)\n", $3); }
  621. | KW_TRIGGER '(' STRING ',' STRING ')'
  622. { printf ("TRIGGER (%s, %s)\n", $3, $5); }
  623. | KW_TEMPLATE '(' STRING ')'
  624. { printf ("TEMPLATE ('%s')\n", $3); }
  625. | KW_MOVEABLE noargs
  626. { printf ("MOVEABLE ()\n"); }
  627. | KW_TEX_SET_SELECT '(' STRING ')'
  628. { printf ("TEX_SET_SELECT ('%s')\n", $3); }
  629. | KW_FILE '(' STRING ')'
  630. { printf ("FILE ('%s')\n", $3); }
  631. ;
  632. /*--------*/
  633. bezier_ops:
  634. bezier_op
  635. | bezier_ops bezier_op
  636. ;
  637. bezier_op:
  638. KW_TEXNR '(' STRING ')'
  639. { printf ("TEXNR (%s)\n", $3); }
  640. | KW_TEXTURE '(' bezier_texture_ops ')'
  641. { printf ("TEXTURE (...)\n"); }
  642. | KW_VERTICES '(' vertex_indices ')'
  643. { printf ("VERTICES (...)\n"); }
  644. ;
  645. bezier_texture_ops:
  646. bezier_texture_op
  647. | bezier_texture_ops bezier_texture_op
  648. ;
  649. bezier_texture_op:
  650. /* unused op for now */
  651. "unused"
  652. ;
  653. /*--------*/
  654. sprite_tpl_ops:
  655. sprite_tpl_op
  656. | sprite_tpl_ops sprite_tpl_op
  657. ;
  658. sprite_tpl_op:
  659. KW_TEXNR '(' STRING ')'
  660. { printf ("TEXNR ('%s')\n", $3); }
  661. | KW_FRAME name '(' sprite_verts ')'
  662. { printf ("FRAME '%s' (...)\n", $2); }
  663. | KW_ACTION name '(' sprite_actions ')'
  664. { printf ("ACTION '%s' ( ... )\n", $2); }
  665. | KW_TRIANGLE '(' NUMBER NUMBER NUMBER ')'
  666. { printf ("TRIANGLE (%g,%g,%g)\n", $3, $4, $5); }
  667. | KW_FILE '(' STRING ')'
  668. { printf ("FILE ('%s')\n", $3); }
  669. | KW_MERGE_TEXELS '(' yesno ')'
  670. { printf ("MERGE_TEXELS (%d)\n", $3); }
  671. /*
  672. @@todo: can't really understand how it all works
  673. | KW_MERGE_NORMALS '(' <sprite-merge> ')'
  674. | KW_MERGE_VERTICES '(' <sprite-merge> ')'
  675. */
  676. /*
  677. @@todo:
  678. | <sprite-skeleton>
  679. */
  680. ;
  681. sprite_verts:
  682. /* empty */
  683. | sprite_verts sprite_vert
  684. ;
  685. sprite_vert:
  686. KW_V '(' vector ':' vector2 ')'
  687. { printf ("V (%g,%g,%g:%g,%g)\n", $3.x, $3.y, $3.z, $5.x, $5.y); }
  688. ;
  689. sprite_actions:
  690. /* empty */
  691. | sprite_actions sprite_action
  692. ;
  693. sprite_action:
  694. KW_F '(' STRING ',' NUMBER ')'
  695. { printf ("F ('%s', %g)\n", $3, $5); }
  696. ;
  697. sprite_ops:
  698. sprite_op
  699. | sprite_ops sprite_op
  700. ;
  701. sprite_op:
  702. KW_MOVE '(' move ')'
  703. { printf ("MOVE ()\n"); }
  704. | KW_TEMPLATE '(' STRING ',' STRING ')'
  705. { printf ("TEMPLATE ('%s', '%s')\n", $3, $5); }
  706. | KW_TEXNR '(' STRING ')'
  707. { printf ("TEXNR ('%s')\n", $3); }
  708. | KW_MIXMODE '(' mixmode_ops ')'
  709. { printf ("MIXMODE (...)\n"); }
  710. ;
  711. mixmode_ops:
  712. mixmode_op
  713. | mixmode_ops mixmode_op
  714. ;
  715. mixmode_op:
  716. KW_COPY noargs
  717. | KW_MULTIPLY noargs
  718. | KW_MULTIPLY2 noargs
  719. | KW_ADD noargs
  720. | KW_ALPHA '(' NUMBER ')'
  721. { printf ("ALPHA (%g)\n", $3); }
  722. | KW_TRANSPARENT noargs
  723. | KW_KEYCOLOR noargs
  724. ;
  725. /*--------*/
  726. camera_ops:
  727. /* empty */
  728. | camera_ops camera_op
  729. ;
  730. camera_op:
  731. KW_POSITION '(' vector ')'
  732. { CAMERA.pos.Set ($3); }
  733. | KW_FORWARD '(' vector ')'
  734. { CAMERA.forward.Set ($3); }
  735. | KW_UPWARD '(' vector ')'
  736. { CAMERA.upward.Set ($3); }
  737. | KW_SECTOR '(' STRING ')'
  738. { CAMERA.sector = $3; }
  739. ;
  740. /*-- General-use non-terminals -----------------------------------------------*/
  741. /*
  742. GENERAL NOTE: To minimize space occupied by pre-tokenized data,
  743. the ',' characters between numbers are removed. Thus the lists of
  744. numbers will look like "NUMBER NUMBER NUMBER" instead of (how it
  745. should be in the most obvious case) "NUMBER ',' NUMBER ',' NUMBER".
  746. */
  747. /* A name - either empty or defined */
  748. name:
  749. /* empty == no name */
  750. { $$ = NULL; }
  751. | STRING
  752. ;
  753. /* Yes or no - the result is a boolean */
  754. yesno:
  755. KW_yes
  756. { $$ = true; }
  757. | KW_no
  758. { $$ = false; }
  759. ;
  760. /* The definition of a color - red, green, blue from 0 to 1 */
  761. color:
  762. NUMBER NUMBER NUMBER
  763. { CSCOLOR ($$).Set ($1, $2, $3); }
  764. ;
  765. /* Simply a vector */
  766. vector:
  767. NUMBER NUMBER NUMBER
  768. { $$.Set ($1, $2, $3); }
  769. ;
  770. /* A vector defined either directly or using a vertex index */
  771. vect_idx:
  772. NUMBER
  773. /*@@todo*/
  774. { $$.x = $$.y = $$.z = 0; }
  775. | vector
  776. ;
  777. /* A 2D vector */
  778. vector2:
  779. NUMBER NUMBER
  780. { $$.Set ($1, $2); }
  781. ;
  782. /* A matrix: there are lots of ways to define a matrix */
  783. matrix:
  784. NUMBER NUMBER NUMBER
  785. NUMBER NUMBER NUMBER
  786. NUMBER NUMBER NUMBER /* Matrix defined by nine numbers */
  787. {
  788. $$ = &storage.matrix2;
  789. $$->Set ($1, $2, $3, $4, $5, $6, $7, $8, $9);
  790. }
  791. | NUMBER /* Uniform matrix scaler */
  792. {
  793. $$ = &storage.matrix2;
  794. $$->Set ($1, 0, 0, 0, $1, 0, 0, 0, $1);
  795. }
  796. | /* Initialize matrix to identity before starting any complex defs */
  797. {
  798. $$ = &storage.matrix2;
  799. $$->Identity ();
  800. }
  801. matrix_ops
  802. ;
  803. matrix_ops:
  804. matrix_op
  805. | matrix_ops matrix_op
  806. ;
  807. matrix_op:
  808. KW_IDENTITY noargs /* Load identity matrix */
  809. { storage.matrix2.Identity (); }
  810. | KW_ROT_X '(' NUMBER ')' /* Rotate around OX */
  811. { storage.matrix2 *= csXRotMatrix3 ($3); }
  812. | KW_ROT_Y '(' NUMBER ')' /* Rotate around OY */
  813. { storage.matrix2 *= csYRotMatrix3 ($3); }
  814. | KW_ROT_Z '(' NUMBER ')' /* Rotate around OZ */
  815. { storage.matrix2 *= csZRotMatrix3 ($3); }
  816. | KW_SCALE '(' NUMBER ')' /* Uniform matrix scaler */
  817. { storage.matrix2 *= $3; }
  818. | KW_SCALE '(' NUMBER NUMBER NUMBER ')' /* Scalers for X/Y/Z individually */
  819. { storage.matrix2 *= csMatrix3 ($3, 0, 0, 0, $4, 0, 0, 0, $5); }
  820. | KW_SCALE_X '(' NUMBER ')' /* Scale related to YOZ */
  821. { storage.matrix2 *= csXScaleMatrix3 ($3); }
  822. | KW_SCALE_Y '(' NUMBER ')' /* Scale related to XOZ */
  823. { storage.matrix2 *= csYScaleMatrix3 ($3); }
  824. | KW_SCALE_Z '(' NUMBER ')' /* Scale related to XOY */
  825. { storage.matrix2 *= csYScaleMatrix3 ($3); }
  826. ;
  827. noargs:
  828. /* No arguments */
  829. | '(' ')'
  830. ;
  831. /* MOVE ( ... ) operator (used in things/sprites/etc) */
  832. move:
  833. {
  834. $$ = &storage;
  835. $$->matrix.Identity ();
  836. $$->matrix_valid = false;
  837. $$->vector_valid = false;
  838. }
  839. move_ops
  840. ;
  841. move_ops:
  842. move_op
  843. | move_ops move_op
  844. ;
  845. move_op:
  846. KW_MATRIX '(' matrix ')'
  847. {
  848. storage.matrix = *$3;
  849. storage.matrix_valid = true;
  850. }
  851. | KW_V '(' vector ')'
  852. {
  853. storage.vector = CSVECTOR3 ($3);
  854. storage.vector_valid = true;
  855. }
  856. ;
  857. /* POLYGON 'name' ( ... ) (used in things and sectors) */
  858. polygon_ops:
  859. polygon_op
  860. | polygon_ops polygon_op
  861. ;
  862. polygon_op:
  863. KW_TEXNR '(' STRING ')'
  864. { polygon.texname = $3; }
  865. | KW_LIGHTING '(' yesno ')'
  866. { printf ("LIGHTING (%d)\n", $3); }
  867. | KW_TEXTURE '('
  868. {
  869. polygon.mode = pmNONE;
  870. polygon.first_len = polygon.second_len = polygon.texlen;
  871. }
  872. polygon_texture_ops ')'
  873. { if (!CreateTexturePlane (polygon.object)) YYABORT; }
  874. | KW_VERTICES '(' polygon_vertex_indices ')'
  875. | KW_GOURAUD noargs
  876. { printf ("GOURAUD ()\n"); }
  877. | KW_FLATCOL '(' color ')'
  878. { printf ("FLATCOL (%g,%g,%g)\n", $3.red, $3.green, $3.blue); }
  879. | KW_ALPHA '(' NUMBER ')'
  880. { printf ("ALPHA (%g)\n", $3); }
  881. | KW_UV '(' tex_coordinates ')'
  882. { printf ("UV (...)\n"); }
  883. | KW_UVA '(' uva_coordinates ')'
  884. { printf ("UVA (...)\n"); }
  885. | KW_COLORS '(' colors ')'
  886. { printf ("COLORS (...)\n"); }
  887. | KW_COSFACT '(' NUMBER ')'
  888. { printf ("COSFACT (%g)\n", $3); }
  889. | KW_CLIP noargs
  890. { printf ("CLIP ()\n"); }
  891. | KW_PORTAL '(' STRING ')'
  892. { printf ("PORTAL (%s)\n", $3); }
  893. | KW_WARP '(' warp_ops ')'
  894. { printf ("WARP (...)\n"); }
  895. ;
  896. colors:
  897. /* none */
  898. | colors color
  899. { }
  900. ;
  901. polygon_vertex_indices:
  902. /* none */
  903. | polygon_vertex_indices NUMBER
  904. { polygon.object->CreateVertex ($2); }
  905. ;
  906. tex_coordinates:
  907. /* none */
  908. | tex_coordinates NUMBER NUMBER
  909. /* <u> <v> */
  910. ;
  911. uva_coordinates:
  912. /* none */
  913. | uva_coordinates NUMBER NUMBER NUMBER
  914. /* <angle> <uva-scale> <uva-offset> */
  915. ;
  916. /* WARP ( ... ) */
  917. warp_ops:
  918. warp_op
  919. | warp_ops warp_op
  920. ;
  921. warp_op:
  922. KW_MATRIX '(' matrix ')'
  923. { printf ("MATRIX (...)\n"); }
  924. | KW_V '(' vector ')'
  925. { printf ("V (...)\n"); }
  926. | KW_W '(' vector ')'
  927. { printf ("W (...)\n"); }
  928. | KW_MIRROR noargs
  929. { printf ("MIRROR ()\n"); }
  930. | KW_STATIC noargs
  931. { printf ("STATIC ()\n"); }
  932. ;
  933. /* TEXTURE (...) */
  934. polygon_texture_ops:
  935. polygon_texture_op
  936. | polygon_texture_ops polygon_texture_op
  937. ;
  938. polygon_texture_op:
  939. KW_ORIG '(' vect_idx ')'
  940. {
  941. polygon.mode |= pmORIGIN;
  942. polygon.origin.Set ($3);
  943. }
  944. | KW_FIRST '(' vect_idx ')'
  945. {
  946. polygon.mode |= pmFIRSTSECOND;
  947. polygon.first.Set ($3);
  948. }
  949. | KW_SECOND '(' vect_idx ')'
  950. {
  951. polygon.mode |= pmFIRSTSECOND;
  952. polygon.second.Set ($3);
  953. }
  954. | KW_FIRST_LEN '(' NUMBER ')'
  955. {
  956. polygon.mode |= pmFIRSTSECOND;
  957. polygon.first_len = $3;
  958. }
  959. | KW_SECOND_LEN '(' NUMBER ')'
  960. {
  961. polygon.mode |= pmFIRSTSECOND;
  962. polygon.second_len = $3;
  963. }
  964. | KW_UVEC '(' vector ')'
  965. {
  966. polygon.mode |= pmVECTORS;
  967. polygon.first = $3;
  968. polygon.first_len = 1.0;
  969. }
  970. | KW_VVEC '(' vector ')'
  971. {
  972. polygon.mode |= pmVECTORS;
  973. polygon.second = $3;
  974. polygon.second_len = 1.0;
  975. }
  976. | KW_MATRIX '(' matrix ')'
  977. {
  978. polygon.mode |= pmMATRIX;
  979. polygon.matrix.Set (*$3);
  980. }
  981. | KW_V '(' vector ')'
  982. {
  983. polygon.mode |= pmMATRIX;
  984. polygon.origin.Set ($3);
  985. }
  986. | KW_PLANE '(' STRING ')'
  987. {
  988. polygon.mode |= pmPLANEREF;
  989. polygon.planetpl = $3;
  990. }
  991. | KW_UV_SHIFT '(' vector2 ')'
  992. { printf ("UV_SHIFT (%g, %g)\n", $3.x, $3.y); }
  993. ;
  994. %% /* End of grammar */
  995. /* On initialization, register keyword list with the C++ parser */
  996. extern int init_token_table (const char * const *yytname);
  997. struct __parser_init
  998. {
  999. __parser_init ()
  1000. {
  1001. init_token_table (yytname);
  1002. #if YYDEBUG
  1003. yydebug = 1;
  1004. #endif
  1005. }
  1006. } __parser_init_dummy;