Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
shared.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  shared.c
4 
5  =============================================================
6 
7  Copyright 1996-2014 Tom Barbalet. All rights reserved.
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or
14  sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  OTHER DEALINGS IN THE SOFTWARE.
29 
30  This software and Noble Ape are a continuing work of Tom Barbalet,
31  begun on 13 June 1996. No apes or cats were harmed in the writing
32  of this software.
33 
34  ****************************************************************/
35 
36 /* This is intended to dramatically simplify the interface between
37  the various platform versions of Noble Ape */
38 
39 #include <stdio.h>
40 
41 #include "gui.h"
42 #include "shared.h"
43 
44 static n_int mouse_x, mouse_y;
45 static n_byte mouse_option, mouse_identification;
46 static n_byte mouse_down;
47 
48 static n_byte mouse_drag;
49 static n_int mouse_drag_x , mouse_drag_y;
50 
51 static n_byte key_identification;
52 static n_byte2 key_value;
53 static n_byte key_down;
54 
55 #define Y_DELTA 36
56 #define X_DELTA 20
57 
58 static n_int toggle_pause = 0;
59 
60 static n_int control_toggle_pause(n_byte actual_toggle)
61 {
63  {
65  }
66 
67  if (actual_toggle)
68  {
69  toggle_pause ^= 1;
70  }
71  else
72  {
73  toggle_pause = 1;
74  }
75 
76  return toggle_pause;
77 }
78 
79 /* do mouse down interaction over a window, at a point, with keys possibly pressed */
80 
81 extern n_byte check_about;
82 extern n_uint tilt_z;
83 extern n_byte terrain_turn;
84 
85 #ifdef MULTITOUCH_CONTROLS
86 
87 touch_control_state tc_state = TCS_SHOW_NOTHING;
88 touch_control_state tc_temp_state = TCS_SHOW_NOTHING;
89 n_int tc_countdown = 0;
90 
91 #endif
92 
93 static void control_mouse(n_byte wwind, n_int px, n_int py, n_byte option)
94 {
95  noble_being *local;
96  noble_simulation * local_sim = sim_sim();
97  if (local_sim == 0L)
98  return;
99 
100  if(wwind == NUM_VIEW && check_about == 1)
101  {
102  check_about = 0;
103  return;
104  }
105 
106  if (local_sim->select == 0L)
107  {
108  return;
109  }
110 
111  local = local_sim->select;
112  if (wwind == NUM_VIEW)
113  {
114  if (option)
115  {
116  n_byte2 location[2];
117 
118  location[0] = APESPACE_CONFINED(MAPSPACE_TO_APESPACE(px));
119  location[1] = APESPACE_CONFINED(MAPSPACE_TO_APESPACE(py));
120 
121  being_set_location(local, location);
122  }
123  else
124  {
125  noble_being * desired_ape = local_sim->select;
126  n_uint high_squ = 31;
127  n_uint loop = 0;
128 
129  while (loop < local_sim->num)
130  {
131  noble_being * current_ape = &(local_sim->beings[loop]);
132  n_int screen_x = APESPACE_TO_MAPSPACE(being_location_x(current_ape)) - px;
133  n_int screen_y = APESPACE_TO_MAPSPACE(being_location_y(current_ape)) - py;
134  n_uint current_squ = (screen_x * screen_x) + (screen_y * screen_y);
135  if (high_squ > current_squ)
136  {
137  high_squ = current_squ;
138  desired_ape = current_ape;
139  }
140  loop++;
141  }
142  if (local_sim->select != desired_ape)
143  {
144  sim_set_select(desired_ape);
145  }
146  else
147  {
148  if (mouse_drag == 0)
149  {
150  mouse_drag_x = px;
151  mouse_drag_y = py;
152  mouse_drag = 1;
153  }
154  }
155  }
156  }
157  if (wwind == NUM_TERRAIN)
158  {
159  n_int upper_x, upper_y;
160 
161 #ifdef MULTITOUCH_CONTROLS
162  if ((tc_state & 1) == 0)
163  {
164  tc_temp_state = tc_state + 1;
165  tc_countdown = 60;
166 
167  }
168 #endif
169  draw_terrain_coord(&upper_x, &upper_y);
170 
171  if (option != 0)
172  {
173  if ((px > (upper_x/4)) && (px < ((upper_x * 3)/4)))
174  {
175  if (py < (upper_y/4))
176  {
177  tilt_z = ((tilt_z + 1) & 255);
178  }
179  else if (py < ((upper_y * 3)/4))
180  {
181  tilt_z = ((tilt_z + 255) & 255);
182  }
183  }
184  }
185  else
186  {
187  n_int sx = px - ((upper_x)>>1);
188 #ifdef MULTITOUCH_CONTROLS
189  if (px < TC_FRACTION_X)
190  {
191  if (tc_state == TCS_LEFT_STATE_CONTROLS)
192  {
193  tc_temp_state = TCS_SHOW_CONTROLS;
194  tc_countdown = 60;
195  }
196  else
197  {
198  tc_temp_state = TCS_RIGHT_STATE_CONTROLS;
199  tc_countdown = 60;
200  }
201  return;
202  }
203 
204  if (px > (upper_x - TC_FRACTION_X))
205  {
206  if (tc_state == TCS_RIGHT_STATE_CONTROLS)
207  {
208  tc_temp_state = TCS_SHOW_CONTROLS;
209  tc_countdown = 60;
210  }
211  else
212  {
213  tc_temp_state = TCS_LEFT_STATE_CONTROLS;
214  tc_countdown = 60;
215  }
216  return;
217  }
218 #endif
219  if (sx > 0)
220  {
221  terrain_turn = ( terrain_turn + 1) & 255;
222  }
223 
224  if (sx <= 0)
225  {
226  terrain_turn = ( terrain_turn + 255) & 255;
227  }
228  }
229  }
230 }
231 
232 /* do key down in which window */
233 static void control_key(n_byte wwind, n_byte2 num)
234 {
235  noble_being * local;
236  noble_simulation * local_sim = sim_sim();
237  if (local_sim == 0L)
238  return;
239 
240  if (local_sim->select == 0L)
241  {
242  return;
243  }
244 
245  local = local_sim->select;
246 
247  if ((num > 27) && (num < 32))
248  {
249  if (wwind != NUM_VIEW)
250  {
251  if ((num - 28) < 2)
252  being_move(local, (1 - ((num - 28) << 1)), 0);
253  else
254  being_move(local, (160-((num - 28) << 6)), 1);
255  }
256  else
257  {
258  being_move(local, (31-num), 2);
259  }
260  }
261  if ((num > 2075) && (num < 2078))
262  {
263  being_move(local, ( -1 + ((2077-num) << 1)), 0);
264  }
265  if ((num > 2077) && (num < 2080))
266  {
267  being_change_selected(local_sim, (num == 2078));
268  }
269 }
270 
271 #ifdef SCRIPT_DEBUG
272 
273 static n_int script_entry = 1;
274 
275 static n_int shared_script_debug_ready(void)
276 {
277  if (script_entry == 0)
278  {
279  return 0;
280  }
281  if (scdebug_file_ready() != 0L)
282  {
283  script_entry = 0;
284  return 1;
285  }
286  return 0;
287 }
288 
290 {
291  if (cStringFileName)
292  {
293  n_file * outputfile = scdebug_file_ready();
294  io_disk_write(outputfile, cStringFileName);
295  }
297  script_entry = 1;
298 }
299 
300 #else
301 
302 void shared_script_debug_handle(n_string cStringFileName)
303 {
304 
305 }
306 
307 #endif
308 
309 static void * control_init(KIND_OF_USE kind, n_uint randomise)
310 {
311  void * sim_return = 0L;
312 
315 
316  sim_return = sim_init(kind, randomise, OFFSCREENSIZE, VIEWWINDOW(0));
317 
318  if (sim_return)
319  {
320  return draw_offscreen(sim_return);
321  }
322  return 0;
323 }
324 
325 shared_cycle_state shared_cycle(n_uint ticks, n_byte fIdentification, n_int dim_x, n_int dim_y)
326 {
327  shared_cycle_state return_value = SHARED_CYCLE_OK;
328  ticks = ticks & 67108863; /* 71 58 27 88 */
329  ticks *= 60;
330 #ifndef _WIN32
332 #endif
333  if ((mouse_down == 1) && (mouse_identification == fIdentification))
334  {
335 
336  if (fIdentification == NUM_VIEW)
337  {
338 #if (MAP_BITS == 8)
339  control_mouse(mouse_identification, mouse_x/2, mouse_y/2, mouse_option);
340 #else
341  control_mouse(mouse_identification, mouse_x, mouse_y, mouse_option);
342 #endif
343  }
344  else
345  {
346  control_mouse(mouse_identification, mouse_x, mouse_y, mouse_option);
347  }
348  }
349 
350 #ifdef MULTITOUCH_CONTROLS
351  if ((mouse_down == 0) && (mouse_identification == fIdentification))
352  {
353  if (tc_temp_state != tc_state)
354  {
355  tc_state = tc_temp_state;
356  }
357  }
358 #endif
359 
360  if((key_down == 1) && (key_identification == fIdentification))
361  {
362  if ((key_identification == NUM_VIEW) || (key_identification == NUM_TERRAIN))
363  {
364  control_key(key_identification, key_value);
365  }
366  }
367  if(fIdentification == NUM_TERRAIN)
368  {
369  sim_realtime(ticks);
370 #ifdef MULTITOUCH_CONTROLS
371  if (tc_countdown)
372  {
373  tc_countdown--;
374  if (tc_countdown == 0)
375  {
376  if ((tc_state & 1) == 1)
377  {
378  tc_temp_state = tc_state - 1;
379  }
380  }
381  }
382 #endif
383  if ((io_command_line_execution() != 1) && (!toggle_pause))
384  {
385  sim_cycle();
386  }
387 #ifdef SCRIPT_DEBUG
388  if (shared_script_debug_ready())
389  {
390  return_value = SHARED_CYCLE_DEBUG_OUTPUT;
391  }
392 #endif
393 #ifndef _WIN32
395  {
396  return_value = SHARED_CYCLE_QUIT;
397  }
398 #endif
399  }
400  return return_value;
401 }
402 
404 {
405  n_byte2 fit[256 * 3];
406  key_down = 0;
407  mouse_down = 0;
408  mouse_drag = 0;
409  if (view == NUM_TERRAIN)
410  {
411  if (control_init(KIND_START_UP, random) == 0L)
412  {
413  return SHOW_ERROR("Initialization failed lack of memory");
414  }
415  }
416  draw_fit(land_points, fit);
417  return view;
418 }
419 
420 void shared_close(void)
421 {
422  sim_close();
423 }
424 
425 void shared_keyReceived(n_byte2 value, n_byte fIdentification)
426 {
427  key_down = 1;
428  key_value = value;
429  key_identification = fIdentification;
430 }
431 
432 void shared_keyUp(void)
433 {
434  key_down = 0;
435 }
436 
438 {
439  mouse_option = option;
440 }
441 
442 void shared_mouseReceived(n_int valX, n_int valY, n_byte fIdentification)
443 {
444  mouse_down = 1;
445  mouse_identification = fIdentification;
446  mouse_x = valX;
447  mouse_y = valY;
448 }
449 
450 void shared_mouseUp(void)
451 {
452  mouse_down = 0;
453  mouse_drag = 0;
454 }
455 
457 {
458  n_string_block full_value;
459  n_int cores = execute_threads_value();
460  toggle_pause = 1;
461  if (cores > 1)
462  {
463  sprintf(full_value, "%s %ld Cores", value, cores);
464  }
465  else
466  {
467  sprintf(full_value, "%s 1 Core", value);
468  }
469  draw_about(full_value);
470 }
471 
473 {
474  (void)draw_error(0L, 0L, 0);
475 }
476 
478 {
479  static n_int NewBlock = 0;
480  if (NewBlock) return 0;
481 
482  NewBlock = 1;
483  (void)control_init(KIND_NEW_SIMULATION, seed);
484 
485  NewBlock = 0;
486 
487  return 0;
488 }
489 
490 n_byte shared_openFileName(n_string cStringFileName, n_byte isScript)
491 {
492  (void)control_toggle_pause(0);
493 
494  if (isScript)
495  {
496  return (console_script(0L, cStringFileName, 0L) == 0);
497  }
498  return (console_open(0L, cStringFileName, 0L) == 0);
499 }
500 
501 void shared_saveFileName(n_string cStringFileName)
502 {
503  (void)control_toggle_pause(0);
504  (void)console_save(0L, cStringFileName, 0L);
505 }
506 
507 void shared_rotate(n_double num, n_byte wwind)
508 {
509  if (wwind == NUM_TERRAIN)
510  {
511  n_int integer_rotation_256 = (n_int)((num * 256) / 360);
512  terrain_turn = (n_byte)(((n_int)terrain_turn + 512 + integer_rotation_256) & 255);
513  }
514 }
515 
517 {
518  return 60;
519 }
520 
522 {
523  switch (menuVal) {
524  case NA_MENU_PAUSE:
525  return control_toggle_pause(1);
526  case NA_MENU_WEATHER:
527  return draw_toggle_weather();
528  case NA_MENU_BRAIN:
529  return draw_toggle_brain();
530  case NA_MENU_BRAINCODE:
531  return draw_toggle_braincode();
532  case NA_MENU_TERRITORY:
533  return draw_toggle_territory();
535  return draw_toggle_tide_daylight();
537  (void)control_key(0, 2079);
538  return 0;
539  case NA_MENU_NEXT_APE:
540  (void)control_key(0, 2078);
541  return 0;
543  (void)draw_error(0L, 0L, 0);
544  return 0;
545  case NA_MENU_FLOOD:
546  sim_flood();
547  return 0;
550  return 0;
551  }
552  return -1;
553 }
554 
556 {
557 
558 }
559 
560 void shared_draw(n_byte * outputBuffer, n_byte fIdentification, n_int dim_x, n_int dim_y)
561 {
562  n_int ly = 0;
563  n_int loop = 0;
564  n_int loopColors = 0;
565  n_byte2 fit[256*3];
566  noble_simulation * local_sim = sim_sim();
567  n_byte * index = draw_pointer(fIdentification);
568 #ifdef NOBLE_IOS
569  n_c_uint * offscreenBuffer = (n_c_uint *) outputBuffer;
570  n_c_uint colorLookUp[256];
571 #else
572  n_byte colorLookUp[256][3];
573 #endif
574  if (index == 0L) return;
575 
576  if (fIdentification == NUM_TERRAIN)
577  {
578  draw_window(dim_x, dim_y);
579  draw_cycle();
580  }
581 
582  draw_color_time(fit, local_sim->land->time);
583 
584  while(loopColors < 256)
585  {
586 #ifdef NOBLE_IOS
587  n_byte colR = fit[loop++] >> 8;
588  n_byte colG = fit[loop++] >> 8;
589  n_byte colB = fit[loop++] >> 8;
590  colorLookUp[ loopColors ] = (colR << 16) | (colG << 8) | (colB << 0);
591 #else
592  colorLookUp[loopColors][0] = fit[loop++] >> 8;
593  colorLookUp[loopColors][1] = fit[loop++] >> 8;
594  colorLookUp[loopColors][2] = fit[loop++] >> 8;
595 #endif
596  loopColors++;
597  }
598 
599 #if (MAP_BITS == 8)
600 #ifndef NOBLE_IOS
601  if (fIdentification == NUM_VIEW)
602  {
603  loop = 0;
604  while(ly < 512)
605  {
606  n_byte * indexLocalX = &index[(255-(ly>>1))*256];
607 
608  if (ly&1)
609  {
610  io_copy(&outputBuffer[loop - (3*512)], &outputBuffer[loop], (3*512));
611  loop += (3*512);
612  }
613  else
614  {
615  n_int lx = 0;
616  while(lx < 256)
617  {
618  unsigned char value = indexLocalX[lx++] ;
619  outputBuffer[loop++] = colorLookUp[value][0];
620  outputBuffer[loop++] = colorLookUp[value][1];
621  outputBuffer[loop++] = colorLookUp[value][2];
622  outputBuffer[loop++] = colorLookUp[value][0];
623  outputBuffer[loop++] = colorLookUp[value][1];
624  outputBuffer[loop++] = colorLookUp[value][2];
625 
626  }
627  }
628 
629  ly++;
630  }
631 
632 
633  return;
634  }
635 #endif
636 #endif
637 
638  loop = 0;
639  while(ly < dim_y)
640  {
641  n_int lx = 0;
642  n_byte * indexLocalX = &index[(dim_y-ly-1)*dim_x];
643  while(lx < dim_x)
644  {
645 #ifdef NOBLE_IOS
646  offscreenBuffer[loop++] = colorLookUp[ indexLocalX[ lx++ ] ];
647 #else
648  unsigned char value = indexLocalX[lx++] ;
649  outputBuffer[loop++] = colorLookUp[value][0];
650  outputBuffer[loop++] = colorLookUp[value][1];
651  outputBuffer[loop++] = colorLookUp[value][2];
652 #endif
653  }
654  ly++;
655  }
656 
657 }
658 
659 
660