home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !MAGS / CHOSNECK / CHOS3.ZIP / CHOSNECK.3RD / STUFF / DATAS.ZIP / ART48.SCR < prev    next >
Encoding:
Text File  |  2003-02-06  |  30.0 KB  |  581 lines

  1. <head>
  2. <title="...forever...">
  3. <font=monaco10.fnt>
  4. <font=newy36.fnt>
  5. <font=time24.fnt>
  6. <image=back.raw w=256 h=256 t=-1>
  7. <buf=9050>
  8. <bgcolor=-1>
  9. <background=0> 
  10. <link_color=000>
  11. <module=console.mod>
  12. <pal=back.pal>
  13. colors:
  14. 251 - black
  15. </head>
  16. <body>
  17. <frame x=0 y=0 w=640 h=9050 b=-1 c=-1>
  18.  
  19. -- - --- -- --------------------------------------------------------------------
  20. <f1><c000>       Making 2d and 3d games 
  21.   on Atari ST and Falcon Part #1 
  22. <f0>
  23.                              by Saulot July'2002
  24. ------------------------------------------------------------------ -- - --- ----
  25.  
  26. Special  hi  to:  Rafal  Kawecki,  Sqward, mr.Pink, Moonwalker, Grey and all the 
  27. people at #atariscne. 
  28.  
  29. *WARNING* This is not for experienced coders(or wonderful childs), so if you are 
  30. considering  yourself as one of those don't be surpised that you know everything 
  31. (Feeling lucky, punk?). 
  32.  
  33. for  comments,  corrections, greetings, money sending ;): saulot@wp.pl Ah, and I 
  34. forgot. Copying for commercial reasons prohibited! 
  35.  
  36.  
  37. 1. Introduction
  38. --------------------------------------------------------------------------------
  39. This  doc  is  intended for total beginners, but I hope that everyone interested 
  40. will  find  something.  Sometime ago I noticed that it's very hard to obtain any 
  41. good  doc  about  games programming (I  don't mention great doc made by Earx/Fun 
  42. which  is  m68k  asm  oriented.) for Atari specific hardware. The information is 
  43. scattered and it can be quite difficult to grasp for uninitiated (Lo! Grey, code 
  44. for  me a demo! Miracles are everywhere! Graphicians learn 68k assembler, coders 
  45. are  making  music and gfx, diskmag editors write programming tutorials ;)))).). 
  46. As I found myself sometime ago in similar situation I decided to make a doc that 
  47. could  help some people to make their journey easier. This doc was also inspired 
  48. by    one  polish  book  about  games  programming  which  was,  of  course,  PC 
  49. targetted (Pascal+wintel  assembler). I  liked this book alot, it contained some 
  50. good  basic ideas which could be easly ported to Atari and C language (and loads 
  51. of errors ha,ha!). 
  52.  
  53. The  tools I've chosen for writing games are: Pure C(which is ANSI standard, has 
  54. easiest  help  system in the world) and of course m68k assembly language. If you 
  55. find  the german language of Pure C help files quite difficult (as I am) you can 
  56. get an english help files by elfsoft (search elfhelp on the web). Its shareware, 
  57. revamped  reference  and it cost's a little -recommended. Pascal is too slow for 
  58. our  purposes,  the  C  language  does  a  job  a  lot better(it works nearer to 
  59. hardware,  his  little  brothers  java  and  c++  are  industry standards!). The 
  60. assembly  is  essential,  because  with  it  we will write some super-ultra fast 
  61. routines  for  extra speed. It isn't too hard to learn, it's maybe less readable 
  62. than other high level languages. I hope that this book(!?) will help someone. Of 
  63. course  text  will  be  accompanied  with  examples of programs with comments. I 
  64. really  want  to  hear  some  comments,  be it total praise or "this is piece of 
  65. shit".  Don't  be  intimidated  at first seeing BGI tutorial. This is mainly for 
  66. introductory  reasons  and  it  will be one chapter only to show some of you the 
  67. basics.  The main target is to learn writing all the needed routines by yourself 
  68. in  m68k assembler or C and incorporate it into your projects. I really have the 
  69. feeling  that  Atari's  (especially STE & FALCON) possibilities in games weren't 
  70. fully  exploited. There is also a bunch of people which are still very dedicated 
  71. to Atari computers and I have a hope that this doc will motivate someone to take 
  72. effort  and do something (I assure you that it is very nice when you are writing 
  73. programs that work :)). So gfx man, coders, musicians unite! 
  74. In these series of docs you will read:
  75. Introduction  to  programming,  using  Pure  C  and assembler, how all this work 
  76. together,  passing  parameters in assembler and C, screen modes, sound hardware, 
  77. blitter  & DSP usage, basics of 2d(bitmaps, sprites etc.) and <link=g48.scr>3d</l> graphics. And a 
  78. lot more. 
  79.  
  80. Something for totally uninitiated
  81. ---------------------------------
  82. If  you  haven't  any contact with programming languages this is a good place to 
  83. start. Let's compile our first program. So let's start! 
  84. 1) Run PC.PRG
  85. 2)  From  the  toolbar choose "File"->"Open .C". When Fileselector appears write 
  86. 1STPROGGY.C. To the window write down these lines of code and save it: 
  87.    
  88.    /* this how we write comments in C */
  89. /* here we put the header file for standard Input/Output functions */
  90. #include <stdio.h>      
  91.  
  92. void main(void)   /* this is our main program function - mandatory */
  93. {  /* beginning of main function */
  94.  
  95. printf("Blah, blah, blah, bleurgh, blurp !!!\n");
  96.  
  97. } /* end of main function */
  98.  
  99. 3)  Make  yourself  a  projectfile(to show the compiler how to make our proggy). 
  100. From  the  toolbar  "File"->"Open  .PRJ".  When  the  Fileselector appears write 
  101. 1STPROGGY.PRJ. In the window write down these lines and save it: 
  102.  
  103. 1STPROGGY.TOS  ;this how our executable program will be called
  104. =              ;equation mark is mandatory!
  105. PCSTART.O      ;this is startup object file that does all the dirty job like 
  106.                ;allocating memory for launched program etc...
  107. 1STPROGGY.C    ;our newly created .C sourcefile
  108. PCSTDLIB.LIB   ;pre compiled standard I/O libraries
  109.  
  110. Notice  few  things  if  you  start to write your own project files. Firstly you 
  111. specify  the  name of output file. Then always appears equation mark. After that 
  112. you  can  optionally  put  the functions written in assembler with .S extension. 
  113. Then  there is startup code(PCSTART.O in our case, thera are other ones but they 
  114. are  uninteresting  to  our  purposes).  After the startup code you throw in the 
  115. names  of  files  with your C source code. And finally you specify the libraries 
  116. your  code  uses.  Moreover in the project file you can use a switches. What the 
  117. hell is that? Well these are special directives given to the compiler(be it C or 
  118. m68k  one).  You  can  specify them from the tool bar, but if you want to spread 
  119. your  source  code  and  be  sure  that  it  will compile in proper way on other 
  120. machines,  then  you  should use them. You can recognize them by [] brackets and 
  121. you can turn them on with - and the letter [-C] for example. To learn more about 
  122. that read the documentation. 
  123. 4)  After  this  Project->Choose  project  and  find the 1STPROGGY.PRJ. And then 
  124. compile  the program with Project->Make all (or simply press Alt+X). And the you 
  125. can  run  it  with  Project->Make  and run. If you received something like this: 
  126.  
  127. Blah, blah, blah, bleurgh, blurp !!! 
  128.  
  129. You  should  be  happy that you have made the very first step in programming. If 
  130. there  is  something  wrong  check  everything  you  wrote  in  C  every mark is 
  131. essential! So watch out. 
  132. Making  these  project  files  in  Pure  C seems to be awful thing for the first 
  133. sight, but it comes handy the more time you will use it. 
  134.  
  135. 2. Graphics with BGI
  136. -------------------------------------------------------------------------------
  137. Our  journey with programming of graphics we will start with using BGI graphics, 
  138. which  is very simple and quick in use. The funny thing I noticed in polish book 
  139. mentioned  earlier,  that it has a whole big BGI chapter called "BGI and games". 
  140. Man  reads  this  chapter  and  reads  and after that he is informed that BGI is 
  141. worthless  $&%*@ and has nothing with doing games ha,ha! Top stuff! The term BGI 
  142. comes from "Borland Graphics Interface" and formerly it was created for creating 
  143. simple  gfx  in  DOS enviroment(awful!) with Turbo Pascal(hideous!). The Borland 
  144. company  created something about 70 graphic functions and procedures that let us 
  145. plot  some  simple  pixels,  lines  and  putting horizontally and vertically the 
  146. characters.  Hopefully  we  can use them in Pure C and can learn some basics. We 
  147. will  not use BGI graphics in our games, but this chapter can give you good idea 
  148. how things work in general. 
  149. The  method  of "stick and carrot" is a good one, so if you are writing programs 
  150. that  work well from beginning, then you are motivated to learn more and try the 
  151. harder  stuff (so, i think). If you know BGI already and you think that you know 
  152. everything  then  skip  all  of  this BGI shit. (but you have to wait awhile I'm 
  153. afraid...) 
  154.  
  155. To use BGI functions you must include two additional lines:
  156. 1) In your program the pre-compiler directive #include <graphics.h>
  157. 2) In your project file add PCBGILIB.LIB with other lib files.   
  158.  
  159. Structure of the screen
  160. -----------------------
  161. The screen in any graphics mode has a little different layout than this you know 
  162. from  the  maths  lessons. The main difference is with the Y-axis; in carthesian 
  163. one  the  Y-axis is directed upward, but on our screen is directed downward. The 
  164. other difference is that point (0,0) is situated always in the upper-left corner 
  165. of  the  screen.  Every pixel has it's own coordinates. So if we have the screen 
  166. with  resolution  of  640x480.  The  first  pixel  on  screen  will  have  (0,0) 
  167. coordinates  and the last one(in the lower-right corner of the screen) will have 
  168. (639,399) coordinates. 
  169.  
  170. Every graphics mode has it's own specific parameters. These are:
  171.  
  172. 1. Screen resolution or how many pixels can be putted on screen horizontally and 
  173. vertically. 
  174. 2. Amount of colours, sometimes given in bits(which describes colour depth). For 
  175. example gfx mode with 4 bit colour depth can give 16 different colours. Why? The 
  176. highest number you can represent with four bits is 15. To this we add the number 
  177. 0  and  we  receive 16 different colours. Everything about bits we will learn in 
  178. second part. 
  179.  
  180. Initializing of Graph module and graphics mode
  181. ----------------------------------------------
  182. As I mentioned earlier to be able to use any of the BGI routines we have to tell 
  183. to our compy that we want to use them. Firstly in the beginning we have to write 
  184. "#include  <graphics.h>"  in our source code and write PCBGILIB.LIB in our *.prj 
  185. file.  Wodda  fukk  is  dat?  -you  ask.  Well, graphics.h is a header file that 
  186. contains  information  about BGI data types, functions and values used and being 
  187. returned  by  these  functions.  The C compiler uses this info as a reference to 
  188. PCBGILIB.LIB  file,  which  contains  implementation of functions and data types 
  189. listed  in  graphics.h file translated to machine language already. Without info 
  190. provided  in header file we couldn't use any of these functions at all. You will 
  191. learn more about it when we start to write functions by ourselves. 
  192. The  situation  is  analogic  with  #include  <stdio.h>  and  #include  <ext.h>. 
  193. Declarations  of  used  header  files  in  C  source  code  and PCSTDLIB.LIB and 
  194. PCEXTLIB.LIB  in *.PRJ file. Better take look at example program 1.1(p_1_1.c and 
  195. p_1_1.prj -it should be somewhere around...). 
  196.  
  197. Next part is a declaring of used functions:
  198.  
  199. int main(void);
  200.  
  201. Function  main  is  a mandatory one -it's our program. This is not neccessary to 
  202. declare this, but in the future it becomes very important. That line informs the 
  203. C  compiler  that  we  will  be  using  function  main,  that  doesn't  need any 
  204. parameters("void"  in  the  brackets) and returns variable of integer data type. 
  205. *IMPORTANT* Notice the semicolon after the declaration, it is how the C compiler 
  206. sees the difference between declaration of function and it's implementation. 
  207. Ehm, data types? They are describing the range of values which our variable can 
  208. take. Take look at this:
  209.  
  210. --------------------------------------------------------
  211. Data type               Range
  212. --------------------------------------------------------
  213. char                  -128 to 127
  214. unsigned char            0 to 255
  215. signed char           -128 to 127
  216. int                -32 768 to 32 767
  217. unsigned int             0 to 65 535
  218. signed int         -32 768 to 32 767
  219. long        -2 147 483 648 to 2 147 483 647
  220. float             -3.4E+38 to 3.4E+38
  221. double           -1.7E+308 to 1.7E+308
  222.  
  223. Treat  this as a very rough information which doesn't include all the data types 
  224. to have general idea. 
  225.  
  226. After  a  declaration  we  must  specify our main function. We are doing it like 
  227. this: 
  228.  
  229. int main(void)
  230. {
  231. return(0);
  232. }
  233.  
  234. It is the shortest runnable C code. The implementation is similar to declaration 
  235. part,  but  we  are  throwing  out  the  semicolon and throw in {} brackets. The 
  236. brackets  tell  where the function starts and where ends(we have to put our code 
  237. somewhere!).  As  we  declared  that function main returns integer value, we are 
  238. writing return(0) which returns 0 value, which means program termination. If you 
  239. will  receive negative numbers it means that some kind of error occurred. Inside 
  240. the  program  we need variables to store some info etc.. We need to declare them 
  241. first: 
  242. int driver,mode,err=0;
  243.  
  244. In  this line we declared three variables of integer type called driver,mode and 
  245. err.  We simultanously initialized them with value of 0. Everything in one line! 
  246. We could also write this like this: 
  247.  
  248. int driver=0;
  249. int mode=0;
  250. int err=0;
  251.  
  252. Or like this:
  253.  
  254. int driver;
  255. int mode;
  256. int err;
  257.  
  258. driver=0;
  259. err=0;
  260. mode=0;
  261.  
  262. Or in another way:
  263.  
  264. int driver,mode,err;
  265. driver=0;
  266. err=0;
  267. mode=0;
  268. ********** IT'S ALL THE SAME !!!!!!! *********
  269.  
  270. !!!!! Local and Global variables !!!!!!!!!!!!
  271. The place where you declare your variables is also important. The variables that 
  272. you  declared  are visible(and you can use them) only in function where you have 
  273. declared them, they vanish after function termination and aren't visible outside 
  274. of  this  function. This sort of variables is called "local variable". It's wise 
  275. to  initialize  local variables inside of our functions with some sort of value, 
  276. because after program start they contain "trash or another garbage". So for your 
  277. own  good,  initialize  them  to  avoid  future  nerve wrecking bug hunting. The 
  278. variables  driver,mode  and  err are local variables in function main() and they 
  279. vanish after main() termination. 
  280. But  sometimes  we need variables that need to be accessed by any function. This 
  281. variables    are   called  "global"  and  are  visible  everywhere  and  can  be 
  282. accessed/changed  by every function in your program. They are declared in normal 
  283. way,  outside of function main() and needn't to be initialized, because compiler 
  284. is  zeroing  them  at each program start. But don't abuse them too much, because 
  285. they  are  stealing memory which cannot be retrieved, and could mess alot if too 
  286. many functions will manipulate them behind your back. Watch out! 
  287.  
  288. But  let's back to our source code. To initialize graphics mode we use initgraph 
  289. function, which in header file looks like this: 
  290. void initgraph( int *graphdriver, int *graphmode, char *pathtodriver );
  291.  
  292. The  function  initgraph  doesn't return any values (void before functions name) 
  293. and  uses  several  parameters.  Damned!  They  look  weird... I think I have to 
  294. stop...  Wot's dat? The "*" after the data type declaration means that this is a 
  295. pointer  to  specified data type(pointer as name tells itself points to specific 
  296. place  in memory where is our variable, it is simply speaking address of cell in 
  297. memory  where  our  variable  is  hiding).  Don't  be  fooled  the  "*"  is also 
  298. multiplication operator used by C! 
  299.  
  300. So now we must specify the graphics driver and gfx mode. We will use VDI for all 
  301. the stuff. We don't need this PC bullshit. 
  302.  driver = VDI; 
  303.   mode = VDIMODE; 
  304.   initgraph(&driver, &mode, ""); 
  305.   err = graphresult(); 
  306.   if(err) { 
  307.     puts(grapherrormsg(err)); 
  308.     return(err); 
  309.    }
  310. We declare that we want to use VDI so we assign to driver variable VDI(which has 
  311. predefined value 256. Predefining values can be handy to make your programs more 
  312. readable.  In  this  case VDI is exchanged by compiler with 256 and VDI with 0). 
  313. After that we are launching initgraph with proper parameters. But what are these 
  314. funky  "&"  before  driver  and  mode  variable?  And  what  for  are  those two 
  315. apostrophes? 
  316. The  first  thing  means that you are passing adress in memory of your variable, 
  317. not it's value.(more about it later) 
  318. The  blank  string  is  provided for compatibility purposes(BGI were ported from 
  319. PC's).  It  should  contain path to the file of the graphics driver. As we don't 
  320. need them on Atari we are leaving it blank. 
  321. Next  thing  we  do  is checking if any error occurs. The function graphresult() 
  322. does all the job for us. It returns negative number if there is something wrong. 
  323. We need to save somewhere this info and we put it in err variable. Next we check 
  324. if err variable is smaller than zero. If yes we print out the error message with 
  325. puts function. Notice that the function grapherrormsg() was used as a parameter. 
  326. It works like this: firstly grapherrormsg() is called with err as its parameter. 
  327. Grapherrormsg  returns pointer to the string which contains our desired message. 
  328. After    printing    the  message,  the  err  value  is  passed  to  our  main() 
  329. function(return(err)) and our program terminates. 
  330.  
  331. But  if  everything  is  well  initialized.  We  are setting textstyle, move our 
  332. invisible  cursor  in  the  middle  of  the  screen(getmaxx()  and getmaxy() are 
  333. returning maximal x and y resolution of the screen, dividing these values by two 
  334. we receive approximate center of the screen) 
  335. Then we print out the message. We wait for keypress, we are closing graphic mode 
  336. with closegraph() and we are passing the value returned by graphresult() , which 
  337. should be 0, to function main(). That's all. 
  338. And  now  the hint. You know why the Pure C help system is easiest in the world. 
  339. Then  mark  a  clue  word(or  something  like  that)  and  press  HELP key. It's 
  340. addictive,  fun,  quick  :).  Play  with it. But remember this help system isn't 
  341. fully idiot-proof ;). 
  342.  
  343. PIXELS (P_1_5.c)
  344. ****************
  345. As you certainly know the screen images are made with these funny, small pixels. 
  346. So let's throw some pixels on the screen. We can do that with function putpixel: 
  347. void putpixel(int x,int y,int colour); 
  348.  
  349. x  and  y are the parameters of our pixel and colour is describing the colour of 
  350. our  pixel.  We  have  16  colours in our disposal (from 0 to 15). These are two 
  351. possibilities of launching putpixel function: 
  352. putpixel(100,100,RED);
  353. putpixel(100,100,4);
  354.  
  355. The  results  are  the  same,  but in first case we use predefined constant as a 
  356. colour  and  in  second case we simply pass the numeric value of that colour. It 
  357. works  exactly  like VDI and VDIMODE in previous program(in 1.1 ha, ha! It looks 
  358. like a big hole between!). 
  359. Now  we take a loop, erm a look at using "for" loops. The "for" loop repeats one 
  360. instruction  or group of instructions specified number of times. When we want to 
  361. put several instructions in "for" loop we must put them in the brackets {}. 
  362.  
  363. for (counter=0;counter<100;counter++)
  364. printf("Programming sucks!!!!");
  365. printf("I should take a vacation from this...");
  366.  
  367. This  code  will  result  in  printing  out  to  the  screen  100 times sentence 
  368. "Programming  sucks!!!!"  and  one time "I should take a vacation from this...". 
  369. counter++ is the equal to counter=counter+1 . 
  370.  
  371. for (counter=0;counter<100;counter++)
  372. {
  373. printf("Programming sucks!!!!");
  374. printf("I should take a vacation from this...");
  375. }
  376.  
  377. But in above case we receive each sentence printed 100 times. Easy!
  378.  
  379. The  example  program P_1_5.c prints out the message, puts something 6000 pixels 
  380. in  random  coordinations of the screen, in random colours, waits for a keypress 
  381. and  quits.  Function  srand()  is  used to initialize the seed of random number 
  382. generator,  so  we  will  receive  different results on screen with each program 
  383. start. And function random(x) which generates the pseudo random number from 0 to 
  384. x-1. That's all folks! 
  385.  
  386. LINES (P_1_6.c)
  387. ***************
  388. For drawing lines we use line function:
  389. void line(int x1,int y1,int x2,int y2);
  390.  
  391. Parameters  x1,y1 are the coordinates of line's starting point and x2,y2 are the 
  392. coordinates  of  it's  end. To change the colour of the line we use the separate 
  393. function called setcolor: 
  394. void setcolor(int colour);
  395. The value colour can take range from 0 to 15 as in putpixel.
  396.  
  397. Take  look  at P_1_6.c program. It's similar to the previous one. This one draws 
  398. 3000  lines in random coordinates. After that waits for a keypress. No surprises 
  399. this time :/. 
  400.  
  401. Functions (P_1_7.c and P_1_8.c)
  402. *******************************
  403. It's  up to introduce functions to our programs. For what I need these functions 
  404. ?!  Take  look  at  program  1.7  (p_1_7.c).  Piece of cake, hum? During program 
  405. execution you are forced to write down two times following lines: 
  406.  
  407. printf("Press any key to proceed\n");
  408. getch();
  409.  
  410. So  lets  transform  it  into  function,  which  we  call press_key.(Look now to 
  411. P_1_8.c) 
  412.  
  413. As you certainly noticed our new function we must:
  414. 1)  declare  that  we  want  to  use  function  by writing if it will return any 
  415. parameters,  how  it  will be called and if it will need any parameters *before* 
  416. our  main()  block.  As  you  can  see our function press_key() doesn't need any 
  417. parameters  and  returns  no  values-  it is indicated by statement void both in 
  418. place  for  expected  parameters and in place before the name of function, which 
  419. specifies  data  type  of  function's  returned  value.  And  don't forget about 
  420. semicolon at the end! 
  421. 2) Writedown the body of the function after declaration and before main() block. 
  422. You  must  specify everything like in declaration(don't write the semicolon this 
  423. time!). In {} brackets you can put the desired code. 
  424.  
  425. Now,  remember  those  nasty PC***LIB.LIB files? So now you will be shocked. The 
  426. header  files  contain  lines  like  in  our  declaration part(they inform about 
  427. functions  we  want  to  use)  and  these  PC***LIB.LIB contain already compiled 
  428. (naked)bodies of these functions! (uh, oh give me a break!) 
  429.  
  430. It's  a  very  good  moment  to talk about giving names in C for your variables, 
  431. functions  etc. You can use upper case and lower case. Lower case and upper case 
  432. characters  are  treated  as  competely  different  so  if  you will declare int 
  433. variables  Defibrylator  and  deFibrylator,  then  they will be treated like two 
  434. different ones. The same situation is with function names. 
  435.  
  436. Functions  and  variables  *should*  be written in lower case (this is something 
  437. like  custom)  and  can  have up to 32 characters in total. So it's good idea to 
  438. give meaningful names. 
  439. For example:
  440. int a;             /* Wots dat? Wot for it iz? */
  441.  
  442. float namethatstellseverything;  /* *VERY* unreadable */
  443.  
  444. double number_of_saulots_braincells=-0.0000000001;
  445. /*Nice,  now  it's very descriptive. And even readable. Use underlines a lot not 
  446. spaces!*/ 
  447.  
  448. If  it comes about predefined constants they are all in UPPER CASE. And for most 
  449. important /* comment */ your sources well. Imagine yourself a situation when you 
  450. were testing air bags in your new car. And these air bags didn't worked, you had 
  451. a  car  crash and you lost all your memory. How can you read your programs after 
  452. that?  If you have commented them well, there will be no problem at all, if not, 
  453. sorry... Keep up this trends and you will get far! 
  454.  
  455. I also changed the declaration of main(). It doesn't return any values, so I put 
  456. another  void (void is cool word! Very SF or what? :] ). And we needn't to write 
  457. this  stupid  return(0).  Main  can  have also parameters. Do you remember those 
  458. freaky  TTP  or  GTP proggies? All the nasty things you write in commandline are 
  459. passed to main() function. 
  460.  
  461. But  we  drifted  off  from functions subject. Functions are simply speaking the 
  462. small  programs  or  consider  them  as  a  bricks  from  which  you  build your 
  463. complicated  program(game).  In the main block we used press_key() function only 
  464. two times. It was really worth the effort? Imagine yourself a situation when you 
  465. have  to  wait  for  a keypress in your program for hundred times. What you will 
  466. choose  -  writing hundred times two lines of code or hundred times press_key()? 
  467. It  is  maybe  a stupid example. The point is that you can create your functions 
  468. once,  gather  them  in libraries and reuse them in future. You don't waste your 
  469. time by rewriting everything from the beginning, you can reuse created functions 
  470. in  other programs by simply including them, your main program is more readable, 
  471. it's smaller -you see? Only good things! No drawbacks! 
  472.  
  473. Functions with parameters(P_1_9.C and P_1_10.C)
  474. ***********************************************
  475. Imagine  yourself  that this short proggy(P_1_9.C) is a game in which the player 
  476. fights  with all the biggest asshloes in the imaginary world (Gill Bates and his 
  477. evil brothers for example). On the beginning we see our old function press_key() 
  478. (Don't  you  ever  forget  this brackets on the end, because compiler will think 
  479. that  you  have putted a variable or something which you haven't declared at all 
  480. or simply wrongly declared!). 
  481. After  that  we  have asshole_attack(). The task of this function is to throw in 
  482. 1000  assholes  to  exterminate  by our player. Program after start presents the 
  483. player  with  legion of 3000 assholes in three series. It looks that everythings 
  484. is ok, but you should, as a programmer, try to better optimize your(or not your) 
  485. existing  routines  if the need arises. The need is a mother of invention! Maybe 
  486. you  want  to make the program faster, make it smaller or reduce memory it uses. 
  487. Speed  is  most  important thing in games, especially on Atari, so it needs some 
  488. extra work. 
  489. Think  for  a  minute  how  to make asshole_attack() better? We can throw toward 
  490. player  1000  assholes, but our player could become bored if he knew that he has 
  491. to  fight  1000  assholes  once  again  all  the  time.  Conclusion: we need the 
  492. parameter to manipulate the amount of assholes throwed into battle. Take look at 
  493. program 1.9 (P_1_9.C). 
  494.  
  495. To  the  procedure  asshole_attack() we added the parameter how_many_assholes of 
  496. unsigned  int  type. It can take values from 0 to 65535, so it can contain quite 
  497. impressive number of assholes. If we used for example unsigned char data type we 
  498. could  have  255  assholes  at  most,  which certainly will reduce the number of 
  499. annihilated  assholes  in the world. When you will write your own functions with 
  500. parameters  you  should turn your attention to how big numbers will be passed to 
  501. them  and  which  data type is best suited. If you don't remember all the ranges 
  502. then look in Pure C help !!! 
  503.  
  504. Functions returning values
  505. **************************
  506. And  where  are  those  procedures?  C is shit because it cannot use procedures! 
  507. Functions,  functions,  functions...  To  hell  with them! Well, not really. The 
  508. functions  in  C  have  all the functionality of procedures plus something more. 
  509. It's like procedure+function in Turbo Pascal combined in one! 
  510.  
  511. So be calm, let's use function as a classical function returning values. We want 
  512. to  write  the  procedure add_two_numbers() which will receive two parameters in 
  513. shape  of  two int type numbers(why they are so numb?;)). As usual everything in 
  514. Program 1.11(P_1_11.C). 
  515. I  think that's there is no surprises there. We declare int type variable called 
  516. result  and  initialize  it  with  zero.  We  pass  two  numbers  into  function 
  517. add_two_numbers()  and  we  assign the returned value to the result variable.(we 
  518. have  to save the returned value somewhere). After that we print out the message 
  519. on  the  screen.  Notice  that add_two_numbers() will be launched first, it will 
  520. return  value  on the left side of equation mark. This is how it works. It's not 
  521. incidental  -each  operator,  data type or something else, has it's own priority 
  522. and  will be behaving in another way (C compiler reads code sometimes from right 
  523. to  left  or  left  to  right). This is somewhat complicated topic. Take look at 
  524. operator  precedence  in C language section of Pure C help file. And take a look 
  525. at  books  mentioned  in  literture  reference  at  the  end(is  there any?) for 
  526. additional  information.  That  was  a function, THATS ALL! No fireworks at all. 
  527.  
  528. About   functions  I  have  told  *almost*  everything.  I  haven't  told  about 
  529. possibility  of  incorporating local, for particular function, variables and two 
  530. variants  of  passing  parameters.  To declare local variables we simply declare 
  531. them(like in main() function): 
  532.  
  533. void dragons_den(void)
  534. {
  535. int dragon,knight;
  536.  
  537. /*some dirty things made by function*/
  538. }
  539. The  variables  dragon and knight can be used inside the function, but they will 
  540. be  invisible  outside this function. As I mentioned earlier you must initialize 
  541. the  local  variables  to  avoid  errors. Local variables are not initialized at 
  542. start  of  the function and contain garbage, rubbish and other random things. Be 
  543. warned! 
  544.  
  545. Second  thing are two variants of passing parameters to function. If we have the 
  546. variable amount_of_potatoes_to_eat of int type and value equal to 0, and we pass 
  547. it to function like this: 
  548.  
  549. void add_5000(int amount)
  550. {
  551. amount=amount+5000;
  552. }
  553.  
  554. In this way:
  555. add_5000(amount_of_potatoes_to_eat);
  556.  
  557. Then value of amount_potatoes_to_eat will be still 0! Why? The function uses the 
  558. copy  of  the  value  of  amount_of_potatoes  and  called  function does all the 
  559. operation  on  the copy of the variable without altering it. If we want to force 
  560. procedure  to  make  changes in original data we must change function like this: 
  561.  
  562. void add_5000(int * amount) 
  563. {
  564. amount=amount+5000;
  565. }
  566.  
  567. And call it in this way:
  568. add_5000(&amount_of_potatoes_to_eat);
  569.  
  570. We  must  tell  the  function  that  it  has  to  expect  a  pointer  to integer 
  571. variable(the  place in memory where residents our stored variable). We have also 
  572. tell to the called function that we are passing the address (the place in memory 
  573. of where is our variable) to amount_of_potatoes_to_eat so we add "&" mark at the 
  574. beginning  of  our  variable  name. Now each variable passed to function will be 
  575. increased by 5000. 
  576.  
  577.  
  578. <link=art48b.scr>Go to NEXT PART</l>
  579. </frame>
  580. </body>
  581.