block.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. /* Block functions and dialogs */
  22. #include "helpsys.h"
  23. #include "idput.h"
  24. #include <stdio.h>
  25. #include "error.h"
  26. #include "block.h"
  27. #include "window.h"
  28. #include "data.h"
  29. #include <_null.h>
  30. #include <dos.h>
  31. #include "idarray.h"
  32. #include "roballoc.h"
  33. //--------------------------
  34. //
  35. // ( ) Copy block
  36. // ( ) Move block
  37. // ( ) Clear block
  38. // ( ) Flip block
  39. // ( ) Mirror block
  40. // ( ) Paint block
  41. // ( ) Copy to/from overlay
  42. // ( ) Save as ANSi
  43. //
  44. // _OK_ _Cancel_
  45. //
  46. //--------------------------
  47. char bdi_types[3]={ DE_RADIO,DE_BUTTON,DE_BUTTON };
  48. char bdi_xs[3]={ 2,5,15 };
  49. char bdi_ys[3]={ 2,11,11 };
  50. char far *bdi_strs[3]={ "Copy block\nMove block\nClear block\nFlip block\n\
  51. Mirror block\nPaint block\nCopy to/from overlay\nSave as ANSi",
  52. "OK","Cancel" };
  53. int bdi_p1s[3]={ 8,0,-1 };
  54. int bdi_p2s[1]={ 20 };
  55. int block_op=0;
  56. void far *bdi_storage[1]={ &block_op };
  57. dialog bdi={
  58. 26,4,53,17,"Choose block command",3,
  59. bdi_types,
  60. bdi_xs,
  61. bdi_ys,
  62. bdi_strs,
  63. bdi_p1s,
  64. bdi_p2s,
  65. bdi_storage,0 };
  66. int block_cmd(void) {
  67. int t1;
  68. set_context(73);
  69. t1=run_dialog(&bdi,current_pg_seg);
  70. pop_context();
  71. if(t1) return -1;
  72. return block_op;
  73. }
  74. char adi_types[3]={ DE_RADIO,DE_BUTTON,DE_BUTTON };
  75. char adi_xs[3]={ 6,5,15 };
  76. char adi_ys[3]={ 4,11,11 };
  77. char far *adi_strs[3]={ "Custom Block\nCustom Floor\nText",
  78. "OK","Cancel" };
  79. int adi_p1s[3]={ 3,0,-1 };
  80. int adi_p2s[1]={ 12 };
  81. int obj_type=0;
  82. void far *adi_storage[1]={ &obj_type };
  83. dialog adi={
  84. 26,4,53,17,"Object type",3,
  85. adi_types,
  86. adi_xs,
  87. adi_ys,
  88. adi_strs,
  89. adi_p1s,
  90. adi_p2s,
  91. adi_storage,0 };
  92. int rtoo_obj_type(void) {
  93. set_context(74);
  94. if(run_dialog(&adi,current_pg_seg)) {
  95. pop_context();
  96. return -1;
  97. }
  98. pop_context();
  99. return obj_type;
  100. }
  101. char csdi_types[3]={ DE_RADIO,DE_BUTTON,DE_BUTTON };
  102. char csdi_xs[3]={ 6,5,15 };
  103. char csdi_ys[3]={ 4,11,11 };
  104. char far *csdi_strs[3]={ "MegaZeux default\nASCII set\nBlank set",
  105. "OK","Cancel" };
  106. int csdi_p1s[3]={ 3,0,-1 };
  107. int csdi_p2s[1]={ 16 };
  108. int cs_type=0;
  109. void far *csdi_storage[1]={ &cs_type };
  110. dialog csdi={
  111. 26,4,53,17,"Character set",3,
  112. csdi_types,
  113. csdi_xs,
  114. csdi_ys,
  115. csdi_strs,
  116. csdi_p1s,
  117. csdi_p2s,
  118. csdi_storage,0 };
  119. int choose_char_set(void) {
  120. set_context(75);
  121. if(run_dialog(&csdi,current_pg_seg)) {
  122. pop_context();
  123. return -1;
  124. }
  125. pop_context();
  126. return cs_type;
  127. }
  128. char ed_types[3]={ DE_INPUT,DE_BUTTON,DE_BUTTON };
  129. char ed_xs[3]={ 5,15,37 };
  130. char ed_ys[3]={ 2,4,4 };
  131. char far *ed_strs[3]={ NULL,"OK","Cancel" };
  132. int ed_p1s[3]={ FILENAME_SIZE-1,0,1 };
  133. int ed_p2s=193;
  134. void far *fe_ptr=NULL;
  135. dialog e_di={ 10,8,69,14,NULL,3,ed_types,ed_xs,ed_ys,ed_strs,ed_p1s,
  136. &ed_p2s,&fe_ptr,0 };
  137. char save_file_dialog(char far *title,char far *prompt,char far *dest) {
  138. fe_ptr=(void far *)dest;
  139. ed_strs[0]=prompt;
  140. e_di.title=title;
  141. char t1=run_dialog(&e_di,current_pg_seg);
  142. return t1;
  143. }
  144. //The ansi prefix code
  145. char ansi_pre[3]="[";
  146. //EGA colors to ANSi colors
  147. char col2ansi[8]={ 0,4,2,6,1,5,3,7 };
  148. //Mini func to output meta codes to transform color from one to another.
  149. //Curr color is the current color and dest color is the color we want.
  150. char issue_meta(unsigned char curr,unsigned char dest,FILE *fp) {
  151. int size=2;
  152. char reset=0;
  153. if(curr==dest) return 0;
  154. fwrite(ansi_pre,1,2,fp);
  155. if((curr&128)&&(!(dest&128))) reset=1;
  156. if((curr&8)&&(!(dest&8))) reset=1;
  157. if(reset) {
  158. fputc('0',fp);
  159. size++;
  160. curr=7;
  161. }
  162. if(dest&128) {
  163. if(size>2) {
  164. fputc(';',fp);
  165. size++;
  166. }
  167. fputc('5',fp);
  168. size++;
  169. }
  170. if(dest&8) {
  171. if(size>2) {
  172. fputc(';',fp);
  173. size++;
  174. }
  175. fputc('1',fp);
  176. size++;
  177. }
  178. //Bold/Blink set. Set fg
  179. if((curr&7)!=(dest&7)) {
  180. if(size>2) {
  181. fputc(';',fp);
  182. size++;
  183. }
  184. fputc('3',fp);
  185. fputc('0'+col2ansi[dest&7],fp);
  186. size+=2;
  187. }
  188. //Set bk
  189. if((curr&112)!=(dest&112)) {
  190. if(size>2) {
  191. fputc(';',fp);
  192. size++;
  193. }
  194. fputc('4',fp);
  195. fputc('0'+col2ansi[(dest&112)>>4],fp);
  196. size+=2;
  197. }
  198. //Send 'm'
  199. fputc('m',fp);
  200. return(size+1);
  201. }
  202. //Export ansi according to current view.
  203. //Only exports the actual chars if text_only is set.
  204. void export_ansi(char far *file,int x1,int y1,int x2,int y2,char text_only) {
  205. FILE *fp;
  206. int x,y,line_size;
  207. int curr_color;
  208. int col,chr;
  209. unsigned char far *vid=(unsigned char far *)MK_FP(current_pg_seg,0);
  210. fp=fopen(file,"wb");
  211. if(fp==NULL) {
  212. if(text_only) error("Error exporting text",1,24,current_pg_seg,0x1401);
  213. else error("Error exporting ANSi",1,24,current_pg_seg,0x0F01);
  214. return;
  215. }
  216. //Fix xsiz/ysiz
  217. if((x2-x1)>78) x2=x1+78;
  218. if((y2-y1)>23) y2=y1+23;
  219. //File open- Init x/y pos and color
  220. x=x1; y=y1;
  221. curr_color=7;
  222. line_size=8;
  223. if(!text_only) {
  224. fwrite(ansi_pre,1,2,fp);
  225. fwrite("0m",1,2,fp);
  226. fwrite(ansi_pre,1,2,fp);
  227. fwrite("2J",1,2,fp);
  228. }
  229. //Ready to fly! Longest meta code issuable is , or
  230. //12 characters.
  231. do {
  232. id_put(0,0,x,y,0,0,current_pg_seg);
  233. chr=vid[0]; col=vid[1];
  234. //Issue meta code
  235. if(!text_only) line_size+=issue_meta(curr_color,col,fp);
  236. curr_color=col;
  237. //Plot character- NOT if an ESC, 10, 13, 9, 8, 0, or 7. (Then use
  238. //alternates)
  239. if(chr==27) chr='-';//Alternate (ESC)
  240. else if(chr==10) chr=219;//Alternate (LF)
  241. else if(chr==13) chr=14;//Alternate (CR)
  242. else if(chr==9) chr='o';//Alternate (TAB)
  243. else if(chr==8) chr=219;//Alternate (BKSP)
  244. else if(chr==7) chr=249;//Alternate (BELL)
  245. else if(chr==0) chr=32;//Alternate (NUL)
  246. fputc(chr,fp); line_size++;
  247. //Increase x/y
  248. if((++x)>x2) {
  249. x=x1;
  250. //Issue CR/LF
  251. fputc(13,fp);
  252. fputc(10,fp);
  253. line_size=0;
  254. if((++y)>y2) break;
  255. }
  256. else {
  257. //Line too long? (Can't happen in text mode)
  258. if(line_size>230) {
  259. //Issue save/restore
  260. fwrite(ansi_pre,1,2,fp);
  261. fputc('s',fp);
  262. fputc(13,fp);
  263. fputc(10,fp);
  264. fwrite(ansi_pre,1,2,fp);
  265. fputc('u',fp);
  266. line_size=3;
  267. }
  268. }
  269. //Loop!
  270. } while(1);
  271. //Done- close
  272. issue_meta(curr_color,7,fp);
  273. fclose(fp);
  274. }
  275. char exdi_types[3]={ DE_RADIO,DE_BUTTON,DE_BUTTON };
  276. char exdi_xs[3]={ 2,5,15 };
  277. char exdi_ys[3]={ 3,11,11 };
  278. char far *exdi_strs[3]={ "Board file (MZB)\nCharacter set (CHR)\n\
  279. Ansi display (ANS)\nText file (TXT)\nPalette (PAL)\nSound effects (SFX)",
  280. "OK","Cancel" };
  281. int exdi_p1s[3]={ 6,0,-1 };
  282. int exdi_p2s[1]={ 19 };
  283. void far *exdi_storage[1]={ NULL };
  284. dialog exdi={
  285. 26,4,53,17,"Export as:",3,
  286. exdi_types,
  287. exdi_xs,
  288. exdi_ys,
  289. exdi_strs,
  290. exdi_p1s,
  291. exdi_p2s,
  292. exdi_storage,0 };
  293. int export_type(void) {
  294. int t1=0;
  295. set_context(77);
  296. exdi_storage[0]=&t1;
  297. if(run_dialog(&exdi,current_pg_seg)) {
  298. pop_context();
  299. return -1;
  300. }
  301. pop_context();
  302. return t1;
  303. }
  304. char imdi_types[3]={ DE_RADIO,DE_BUTTON,DE_BUTTON };
  305. char imdi_xs[3]={ 2,5,15 };
  306. char imdi_ys[3]={ 3,11,11 };
  307. char far *imdi_strs[3]={ "Board file (MZB)\nCharacter set (CHR)\n\
  308. Ansi display (ANS)\nWorld file (MZX)\nPalette (PAL)\nSound effects (SFX)\n\
  309. Ansi (choose pos.)",
  310. "OK","Cancel" };
  311. int imdi_p1s[3]={ 7,0,-1 };
  312. int imdi_p2s[1]={ 19 };
  313. void far *imdi_storage[1]={ NULL };
  314. dialog imdi={
  315. 26,4,53,17,"Import:",3,
  316. imdi_types,
  317. imdi_xs,
  318. imdi_ys,
  319. imdi_strs,
  320. imdi_p1s,
  321. imdi_p2s,
  322. imdi_storage,0 };
  323. int import_type(void) {
  324. int t1=0;
  325. set_context(78);
  326. imdi_storage[0]=&t1;
  327. if(run_dialog(&imdi,current_pg_seg)) {
  328. pop_context();
  329. return -1;
  330. }
  331. pop_context();
  332. return t1;
  333. }
  334. //Imports an ANSi into board as fake/block or into overlay. Starts at
  335. //UL corner. obj_type is the thing id for normal import (Text, etc.) OR
  336. //0 for overlay import. (verify overlay is on before calling this function)
  337. void import_ansi(char far *filename,char obj_type,int &curr_thing,
  338. int &curr_param,int start_x,int start_y) {
  339. int x=start_x,y=start_y,ux,color=7;
  340. int save_x=start_x,save_y=start_y,t1,t2,sym;
  341. FILE * fp;
  342. fp=fopen(filename,"rb");
  343. if(fp==NULL) {
  344. error("Error importing ANSi",1,24,current_pg_seg,0x1901);
  345. return;
  346. }
  347. do {
  348. sym=fgetc(fp);
  349. if(feof(fp)) break;
  350. //Tabs & BCKSPACE are interpreted as ANSi chars...
  351. if(sym==0x1B) {//ESC for ANSi code...
  352. sym=fgetc(fp);
  353. if(sym=='[') {//Yep.
  354. t2=-1;
  355. sym=fgetc(fp);
  356. //Save/Restore position
  357. if(sym=='s') {
  358. save_x=x;
  359. save_y=y;
  360. continue;
  361. }
  362. if(sym=='u') {
  363. x=save_x;
  364. y=save_y;
  365. continue;
  366. }
  367. //Clear line
  368. if(sym=='K') {
  369. continue;
  370. }
  371. //Move X chars in a direction
  372. if(sym=='A') {
  373. y--;
  374. if(y<start_y) y=start_y;
  375. continue;
  376. }
  377. if(sym=='B') {
  378. y++;
  379. if(y>=max_bysiz) y=max_bysiz-1;
  380. continue;
  381. }
  382. if(sym=='C') {
  383. x++;
  384. if(x>(start_x+79)) x=start_x+79;
  385. if(x>=max_bxsiz) x=max_bxsiz-1;
  386. continue;
  387. }
  388. if(sym=='D') {
  389. x--;
  390. if(x<start_x) x=start_x;
  391. continue;
  392. }
  393. if(sym=='H') {
  394. x=start_x;
  395. y=start_y;
  396. continue;
  397. }
  398. if((sym<'0')||(sym>'9')) goto print_it;
  399. //Others require a # then a code
  400. next_num:
  401. t1=0;
  402. do {
  403. t1=(t1*10)+sym-'0';
  404. sym=fgetc(fp);
  405. } while((sym>='0')&&(sym<='9'));
  406. //sym is H, m, ;, A, B, C, D, or J; t1 is #
  407. if(sym=='J') {
  408. if(t1!=2) break;
  409. x=start_x;
  410. y=start_y;
  411. continue;
  412. }
  413. if(sym=='A') {
  414. y-=t1;
  415. if(y<start_y) y=start_y;
  416. continue;
  417. }
  418. if(sym=='B') {
  419. y+=t1;
  420. if(y>=max_bysiz) y=max_bysiz-1;
  421. continue;
  422. }
  423. if(sym=='C') {
  424. x+=t1;
  425. if(x>(start_x+79)) x=start_x+79;
  426. if(x>=max_bxsiz) x=max_bxsiz-1;
  427. continue;
  428. }
  429. if(sym=='D') {
  430. x-=t1;
  431. if(x<start_x) x=start_x;
  432. continue;
  433. }
  434. if(sym=='H') {
  435. if(t2>-1) {
  436. y=start_y+t2-1;
  437. x=start_x+t1-1;
  438. }
  439. else {
  440. y=start_y+t1-1;
  441. x=start_x;
  442. }
  443. t2=-1;
  444. if(x>(start_x+79)) x=start_x+79;
  445. if(x>=max_bxsiz) x=max_bxsiz-1;
  446. if(y>=max_bysiz) y=max_bysiz-1;
  447. if(x<start_x) x=start_x;
  448. if(y<start_y) y=start_y;
  449. continue;
  450. }
  451. if(sym==';') {
  452. if(t2==-1) {
  453. t2=t1;
  454. sym=fgetc(fp);
  455. goto next_num;
  456. }
  457. }
  458. if((sym==';')||(sym=='m')) {
  459. if(t2==-1) t2=t1;
  460. next_meta:
  461. switch(t2) {
  462. case 0:
  463. color=7;
  464. break;
  465. case 1:
  466. color|=8;
  467. break;
  468. case 5:
  469. color|=128;
  470. break;
  471. case 30:
  472. color&=248;
  473. break;
  474. case 31:
  475. color=(color&248)+4;
  476. break;
  477. case 32:
  478. color=(color&248)+2;
  479. break;
  480. case 33:
  481. color=(color&248)+6;
  482. break;
  483. case 34:
  484. color=(color&248)+1;
  485. break;
  486. case 35:
  487. color=(color&248)+5;
  488. break;
  489. case 36:
  490. color=(color&248)+3;
  491. break;
  492. case 37:
  493. color=(color&248)+7;
  494. break;
  495. case 40:
  496. color&=143;
  497. break;
  498. case 41:
  499. color=(color&143)+64;
  500. break;
  501. case 42:
  502. color=(color&143)+32;
  503. break;
  504. case 43:
  505. color=(color&143)+96;
  506. break;
  507. case 44:
  508. color=(color&143)+16;
  509. break;
  510. case 45:
  511. color=(color&143)+80;
  512. break;
  513. case 46:
  514. color=(color&143)+48;
  515. break;
  516. case 47:
  517. color=(color&143)+112;
  518. break;
  519. }
  520. if((sym=='m')&&(t2==t1)) continue;
  521. else if(sym=='m') {
  522. t2=t1;
  523. goto next_meta;
  524. }
  525. t2=t1;
  526. sym=fgetc(fp);
  527. goto next_num;
  528. }
  529. }
  530. }
  531. print_it:
  532. if(sym=='\r') x=start_x;
  533. else if(sym=='\n') {
  534. if(++y>=max_bysiz) y=max_bysiz-1;
  535. }//Return
  536. else {
  537. ux=x;
  538. if(ux>=max_bxsiz) ux=max_bxsiz-1;
  539. if(obj_type>0) {
  540. //Can't overwrite player...
  541. if(level_id[ux+y*max_bxsiz]!=127) {
  542. //Check for deleting objects, possibly the current
  543. t1=level_id[ux+y*max_bxsiz];
  544. if(t1==122) {//(sensor)
  545. //Clear, copying to 0 first if param==curr
  546. if((level_param[ux+y*max_bxsiz]==curr_param)&&
  547. (curr_thing==122)) {
  548. copy_sensor(0,curr_param);
  549. curr_param=0;
  550. }
  551. clear_sensor(level_param[ux+y*max_bxsiz]);
  552. }
  553. else if((t1==123)||(t1==124)) {//(robot)
  554. //Clear, copying to 0 first if param==curr
  555. if((level_param[ux+y*max_bxsiz]==curr_param)&&
  556. ((curr_thing==123)||(curr_thing==124))) {
  557. copy_robot(0,curr_param);
  558. curr_param=0;
  559. }
  560. clear_robot(level_param[ux+y*max_bxsiz]);
  561. }
  562. else if((t1==125)||(t1==126)) {//(scroll)
  563. //Clear, copying to 0 first if param==curr
  564. if((level_param[ux+y*max_bxsiz]==curr_param)&&
  565. ((curr_thing==125)||(curr_thing==126))) {
  566. copy_scroll(0,curr_param);
  567. curr_param=0;
  568. }
  569. clear_scroll(level_param[ux+y*max_bxsiz]);
  570. }
  571. if(sym==32) id_place(ux,y,0,color,0);
  572. else id_place(ux,y,obj_type,color,sym);
  573. }
  574. }
  575. else {
  576. //Overlay
  577. overlay[ux+y*max_bxsiz]=sym;
  578. overlay_color[ux+y*max_bxsiz]=color;
  579. }
  580. if(++x>(start_x+79)) {
  581. x=start_x;
  582. if(++y>=max_bysiz) y=max_bysiz-1;
  583. }
  584. if(x>=max_bxsiz) x=max_bxsiz-1;
  585. }
  586. } while(1);
  587. fclose(fp);
  588. return;
  589. }
  590. char iadi_types[3]={ DE_RADIO,DE_BUTTON,DE_BUTTON };
  591. char iadi_xs[3]={ 6,5,15 };
  592. char iadi_ys[3]={ 4,11,11 };
  593. char far *iadi_strs[3]={ "Custom Block\nCustom Floor\nText\nOverlay",
  594. "OK","Cancel" };
  595. int iadi_p1s[3]={ 4,0,-1 };
  596. int iadi_p2s[1]={ 12 };
  597. int iao_type=0;
  598. void far *iadi_storage[1]={ &iao_type };
  599. dialog iadi={
  600. 26,4,53,17,"Import ANSi as-",3,
  601. iadi_types,
  602. iadi_xs,
  603. iadi_ys,
  604. iadi_strs,
  605. iadi_p1s,
  606. iadi_p2s,
  607. iadi_storage,0 };
  608. int import_ansi_obj_type(void) {
  609. set_context(78);
  610. if(run_dialog(&iadi,current_pg_seg)) {
  611. pop_context();
  612. return -1;
  613. }
  614. pop_context();
  615. return iao_type;
  616. }