Author Topic: Program drops when putting an image in another image  (Read 4430 times)

0 Members and 1 Guest are viewing this topic.

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Program drops when putting an image in another image
« on: August 05, 2019, 08:16:25 am »
I've been writing an ap to generate star systems to import to my project at:

https://www.qb64.org/forum/index.php?topic=1429.0

It accepts stellar data input, or rolls "dice" to determine it randomly. Then it constructs a system with some number of orbits around however many stars it contains. Then it displays a graphic representation of that system and queries for the presence, number and placement of gas giant planets. TAB or right arrow cycles through the available orbits represented by boxes that are colored according to their orbital zones (inner red, habitable green & outer blue; with grey being otherwise unavailable). ENTER commits a gas giant to the highlighted orbit, at which point a name for the GG is input and the process goes on to the next GG. The previous placement is colored grey and assigned the number of the body inserted.

Sorry for the crpytic user interface, it's a work in progress.

Works well, but I wanted to show the original color of the orbit so the idea was to copy the image and put a smaller version of the previous color in the occupied orbit.

I'm very new at graphics programming, and it's easily possible that I'm missing something essential, but....

The issue is:
When I put an image into another image, the program is dropped completely. No error messages, it just vanishes within about a second or so of displaying the new image. Which it does do briefly. It's in a  do loop, so I thought maybe it's loading up with images, but I've never been able to get _FREEIMAGE to do anything other than throw errors at me, so obviously I have no understanding of how to use that one...perhaps it's just a matter of putting it in the right spot.

The difference between a working program and a dropped one seems to be associated with lines 362 & 364 in SUB GasGiants. I've commented them out so that an initial running of the program works.

Is there a limit to nested _PUTIMAGEs? Am I committing an obvious coding gaff? or is there a bug in the IDE, I'm using 1.3 96937f0

Code: QB64: [Select]
  1. 'System Buider 0.1
  2. 'companion utility to CT-Vector
  3. 'primary reference shall be DGP's WBH
  4.  
  5. '                                                               MAIN MODULE
  6.  
  7. TYPE unitpoint '                                                relative unit placement
  8.     pX AS _INTEGER64
  9.     pY AS _INTEGER64
  10.     pZ AS _INTEGER64
  11.  
  12. TYPE body '                                                     Celestial bodies
  13.     nam AS STRING * 20 '                                        Name
  14.     parnt AS STRING * 20 '                                      name of parent body
  15.     radi AS _INTEGER64 '                                        Size (needs _INTEGER64 in event of large star)
  16.     orad AS _INTEGER64 '                                        Orbital radius
  17.     oprd AS SINGLE '                                            Orbital period (years)
  18.     rota AS SINGLE '                                            Rotational period (days)
  19.     dens AS SINGLE '                                            Density, basis for grav(Gs) calculation
  20.     rank AS _BYTE '                                             1=primary, 2=planet/companion, 3=satelite
  21.     star AS _BYTE '                                             -1=star  0=non-stellar body
  22.     class AS STRING * 2 '                                       Two digit code, use for stellar class, GG, etc.
  23.     siz AS STRING * 3 '                                         three digit code, use for stellar size,
  24.     maxor AS _BYTE '                                            Maximum orbits for body
  25.     ps AS unitpoint '                                           coordinate position
  26.  
  27. TYPE layer
  28.     class AS INTEGER '                                          orbit class <3 no not use orbit
  29.     orad AS _INTEGER64 '                                        radius from rank parent
  30.     oprd AS SINGLE '                                            Orbital period (years)
  31.     pin AS INTEGER '                                            body occupant identifier
  32.     rank AS INTEGER '                                           TBD
  33.     prsnt AS INTEGER '                                          is orbit present? -1 true
  34.  
  35. TYPE roll
  36.     c AS _BYTE '                                                class DM
  37.     s AS _BYTE '                                                size DM
  38.  
  39. '                                                               VARIABLE DECLARATIONS
  40. DIM SHARED clr&(0 TO 15) '                                      32 bit equivalent of SCREEN 0 colors
  41. DIM SHARED MWin AS _BYTE '                                      Main world entered? -1 true
  42. DIM SHARED sysnat AS _BYTE '                                    1 = solo, 2 = binary, 3 = trinary
  43. DIM SHARED starroll(4) AS roll '                                memorize star class and size DMs
  44. DIM SHARED heavens(100) AS body '                                planet data array
  45. DIM SHARED orbit(21, 5) AS layer '                                 Main system orbit shells
  46. DIM SHARED orbs AS INTEGER '                                    number of stellar & planetary bodies present
  47. 'DIM SHARED in AS INTEGER '                                      planetary index
  48. 'DIM SHARED orbitclass AS INTEGER '                              0 thru 6: interior,vaporized,inner,habitable,outer,too far
  49. DIM SHARED main& '                                              main screen handle
  50. DIM SHARED starin& '                                            stellar details screen handle
  51. DIM SHARED chkbx& '                                             check box
  52. DIM SHARED plcmnt& '                                            planet placement screen
  53.  
  54. CONST AUtokm = 149668990
  55. CONST Solrad = 695700
  56.  
  57. '                                                               DEFINE SCREEN IMAGES
  58. main& = _NEWIMAGE(1200, 688, 32) '                              main screen image 1200 x 600 32bit color
  59. starin& = _NEWIMAGE(640, 688, 32) '                             stellar details screen 80x48 text
  60. chkbx& = _NEWIMAGE(24, 24, 32)
  61. plcmnt& = _NEWIMAGE(1200, 464, 32) '                            150x29
  62. 'plcmnt& = _LOADIMAGE("jup.jpg", 32)
  63.  
  64. SCREEN main& '                                                  Initiate main screen
  65. _TITLE "System Builder 0.1"
  66. _SCREENMOVE (_DESKTOPWIDTH - 1200) / 2, 1
  67.  
  68.  
  69. SetEnviron
  70. RefreshPrompt
  71.  
  72. '                                                               DATA SECTION
  73. colors:
  74. '                                                               colors 0-4
  75. DATA 0,0,0,0,0,168,0,168,0,0,168,168,168,0,0
  76. '                                                               colors 5-9
  77. DATA 168,0,168,168,84,0,168,168,168,84,84,84,84,84,252
  78. '                                                               colors 10-14
  79. DATA 84,252,84,84,252,252,252,84,84,252,84,252,252,252,84
  80. '                                                               color 15
  81. DATA 252,252,252
  82.  
  83. stellar_details:
  84. 'Steller data & orbit zones tables
  85. 'Orbit Class: Size, Type, Mass(in solar masses), Radius(in solar radii), 1=interior, 2=vaporized, 3=inner, 4=habitable, 5=outer, 6=too far
  86. DATA "Ia","B0",60,52,1,2,2,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,6
  87. DATA "Ia","B5",30,75,1,2,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  88. DATA "Ia","A0",18,135,1,1,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  89. DATA "Ia","A5",15,149,1,1,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  90. DATA "Ia","F0",13,174,1,1,1,2,2,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  91. DATA "Ia","F5",12,204,1,1,1,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  92. DATA "Ia","G0",12,298,1,1,1,1,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  93. DATA "Ia","G5",13,454,1,1,1,1,1,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  94. DATA "Ia","K0",14,654,1,1,1,1,1,1,2,3,3,3,3,3,4,5,5,5,5,5,5,6
  95. DATA "Ia","K5",18,1010,1,1,1,1,1,1,2,3,3,3,3,3,4,5,5,5,5,5,5,6
  96. DATA "Ia","M0",20,1467,1,1,1,1,1,1,1,3,3,3,3,3,4,5,5,5,5,6
  97. DATA "Ia","M5",25,3020,1,1,1,1,1,1,1,1,3,3,3,3,4,5,5,5,5,6
  98. DATA "Ia","M9",30,3499,1,1,1,1,1,1,1,1,3,3,3,3,4,5,5,5,5,6
  99. DATA "Ib","B0",50,30,1,2,2,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,6
  100. DATA "Ib","B5",25,35,1,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  101. DATA "Ib","A0",16,50,1,2,2,2,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  102. DATA "Ib","A5",13,55,1,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  103. DATA "Ib","F0",12,59,1,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  104. DATA "Ib","F5",10,60,1,2,2,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  105. DATA "Ib","G0",10,84,1,2,2,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  106. DATA "Ib","G5",12,128,1,1,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  107. DATA "Ib","K0",13,216,1,1,1,1,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  108. DATA "Ib","K5",16,392,1,1,1,1,1,2,3,3,3,3,3,5,5,5,5,5,5,5,5,6
  109. DATA "Ib","M0",16,857,1,1,1,1,1,1,3,3,3,3,3,5,5,5,5,5,5,6
  110. DATA "Ib","M5",20,2073,1,1,1,1,1,1,1,3,3,3,3,4,4,5,5,5,5,6
  111. DATA "Ib","M9",25,2876,1,1,1,1,1,1,1,1,3,3,3,4,4,5,5,5,5,6
  112. DATA "II","B0",30,22,1,2,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  113. DATA "II","B5",20,20,1,2,2,2,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  114. DATA "II","A0",14,18,1,2,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,5,6
  115. DATA "II","A5",11,14,1,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,5,5,6
  116. DATA "II","F0",10,16,1,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,5,5,6
  117. DATA "II","F5",8.1,18,1,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,5,5,6
  118. DATA "II","G0",8.1,25,1,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,5,5,6
  119. DATA "II","G5",10,37,1,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,5,5,6
  120. DATA "II","K0",11,54,1,2,3,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  121. DATA "II","K5",14,124,1,1,2,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  122. DATA "II","M0",14,237,1,1,1,1,3,3,3,3,3,3,4,5,5,5,5,5,5,6
  123. DATA "II","M5",16,712,1,1,1,1,1,1,3,3,3,3,3,4,5,5,5,5,5,6
  124. DATA "II","M9",18,931,1,1,1,1,1,1,3,3,3,3,3,4,5,5,5,5,5,6
  125. DATA "III","B0",25,16,1,2,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,6
  126. DATA "III","B5",15,10,1,2,2,2,3,3,3,3,3,3,4,5,5,5,5,5,5,6
  127. DATA "III","A0",12,6.2,1,3,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  128. DATA "III","A5",9,4.6,1,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  129. DATA "III","F0",8,4.7,1,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  130. DATA "III","F5",5,5.2,1,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  131. DATA "III","G0",2.5,7.1,1,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  132. DATA "III","G5",3.2,11,1,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  133. DATA "III","K0",4,16,1,3,3,3,3,3,3,4,5,5,5,5,5,5,5,6
  134. DATA "III","K5",5,42,1,3,3,3,3,3,3,3,4,5,5,5,5,5,5,6
  135. DATA "III","M0",6.3,63,1,2,3,3,3,3,3,3,4,5,5,5,5,6
  136. DATA "III","M5",7.4,228,1,1,1,1,3,3,3,3,3,4,5,5,5,6
  137. DATA "III","M9",9.2,360,1,1,1,1,1,3,3,3,3,4,5,5,5,6
  138. DATA "IV","B0",20,13,2,2,2,2,2,2,2,3,3,3,3,3,4,5,6
  139. DATA "IV","B5",10,5.3,2,2,2,3,3,3,3,3,3,4,5,5,5,5,6
  140. DATA "IV","A0",6,4.5,2,3,3,3,3,3,3,4,5,5,5,5,5,5,6
  141. DATA "IV","A5",4,2.7,3,3,3,3,3,3,4,5,5,5,5,5,5,5,6
  142. DATA "IV","F0",2.5,2.7,3,3,3,3,3,3,4,5,5,5,5,5,5,5,6
  143. DATA "IV","F5",2,2.6,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  144. DATA "IV","G0",1.75,2.5,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  145. DATA "IV","G5",2,2.8,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  146. DATA "IV","K0",2.3,3.3,3,3,3,3,4,5,5,5,5,5,5,6
  147. DATA "V","B0",18,10,2,2,2,2,2,2,3,3,3,3,3,3,4,6
  148. DATA "V","B5",6.5,4.4,2,2,2,2,3,3,3,3,3,4,5,5,5,6
  149. DATA "V","A0",3.2,3.2,3,3,3,3,3,3,3,4,5,5,5,5,5,6
  150. DATA "V","A5",2.1,1.8,3,3,3,3,3,3,4,5,5,5,5,5,5,6
  151. DATA "V","F0",1.7,1.7,3,3,3,3,3,4,5,5,5,5,5,5,5,6
  152. DATA "V","F5",1.3,1.4,3,3,3,3,4,5,5,5,5,5,5,5,5,6
  153. DATA "V","G0",1.04,1.03,3,3,3,4,5,5,5,5,5,5,5,5,5,6
  154. DATA "V","G5",0.94,0.91,3,3,4,5,5,5,5,5,5,5,5,5,5,6
  155. DATA "V","K0",0.825,0.908,3,3,4,5,5,5,5,5,5,5,5,6
  156. DATA "V","K5",0.57,0.566,4,5,5,5,5,5,5,5,5,5,5,6
  157. DATA "V","M0",0.489,0.549,4,5,5,5,5,5,5,5,5,6
  158. DATA "V","M5",0.331,0.358,5,5,5,5,5,5,5,5,5,6
  159. DATA "V","M9",0.215,0.201,5,5,5,5,5,5,5,5,5,6
  160. DATA "VI","F5",0.8,1.14,3,3,3,4,5,6
  161. DATA "VI","G0",0.6,1.02,3,3,4,5,5,6
  162. DATA "VI","G5",0.528,0.55,3,4,5,5,5,6
  163. DATA "VI","K0",0.430,0.4,3,4,5,5,5,6
  164. DATA "VI","K5",0.33,0.308,5,5,5,5,5,6
  165. DATA "VI","M0",0.154,0.256,5,5,5,5,5,6
  166. DATA "VI","M5",0.104,0.104,5,5,5,5,5,6
  167. DATA "VI","M9",0.058,0.053,5,5,5,5,5,6
  168. DATA "D","B0",0.26,0.018,4,5,5,5,6
  169. DATA "D","A0",0.36,0.017,5,5,5,5,6
  170. DATA "D","F0",0.42,0.013,5,5,5,5,6
  171. DATA "D","G0",0.63,0.012,5,5,5,5,6
  172. DATA "D","K0",0.83,0.009,5,5,5,5,6
  173. DATA "D","M0",1.11,0.006,5,5,5,5,6
  174.  
  175. Orbits:
  176. 'Orbit radii in AU
  177. DATA 0.2,0.4,0.7,1,1.6,2.8,5.2,10,19.6,38.8,77.2
  178. DATA 154,307.6,614.8,1229.2,2458,4915.6,9830.8,19661.2,39322
  179.  
  180. '                                                               END DATA SECTION
  181. '                                                               END MAIN MODULE
  182.  
  183. SUB AvailableOrbit (var AS INTEGER)
  184.  
  185.     DIM x%
  186.     FOR x% = 0 TO heavens(var).maxor
  187.         SELECT CASE orbit(x%, var).class
  188.             CASE 1: orbit(x%, var).prsnt = 0
  189.             CASE 2 TO 5: orbit(x%, var).prsnt = -1
  190.             CASE 6: orbit(x%, var).prsnt = 0: EXIT FOR '        <<< subtract 1 from heavens(var).maxor or set to x% ???
  191.         END SELECT
  192.     NEXT x%
  193.     IF x% < 21 THEN
  194.         DO
  195.             orbit(x%, var).prsnt = 0
  196.             x% = x% + 1
  197.         LOOP UNTIL x% = 21
  198.     END IF
  199.  
  200. END SUB 'AvailableOrbit%
  201.  
  202.  
  203. FUNCTION Choose% (query AS STRING, choice AS STRING)
  204.  
  205.     DIM ch%
  206.     PRINT query
  207.     DO
  208.         ch% = INSTR(choice, UCASE$(INKEY$))
  209.         _LIMIT 50
  210.     LOOP UNTIL ch% <> 0
  211.     Choose% = ch%
  212.  
  213. END FUNCTION 'Choose
  214.  
  215.  
  216. FUNCTION DiceRoll% (quan AS INTEGER, dice AS INTEGER, plus AS INTEGER)
  217.  
  218.     'Rolls any number of dice of any number of sides and adds modifiers
  219.     'syntax usage: DiceRoll% (number of dice rolled, number of sides, any modifier)
  220.  
  221.     DIM t%, x%
  222.     t% = plus '                                                 add modifier
  223.     FOR x% = 1 TO quan '                                        roll die <quan>tity of times
  224.         t% = t% + INT(RND * dice) + 1 '                         total up results
  225.     NEXT x%
  226.     DiceRoll% = t%
  227.  
  228. END FUNCTION 'DiceRoll%
  229.  
  230.  
  231. FUNCTION FindParent (var AS INTEGER)
  232.  
  233.     'Accepts a planetary body index (var) and finds the index of its parent body
  234.     DIM x%, p%
  235.     FOR x% = 1 TO UBOUND(heavens)
  236.         IF heavens(var).parnt = heavens(x%).nam THEN p% = x%
  237.     NEXT x%
  238.     FindParent = p%
  239.  
  240. END FUNCTION 'FindParent
  241.  
  242.  
  243. SUB GasGiants
  244.  
  245.     DIM x$, chk&, rl%, gp%, n%, x%, y%, zc%, yc%, z%, ggs%, sz%, noa%, ggdet AS body
  246.  
  247.     gp% = GetAnswer%("Gas Giant Present?: <Y>es <N>o <R>oll", "YNR")
  248.     SELECT CASE gp%
  249.         CASE 1: rl% = 6
  250.         CASE 2: rl% = 0
  251.         CASE 3: rl% = DiceRoll%(2, 6, 0) '                      roll for GG presence
  252.     END SELECT
  253.     IF rl% > 5 THEN
  254.         n% = GetAnswer%("Number of gas giants: <1> <2> <3> <4> <5> <R>oll", "12345R")
  255.         IF n% < 6 THEN
  256.             ggs% = n%
  257.         ELSE
  258.             rl% = DiceRoll%(2, 6, 0) '                          roll for GG number
  259.             IF rl% < 10 THEN
  260.                 ggs% = INT(rl% / 2)
  261.             ELSE
  262.                 ggs% = INT((rl% - 1) / 2)
  263.             END IF
  264.         END IF
  265.         'check for sufficient orbits for gas giants <<<CAN THIS BE SUBBED OUT?
  266.         noa% = 0
  267.         FOR y% = 1 TO sysnat
  268.             FOR z% = 0 TO heavens(y%).maxor
  269.                 IF orbit(z%, y%).class > 2 AND orbit(z%, y%).class < 6 THEN
  270.                     IF orbit(z%, y%).pin = 0 AND orbit(z%, y%).prsnt THEN
  271.                         noa% = noa% + 1
  272.                     END IF
  273.                 END IF
  274.             NEXT z%
  275.         NEXT y%
  276.         IF noa% = 0 THEN GOTO GGnone
  277.         IF noa% < ggs% THEN ggs% = noa%
  278.  
  279.         'Do GG orbits and details
  280.         FOR x% = 1 TO ggs%
  281.             yc% = 1: zc% = 0
  282.             ggdet.class = "GG"
  283.             rl% = DiceRoll%(1, 6, 0) '                          roll for GG size (S/L)
  284.             IF rl% < 4 THEN '                                   determine radi as per WBH
  285.                 ggdet.siz = "S"
  286.                 rl% = DiceRoll%(2, 6, 0)
  287.                 SELECT CASE rl%
  288.                     CASE IS < 7: sz% = rl% * 10
  289.                     CASE IS < 9: sz% = (rl% - 1) * 10
  290.                     CASE 10 TO 12: sz% = (rl% - 2) * 10
  291.                 END SELECT
  292.             ELSE
  293.                 ggdet.siz = "L"
  294.                 rl% = DiceRoll%(3, 6, 0)
  295.                 SELECT CASE rl%
  296.                     CASE IS < 8: sz% = (rl% + 8) * 10
  297.                     CASE 8 TO 18: sz% = (rl% + 7) * 10
  298.                 END SELECT
  299.             END IF
  300.             ggdet.radi = (((sz% * 1000) + (DiceRoll%(2, 6, -7) * 1000) + (DiceRoll%(2, 6, -7) * 100) + (DiceRoll%(2, 6, -7) * 10) + DiceRoll%(2, 6, -7)) * 1.6) / 2
  301.             '                                                   density
  302.             rl% = DiceRoll%(3, 6, 0)
  303.             SELECT CASE rl%
  304.                 CASE IS < 8: ggdet.dens = (rl% + 7) / 100
  305.                 CASE 8 TO 11: ggdet.dens = (rl% * 2) / 100
  306.                 CASE 12, 13: ggdet.dens = (rl% + 11) / 100
  307.                 CASE 14 TO 18: ggdet.dens = (rl% + 12) / 100
  308.             END SELECT
  309.  
  310.             'Gas Giant Placement routine here or call
  311.  
  312.             'Screen 0 color array
  313.             '0=black,1=blue,2=green,3=aqua,4=red,5=purple,6=brown,7=white
  314.             '8=gray, +8=bright color, except 14=yellow,
  315.             SCREEN plcmnt& '                                    <<<CAN THIS BE SUBBED OUT TOO?
  316.             _DEST plcmnt&
  317.             COLOR clr&(14), clr&(3): CLS
  318.             PRINT x%; "- "; ggdet.siz; ggdet.class; " radius="; ggdet.radi; "  density="; ggdet.dens
  319.             DO
  320.                 FOR y% = 1 TO sysnat
  321.                     LOCATE 5 * (y% - 1) + 2,
  322.                     PRINT SPC(5 * (heavens(y%).rank - 1)); _TRIM$(heavens(y%).nam); " "; heavens(y%).class; heavens(y%).siz
  323.                     PRINT SPC(5 * (heavens(y%).rank - 1));
  324.                     FOR z% = 0 TO heavens(y%).maxor
  325.                         x$ = INKEY$
  326.                         IF x$ = CHR$(0) + CHR$(77) THEN zc% = zc% + 1
  327.                         IF x$ = CHR$(9) THEN zc% = zc% + 1
  328.                         IF x$ = CHR$(13) THEN EXIT DO
  329.                         IF orbit(zc%, yc%).class < 3 THEN zc% = zc% + 1
  330.                         IF orbit(zc%, yc%).prsnt = 0 THEN zc% = zc% + 1
  331.                         IF orbit(zc%, yc%).pin > 0 THEN zc% = zc% + 1
  332.                         IF zc% > heavens(yc%).maxor THEN
  333.                             zc% = 0: yc% = yc% + 1
  334.                         END IF
  335.                         IF yc% > sysnat THEN yc% = 1
  336.                         IF z% < 10 THEN
  337.                             PRINT "  "; z%; "  ";
  338.                         ELSE
  339.                             PRINT " "; z%; "  ";
  340.                         END IF
  341.  
  342.                         _DEST chkbx&
  343.  
  344.                         SELECT CASE orbit(z%, y%).class
  345.                             CASE 2: COLOR clr&(0), clr&(15): CLS
  346.                             CASE 3: COLOR clr&(15), clr&(12): CLS
  347.                             CASE 4: COLOR clr&(15), clr&(2): CLS
  348.                             CASE 5: COLOR clr&(15), clr&(1): CLS
  349.                         END SELECT
  350.                         IF zc% = z% AND yc% = y% THEN
  351.                             LINE (1, 1)-(22, 22), clr&(4), B: LINE (2, 2)-(21, 21), clr&(15), B ' display active orbit box
  352.                         END IF
  353.                         IF orbit(z%, y%).prsnt = 0 OR orbit(z%, y%).pin > 0 THEN '           Check box greyed out or available
  354.                             'chk& = _COPYIMAGE(chkbx&)
  355.                             COLOR , clr&(8): CLS
  356.                             '_PUTIMAGE (3, 3)-(20, 20), chk&, chkbx&
  357.                             IF orbit(z%, y%).pin > 0 THEN
  358.                                 _PRINTSTRING (4, 4), _TRIM$(STR$(orbit(z%, y%).pin)), chkbx&
  359.                             END IF
  360.                         END IF
  361.  
  362.                         SCREEN plcmnt&
  363.                         _DEST plcmnt&
  364.                         IF orbit(z%, y%).class > 1 THEN
  365.                             _PUTIMAGE (((heavens(y%).rank - 1) * 40) + (56 * z%) + 16, (48 + ((y% - 1) * 80))), chkbx&, plcmnt&
  366.                         END IF
  367.                     NEXT z%
  368.                     PRINT
  369.                 NEXT y%
  370.  
  371.             LOOP
  372.             PRINT: PRINT: PRINT
  373.  
  374.             orbs = orbs + 1
  375.             heavens(orbs) = ggdet '                             sets class, size, radius, density
  376.             LOCATE sysnat * 5 + 3, 1
  377.             INPUT "Name of Gas Giant: ", heavens(orbs).nam '    sets name
  378.             heavens(orbs).parnt = heavens(yc%).nam '            sets parent name
  379.             heavens(orbs).orad = orbit(zc%, yc%).orad '         sets orbital radius (relative to .parnt
  380.             orbit(zc%, yc%).pin = orbs '                        places in orbital slot
  381.             CLS
  382.         NEXT x%
  383.  
  384.         SCREEN main&: _DEST main&
  385.     ELSE
  386.         GGnone:
  387.         PRINT "No gas giants present"
  388.         SLEEP 3
  389.  
  390.     END IF
  391.  
  392. END SUB 'GasGiants
  393.  
  394.  
  395. FUNCTION GetAnswer% (prompt$, validChars$)
  396.  
  397.     '-------------------------QUERY------------------------------------------------------CLEARED
  398.     ' FUNCTION: GetAnswer%
  399.     '
  400.     ' Purpose:
  401.     ' Display a menu prompt.
  402.     ' Get a character of input from the keyboard and return a numerical expression
  403.     ' to represent choice for SELECT CASE or similar control functions. Rejects any
  404.     ' invalid characters entered. A standard library routine stolen from "QBasic
  405.     ' for Dummies". Why reinvent a wheel?
  406.     '
  407.     ' Passed Variables:
  408.     ' prompt$ sends menu prompt to be displayed
  409.     ' validChars$ sends list of acceptable hotkey choices
  410.     '
  411.     '------------------------------------------------------------------------------------
  412.     DIM inChar$, charPos%, okchar% '                            added for OPTION _EXPLICIT
  413.     PRINT prompt$
  414.     DO
  415.         inChar$ = UCASE$(INKEY$)
  416.  
  417.         charPos% = INSTR(validChars$, inChar$) '                examine the input.
  418.         IF (LEN(inChar$) = 1) AND (charPos% <> 0) THEN
  419.             okchar% = 1
  420.         ELSE
  421.             okchar% = 0
  422.         END IF
  423.     LOOP UNTIL okchar% '                                        Stop looping when a valid character is received.
  424.  
  425.     GetAnswer% = charPos%
  426.  
  427. END FUNCTION 'GetAnswer%
  428.  
  429.  
  430. SUB MainIn
  431.  
  432.     'conduct main world UPP entry
  433.  
  434. END SUB 'MainIn
  435.  
  436.  
  437. SUB MaxOrbits (id AS INTEGER, typ AS STRING, siz AS STRING)
  438.  
  439.     DIM x%, y%, mx%, sc$, sz$, sm!, sr!, typt$, dm%, rl%, o$
  440.     STATIC o2$ '                                                used to avoid duplicating inner orbits
  441.  
  442.     IF VAL(MID$(typ, 2)) >= 5 THEN
  443.         typt$ = _TRIM$(LEFT$(typ, 1)) + "5"
  444.     ELSEIF VAL(MID$(typ, 2)) < 5 THEN
  445.         typt$ = _TRIM$(LEFT$(typ, 1)) + "0"
  446.     END IF
  447.  
  448.     RESTORE stellar_details
  449.     'Find the proper table of orbits, when found exit with data set
  450.     DO
  451.         REDIM rbits%(0 TO 21)
  452.         x% = 0
  453.         READ sz$: READ sc$: READ sm!: READ sr!
  454.         DO
  455.             READ rbits%(x%)
  456.             IF rbits%(x%) = 6 THEN EXIT DO '                    beyond available orbits for star type 6 is delimiter
  457.             x% = x% + 1
  458.         LOOP
  459.     LOOP UNTIL _TRIM$(sc$) = _TRIM$(typt$) AND _TRIM$(sz$) = _TRIM$(siz)
  460.  
  461.     PRINT sc$; " "; sz$; " ";
  462.     heavens(id).radi = sr! * Solrad
  463.     heavens(id).dens = sm! / (1.333 * _PI * (sr! ^ 3)) '        .255 solar density
  464.  
  465.     FOR y% = 0 TO x%
  466.         orbit(y%, id).class = rbits%(y%)
  467.         IF orbit(y%, id).class = 1 THEN orbit(y%, id).prsnt = 0 '       within star photosphere
  468.         PRINT orbit(y%, id).class;
  469.     NEXT y%
  470.  
  471.     IF siz = "Ia" OR siz = "Ib" OR siz = "II" THEN '            determine size modifier
  472.         dm% = dm% + 8
  473.     ELSEIF siz = "III" THEN
  474.         dm% = dm% + 4
  475.     ELSE
  476.         'no die modifier
  477.     END IF
  478.  
  479.     IF LEFT$(typ, 1) = "M" THEN '                               determine class modifier
  480.         dm% = dm% - 4
  481.     ELSEIF LEFT$(typ, 1) = "F" THEN
  482.         dm% = dm% - 2
  483.     ELSE
  484.         'no die modifier
  485.     END IF
  486.     mx% = GetAnswer%("Choose max. orbits, DM of " + STR$(dm%) + " applied: (2 - 9) A=10, B=11, C=12, <R>oll:", "23456789ABCR")
  487.     IF mx% < 12 THEN
  488.         heavens(id).maxor = mx% + 1 + dm%
  489.     ELSE
  490.         heavens(id).maxor = DiceRoll%(2, 6, dm%) '              roll for maximum orbits
  491.     END IF
  492.     AvailableOrbit id
  493.  
  494.     IF id = 1 THEN
  495.     ELSEIF id = 2 THEN
  496.         rl% = DiceRoll%(2, 6, 0) '                              roll for companion orbit
  497.         SELECT CASE rl%
  498.             CASE 2 TO 3: o$ = "c" '                             close companion
  499.             CASE 4: o$ = "1" '                                  orbit 1
  500.             CASE 5: o$ = "2" '                                  orbit 2
  501.             CASE 6: o$ = "3" '                                  orbit 3
  502.             CASE 7: o$ = STR$(4 + DiceRoll%(1, 6, 0)) '         orbit 4 + 1D
  503.             CASE 8: o$ = STR$(5 + DiceRoll%(1, 6, 0)) '         orbit 5 + 1D
  504.             CASE 9: o$ = STR$(6 + DiceRoll%(1, 6, 0)) '         orbit 6 + 1D
  505.             CASE 10: o$ = STR$(7 + DiceRoll%(1, 6, 0)) '        orbit 7 + 1D
  506.             CASE 11: o$ = STR$(8 + DiceRoll%(1, 6, 0)) '        orbit 8 + 1D
  507.             CASE 12: o$ = "f" '                                 far
  508.         END SELECT
  509.         o2$ = o$
  510.         PlaceStar id, o$
  511.     ELSEIF id = 3 THEN
  512.         try_again:
  513.         rl% = DiceRoll%(2, 6, 4) '                              roll for second companion orbit
  514.         SELECT CASE rl%
  515.             CASE 6: o$ = "3" '                                  orbit 3
  516.             CASE 7: o$ = STR$(4 + DiceRoll%(1, 6, 0)) '         orbit 4 + 1D
  517.             CASE 8: o$ = STR$(5 + DiceRoll%(1, 6, 0)) '         orbit 5 + 1D
  518.             CASE 9: o$ = STR$(6 + DiceRoll%(1, 6, 0)) '         orbit 6 + 1D
  519.             CASE 10: o$ = STR$(7 + DiceRoll%(1, 6, 0)) '        orbit 7 + 1D
  520.             CASE 11: o$ = STR$(8 + DiceRoll%(1, 6, 0)) '        orbit 8 + 1D
  521.             CASE IS >= 12: o$ = "f" '                           far
  522.         END SELECT
  523.         IF o$ = o2$ AND o$ <> "f" THEN GOTO try_again '         Don't put in same orbit as #2, but take a chance on far orbits
  524.         PlaceStar id, o$
  525.  
  526.         'id 4 & 5 on recursive call for far companion binary stars?
  527.     ELSEIF id = 4 OR id = 5 THEN
  528.         rl% = DiceRoll%(2, 6, -4)
  529.         SELECT CASE rl%
  530.             CASE IS <= 3: o$ = "c"
  531.             CASE 4: o$ = "1"
  532.             CASE 5: o$ = "2"
  533.             CASE 6: o$ = "3"
  534.             CASE 7: o$ = STR$(4 + DiceRoll%(1, 6, 0))
  535.             CASE 8: o$ = STR$(5 + DiceRoll%(1, 6, 0))
  536.         END SELECT
  537.         PlaceStar id, o$
  538.     END IF
  539.  
  540. END SUB 'MaxOrbits
  541.  
  542.  
  543. SUB PlaceStar (var AS INTEGER, orbst AS STRING)
  544.  
  545.     'Place body(var) into (orbit)
  546.  
  547.     DIM x%, y%, ao%, rl%, sc%, sz% 'DIM zo% ' DIM l%
  548.  
  549.     IF orbst = "c" THEN '                                         close companion
  550.         heavens(var).orad = heavens(1).radi + heavens(var).radi + DiceRoll%(1, 100000, 20000)
  551.         heavens(var).maxor = 0
  552.     ELSEIF orbst = "f" THEN '                                     far orbit
  553.         heavens(var).orad = (DiceRoll%(1, 6, 0) * 1000) * AUtokm
  554.         rl% = DiceRoll%(2, 6, -1) '                             is this one a binary?
  555.         IF rl% > 7 THEN '                                       yes it is
  556.             'configure far binary companion here
  557.             y% = 0
  558.             DO '                                                find next empty array element
  559.                 y% = y% + 1
  560.                 IF heavens(y%).star THEN
  561.                 ELSE
  562.                     EXIT DO '                                   y% element is empty
  563.                 END IF
  564.             LOOP
  565.             heavens(y%).star = -1
  566.             heavens(y%).rank = 3
  567.             PRINT
  568.             INPUT "Name of far companion binary star: ", heavens(y%).nam
  569.             heavens(y%).parnt = heavens(var).nam
  570.             orbs = orbs + 1: sysnat = sysnat + 1
  571.             'Star Spectral Class
  572.             sc% = GetAnswer%("Spectral class: <B><A><F><G><K><M> or <R>oll ", "BAFGKMR")
  573.             heavens(y%).class = StarClass$(y%, sc%)
  574.             PRINT heavens(y%).class
  575.             'Star Size
  576.             sz% = GetAnswer%("Star Size: <A.Ia><B.Ib><2.II><3.III><4.IV><5.V><6.VI><D> or <R>oll ", "AB23456DR")
  577.             heavens(y%).siz = StarSize$(y%, sz%)
  578.             PRINT heavens(y%).siz
  579.             MaxOrbits y%, heavens(y%).class, heavens(y%).siz
  580.         END IF
  581.     ELSE '                                                      system orbit
  582.         x% = VAL(orbst)
  583.         IF orbit(x%, FindParent(var)).orad < heavens(FindParent(var)).radi THEN 'if parent star bigger than orbit then
  584.             heavens(var).orad = heavens(FindParent(var)).radi + heavens(var).radi + DiceRoll%(1, 100000, 20000) 'close companion of giant star
  585.         ELSE
  586.             heavens(var).orad = orbit(x%, FindParent(var)).orad
  587.             orbit(x%, FindParent(var)).pin = var
  588.             'determine available orbits here
  589.             ao% = INT(x% / 2)
  590.             heavens(var).maxor = ao%
  591.             AvailableOrbit var
  592.             DO '                                                delete inner orbits from parent
  593.                 ao% = ao% + 1:
  594.                 IF ao% < x% THEN
  595.                     orbit(ao%, FindParent(var)).prsnt = 0
  596.                 ELSEIF ao% = x% THEN
  597.                     orbit(ao%, FindParent(var)).prsnt = -1
  598.                 ELSE
  599.                     orbit(ao%, FindParent(var)).prsnt = 0
  600.                 END IF
  601.             LOOP UNTIL ao% = x% + 2
  602.         END IF
  603.     END IF
  604.  
  605. END SUB 'PlaceStar
  606.  
  607.  
  608. SUB RefreshPrompt
  609.  
  610.     DIM x%
  611.     SCREEN main&
  612.     _DEST main&
  613.     CLS
  614.     'if there is a main world pre-generated, enter it first and set MWin to -1
  615.     'IF YesOrNo$("Is there a main world to enter?") = "Y" THEN MainIn
  616.     'FOR x% = 0 TO 19
  617.     '    PRINT x%; "  "; orbit(x%, 1).orad
  618.     'NEXT x%
  619.     'SLEEP
  620.     StarSystem '                                               Rank 1 primary & rank 2 companion(s)
  621.     GasGiants
  622.     SystemDisplay
  623.     'WorldSize 2
  624.  
  625. END SUB 'RefreshPromt
  626.  
  627.  
  628. SUB SetEnviron
  629.  
  630.     DIM x%, y%, r%, g%, b%, ob!
  631.  
  632.     orbs = 0
  633.  
  634.     RESTORE colors
  635.     FOR x% = 0 TO 15 '                                          iterate colors 0 thru 15
  636.         READ r% '                                               get red component
  637.         READ g% '                                               get green component
  638.         READ b% '                                               get blue component
  639.         clr&(x%) = _RGB32(r%, g%, b%) '                         mix color x into array
  640.     NEXT x%
  641.  
  642.     'Setup radii of orbit shells
  643.     FOR y% = 1 TO 5
  644.         RESTORE Orbits
  645.         'set orbital radii in km
  646.         FOR x% = 0 TO 19
  647.             READ ob!
  648.             orbit(x%, y%).orad = ob! * AUtokm
  649.         NEXT x%
  650.     NEXT y%
  651.  
  652. END SUB 'SetEnviron
  653.  
  654.  
  655. FUNCTION StarClass$ (var AS _BYTE, roll AS INTEGER)
  656.  
  657.     DIM dm%, rl%, sc$
  658.     SELECT CASE roll
  659.         CASE IS = 1: sc$ = "B"
  660.         CASE IS = 2: sc$ = "A"
  661.         CASE IS = 3: sc$ = "F"
  662.         CASE IS = 4: sc$ = "G"
  663.         CASE IS = 5: sc$ = "K"
  664.         CASE IS = 6: sc$ = "M"
  665.         CASE IS = 7
  666.             SELECT CASE var '                                   determine applicable DMs
  667.                 CASE 1: IF MWin THEN dm% = 4 '                  add UPP details when coded
  668.                 CASE 2 TO 5: dm% = starroll(FindParent(var)).c 'add DM of parent
  669.             END SELECT
  670.             rl% = DiceRoll%(2, 6, dm%): starroll(var).c = rl% - dm%
  671.             IF var > 1 THEN
  672.                 SELECT CASE rl%
  673.                     CASE IS <= 2: sc$ = "A"
  674.                     CASE 3 TO 4: sc$ = "F"
  675.                     CASE 5 TO 6: sc$ = "G"
  676.                     CASE 7 TO 8: sc$ = "K"
  677.                     CASE IS > 8: sc$ = "M"
  678.                 END SELECT
  679.             ELSE
  680.                 SELECT CASE rl%
  681.                     CASE IS <= 2: sc$ = "A"
  682.                     CASE 3 TO 7: sc$ = "M"
  683.                     CASE IS = 8: sc$ = "K"
  684.                     CASE IS = 9: sc$ = "G"
  685.                     CASE IS >= 10: sc$ = "F"
  686.                 END SELECT
  687.             END IF
  688.     END SELECT
  689.     StarClass$ = _TRIM$(sc$) + _TRIM$(STR$(DiceRoll%(1, 10, 0)))
  690.  
  691. END FUNCTION 'StarClass$
  692.  
  693.  
  694. FUNCTION StarSize$ (var AS _BYTE, roll AS INTEGER)
  695.  
  696.     DIM dm%, rl%, sz$
  697.  
  698.     SELECT CASE roll
  699.         CASE IS = 1: sz$ = "Ia"
  700.         CASE IS = 2: sz$ = "Ib"
  701.         CASE IS = 3: sz$ = "II"
  702.         CASE IS = 4: sz$ = "III"
  703.         CASE IS = 5
  704.             IF LEFT$(heavens(var).class, 1) = "M" THEN
  705.                 sz$ = "V"
  706.             ELSEIF LEFT$(heavens(var).class, 1) = "K" AND VAL(RIGHT$(heavens(var).class, 1)) > 4 THEN
  707.                 sz$ = "V"
  708.             ELSE
  709.                 sz$ = "IV"
  710.             END IF
  711.         CASE IS = 6: sz$ = "V"
  712.         CASE IS = 7: sz$ = "VI"
  713.         CASE IS = 8: sz$ = "D": heavens(var).class = LEFT$(heavens(var).class, 1)
  714.         CASE IS = 9
  715.             SELECT CASE var '                                   Apply size DMs
  716.                 CASE 1
  717.                 CASE 2 TO 5: dm% = starroll(FindParent(var)).s 'add DM of parent
  718.             END SELECT
  719.             rl% = DiceRoll%(2, 6, dm%): starroll(var).s = rl% - dm%
  720.             SELECT CASE rl%
  721.                 CASE 2: sz$ = "II"
  722.                 CASE 3: sz$ = "III"
  723.                 CASE 4 '                                        K5 thru M don't exist in size IV make them V
  724.                     IF LEFT$(heavens(var).class, 1) = "M" THEN
  725.                         sz$ = "V"
  726.                     ELSEIF LEFT$(heavens(var).class, 1) = "K" AND VAL(RIGHT$(heavens(var).class, 1)) > 4 THEN
  727.                         sz$ = "V"
  728.                     ELSE
  729.                         sz$ = "IV"
  730.                     END IF
  731.                 CASE 5 TO 10: sz$ = "V"
  732.                 CASE 11: sz$ = "VI"
  733.                 CASE IS >= 12: sz$ = "D": heavens(var).class = LEFT$(heavens(var).class, 1)
  734.             END SELECT
  735.     END SELECT
  736.     StarSize$ = sz$
  737.  
  738. END FUNCTION 'StarSize$
  739.  
  740.  
  741. SUB StarSystem
  742.  
  743.     'dimension local
  744.     DIM x%, rl%, sn%, sc%, sz%
  745.     SCREEN starin&: _DEST starin&
  746.     COLOR clr&(14), clr&(1)
  747.     CLS
  748.     LOCATE 1, 30
  749.     PRINT "STAR SYSTEM DETAILS"
  750.     LOCATE 3, 1
  751.     sn% = GetAnswer%("System nature: <1> solo, <2> binary, <3> trinary, <R>oll ", "123R")
  752.     IF sn% > 0 AND sn% < 4 THEN
  753.         sysnat = sn%
  754.     ELSE
  755.         rl% = DiceRoll%(2, 6, 0) '                              roll for system nature
  756.         SELECT CASE rl%
  757.             CASE IS < 8: sysnat = 1
  758.             CASE 8 TO 11: sysnat = 2
  759.             CASE 12: sysnat = 3
  760.         END SELECT
  761.     END IF
  762.  
  763.     'spectral class & size
  764.     FOR x% = 1 TO sysnat
  765.         heavens(x%).star = -1
  766.         IF x% = 1 THEN
  767.             heavens(x%).rank = 1
  768.             INPUT "Name of primary star: ", heavens(x%).nam
  769.             heavens(x%).ps.pX = 0: heavens(x%).ps.pY = 0: heavens(x%).ps.pZ = 0 'Primary Star
  770.             orbs = orbs + 1
  771.         ELSE
  772.             heavens(x%).rank = 2
  773.             PRINT
  774.             INPUT "Name of companion star: ", heavens(x%).nam
  775.             heavens(x%).parnt = heavens(1).nam
  776.             orbs = orbs + 1
  777.         END IF
  778.  
  779.         'Star Spectral Class
  780.         sc% = GetAnswer%("Spectral class: <B><A><F><G><K><M> or <R>oll ", "BAFGKMR")
  781.         heavens(x%).class = StarClass$(x%, sc%)
  782.         PRINT heavens(x%).class
  783.  
  784.         'Star Size
  785.         sz% = GetAnswer%("Star Size: <A.Ia><B.Ib><2.II><3.III><4.IV><5.V><6.VI><D> or <R>oll ", "AB23456DR")
  786.         heavens(x%).siz = StarSize$(x%, sz%)
  787.         PRINT heavens(x%).siz
  788.         MaxOrbits x%, heavens(x%).class, heavens(x%).siz
  789.     NEXT x%
  790.     PRINT "Press any key to continue"
  791.     SLEEP
  792.  
  793.     SCREEN main&
  794.     _DEST main&
  795.     CLS
  796.  
  797. END SUB 'StarSystem
  798.  
  799.  
  800. SUB SystemDisplay
  801.     DIM x%, y%, z%, tl$
  802.     tl$ = CHR$(192) + CHR$(196) + CHR$(196) + CHR$(196) '       orbit leader
  803.     PRINT _TRIM$(heavens(1).nam); " ";
  804.     SELECT CASE sysnat
  805.         CASE 1: PRINT "Solo"
  806.         CASE 2: PRINT "Binary"
  807.         CASE 3: PRINT "Trinary"
  808.     END SELECT
  809.     FOR x% = 1 TO UBOUND(heavens)
  810.         IF heavens(x%).rank = 0 THEN EXIT FOR
  811.         PRINT SPC(5 * (heavens(x%).rank - 1)); tl$;
  812.         PRINT " "; _TRIM$(heavens(x%).nam); " "; heavens(x%).class; heavens(x%).siz; "  orbital radius"; heavens(x%).orad; " density"; heavens(x%).dens; " Max orbits"; heavens(x%).maxor
  813.         FOR y% = 0 TO 21
  814.             IF orbit(y%, x%).prsnt THEN
  815.                 SELECT CASE orbit(y%, x%).class
  816.                     CASE 2: PRINT CHR$(196); " ";
  817.                     CASE 3: PRINT "I ";
  818.                     CASE 4: PRINT "H ";
  819.                     CASE 5: PRINT "O ";
  820.                     CASE 6: PRINT: EXIT FOR
  821.                 END SELECT
  822.                 'PRINT "* ";
  823.             ELSE
  824.                 PRINT "- ";
  825.             END IF
  826.         NEXT y%
  827.         PRINT
  828.     NEXT x%
  829.     PRINT: PRINT
  830.     FOR z% = 1 TO orbs
  831.         PRINT z%; " "; heavens(z%).nam; " "; heavens(z%).siz; heavens(z%).class; " orbital radius="; heavens(z%).orad; " from "; heavens(z%).parnt
  832.     NEXT z%
  833.  
  834. END SUB 'SystemDisplay
  835.  
  836.  
  837. SUB WorldSize (in AS INTEGER)
  838.  
  839.     'determines world radius heavens(x).radi in km
  840.     DIM s AS INTEGER
  841.     INPUT "UWP Size ", s
  842.     heavens(in).radi = (((s * 1000) + (DiceRoll%(2, 6, -7) * 100) + (DiceRoll%(2, 6, -7) * 10) + DiceRoll%(2, 6, -7)) * 1.6) / 2
  843.  
  844. END SUB 'WorldSize
  845.  
  846.  
  847. FUNCTION YesOrNo$ (question AS STRING)
  848.  
  849.     '-------------------------QUERY------------------------------------------------------CLEARED
  850.     ' FUNCTION: YesOrNo$
  851.     '
  852.     ' Purpose:
  853.     ' Display a question and wait for the user to type Y or N returning result to
  854.     ' calling routine for further processing. A standard library function that is used
  855.     ' to verify deletion of an active PC.
  856.     '
  857.     ' Passed Variables:
  858.     ' question sends displayed prompt for Yes or No choice
  859.     '
  860.     '------------------------------------------------------------------------------------
  861.  
  862.     DIM answer$
  863.     PRINT question;
  864.     DO
  865.         answer$ = UCASE$(INKEY$)
  866.     LOOP UNTIL answer$ = "Y" OR answer$ = "N"
  867.     PRINT answer$
  868.  
  869.     YesOrNo$ = answer$
  870.  
  871. END FUNCTION 'YesOrNo$
  872.  
  873.  
  874.  
  875. SUB EmptyOrbits
  876.  
  877.     DIM rl%, dm%
  878.  
  879.     rl% = DiceRoll%(1, 6, 0)
  880.     SELECT CASE rl%
  881.         CASE 1 TO 4
  882.         CASE 5, 6
  883.  
  884.     END SELECT
  885.  
  886. END SUB 'EmptyOrbits

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Program drops when putting an image in another image
« Reply #1 on: August 05, 2019, 10:34:05 am »
Hi Andy,

Do you really want the image drawn inside the other image or do you want the image drawn on screen placed over and "inside" the box of other image?

Apologies if I am misunderstanding and asking stupid question.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Program drops when putting an image in another image
« Reply #2 on: August 05, 2019, 11:32:22 am »
Hi. This problems can do _DISPLAY. If is somewhere in program used, it can be this. I look to it.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Program drops when putting an image in another image
« Reply #3 on: August 05, 2019, 11:48:37 am »
So. Is this correct program area?

                        IF orbit(z%, y%).prsnt = 0 OR orbit(z%, y%).pin > 0 THEN '           Check box greyed out or available
                            'chk& = _COPYIMAGE(chkbx&)
                            COLOR , clr&(8): CLS
                            _PUTIMAGE (3, 3)-(20, 20), chk&, chkbx&                                                           Here is none valid image in chk&. chk& is empty variable.
                            IF orbit(z%, y%).pin > 0 THEN
                                _PRINTSTRING (4, 4), _TRIM$(STR$(orbit(z%, y%).pin)), chkbx&
                            END IF
                        END IF

                        SCREEN plcmnt&                                                                                                   Here, if is image inserted, so program wait for nothing and draw this empty screen
                        _DEST plcmnt&                                                                                                   
                        IF orbit(z%, y%).class > 1 THEN
                            _PUTIMAGE (((heavens(y%).rank - 1) * 40) + (56 * z%) + 16, (48 + ((y% - 1) * 80))), chkbx&, plcmnt&   


So your problem is - insert to chk& valid image. As it see, so chkbx& is next image, visible after inserting to plcmnt&.  For better solution this problem insert to program PRINT chk&: SLEEP. Value for valid images must be always < -1.
« Last Edit: August 05, 2019, 12:08:08 pm by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Program drops when putting an image in another image
« Reply #4 on: August 05, 2019, 12:25:24 pm »
First you insert Chk& to Chkbx&, if is condition "IF orbit"  valid (try BEEP insert to this condition, to be sure, that this option occur), for me it see as you copy default (current) screen area to new image chkbx& and then after this condition, you insert chkbx& to plcmnt&.

I read your code again. Just ask. You know that you should only call SCREEN if you want to see the screen. To work on the screen, even if it is not visible, just use _DEST for draw the artwork,  _SOURCE to read the colors from this unvisible screen. And when is all done, use SCREEN for view. PUTIMAGE work with it, without SCREEN need.
« Last Edit: August 05, 2019, 12:39:53 pm by Petr »

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Program drops when putting an image in another image
« Reply #5 on: August 05, 2019, 01:03:31 pm »
just FYI doesn't crash for me. When does it crash for you?
Granted after becoming radioactive I only have a half-life!

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Program drops when putting an image in another image
« Reply #6 on: August 05, 2019, 01:04:53 pm »
Do you really want the image drawn inside the other image or do you want the image drawn on screen placed over and "inside" the box of other image?

Yes, I'm trying to get the box to show a grey core while still showing it original color as a border. That way I still have a visual reference for placing additional planets. I thought I could preload the chkbx& image with chk& in the middle and not have to worry about positioning chk& in plcmnt& over the specific chkbx&, since the overall algorithm already does that pretty well. Why it kills the program without any error message and a brief delay is what I find a mystery.

So. Is this correct program area?

So your problem is - insert to chk& valid image. As it see, so chkbx& is next image, visible after inserting to plcmnt&.  For better solution this problem insert to program PRINT chk&: SLEEP. Value for valid images must be always < -1.

Yes, that's the part that gives me the trouble.
I thought that _COPYIMAGE would make a copy with a valid handle, I think I don't quite understand the dynamics of images yet...

In looking at your response I realized I hadn't set _DEST for chk& and then back to chkbx& before putting the image, even though it did what it was supposed to do briefly. So I made that change thinking it might improve stability.

                        IF orbit(z%, y%).prsnt = 0 OR orbit(z%, y%).pin > 0 THEN '           Check box greyed out or available
                            chk& = _COPYIMAGE(chkbx&)
                            _DEST chk&: COLOR , clr&(8): CLS: _DEST chkbx&
                            _PUTIMAGE (3, 3)-(20, 20), chk&, chkbx&
                            IF orbit(z%, y%).pin > 0 THEN
                                _PRINTSTRING (4, 4), _TRIM$(STR$(orbit(z%, y%).pin)), chkbx&
                            END IF
                        END IF

After doing that the program hung in there a couple seconds or so longer before dropping, but it still dropped. I'm stymied, and considering just going with the number in the box and forgetting the fancy stuff.

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Program drops when putting an image in another image
« Reply #7 on: August 05, 2019, 01:06:23 pm »
just FYI doesn't crash for me. When does it crash for you?
It happens immediately after I set a planet in an orbit and the display in question becomes active.

Maybe I should try it on a different machine, but then that makes my laptop somewhat less than useful to me...
« Last Edit: August 05, 2019, 01:08:16 pm by OldMoses »

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Program drops when putting an image in another image
« Reply #8 on: August 05, 2019, 01:09:04 pm »
where does that happen? I get through all the questions and naming bits. then the program is ended by the 'END' statement


interesting output though.
though with my secondary stars density I think my system is becoming a Black Hole! though with its orbital radius it must be so far away I may not have to worry.
« Last Edit: August 05, 2019, 01:14:41 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Program drops when putting an image in another image
« Reply #9 on: August 05, 2019, 01:25:19 pm »
Do it again, but type "Y" for GG present. Then you'll get the screen where you tab through the available orbits. Hit <enter> to choose an orbit for the GG listed at the top (it'll ask for a name), then it should deposit a number in the chosen box and put a grey core in the box, that's when the program drops for me.
« Last Edit: August 05, 2019, 01:30:26 pm by OldMoses »

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Program drops when putting an image in another image
« Reply #10 on: August 05, 2019, 01:29:25 pm »
interesting output though.
though with my secondary stars density I think my system is becoming a Black Hole! though with its orbital radius it must be so far away I may not have to worry.

That output screen is mostly a debugging leftover, but I was surprised by the density too. I think it's because the mass of a white dwarf is concentrated in such a small volume. It's a much larger star compressed into an Earth sized orb. It's kind of the last whistle stop before a black hole.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Program drops when putting an image in another image
« Reply #11 on: August 05, 2019, 03:28:17 pm »
Do it again, but type "Y" for GG present. Then you'll get the screen where you tab through the available orbits. Hit <enter> to choose an orbit for the GG listed at the top (it'll ask for a name), then it should deposit a number in the chosen box and put a grey core in the box, that's when the program drops for me.

still works for me, doesn't always seem to put the correct number of boxes though, seems to place an extra one sometimes, get 5 boxes when I press 4. Both TAB and RIGHT ARROW move the selected box. but can only move right until it cycles back no left movement. but no crashing.
Granted after becoming radioactive I only have a half-life!

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Program drops when putting an image in another image
« Reply #12 on: August 05, 2019, 05:25:26 pm »
still works for me, doesn't always seem to put the correct number of boxes though, seems to place an extra one sometimes, get 5 boxes when I press 4. Both TAB and RIGHT ARROW move the selected box. but can only move right until it cycles back no left movement. but no crashing.

It is going to take some tweaking to get the orbit handler right. In some cases it appears to do it wrong, in others it is doing an orbit restriction for near companion stars that have their own orbiting bodies. I have to chase down all the permutations, if that's even possible. I tried a back arrow routine and it got really squirrely, so I abandoned that for the time being.

I think I'm going to have to do a test bed program to see if I can duplicate the issue, and if it doesn't happen to anyone else, I'll have to take a hard look at my machine.

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Program drops when putting an image in another image
« Reply #13 on: August 06, 2019, 07:12:11 am »
In essence, this is what I'm attempting to do, without all the other program stuff to wade through.

This worked fine until I put it in the DO...LOOP, at which point it also crashed. So I put a limit on it and watched with Task Manager.

It uses increasing amounts of memory, up to around 50MB and then quits.

Do I need to use _FREEIMAGE? I thought it wouldn't be an issue as I am using the same handle variables each time.

EDIT: YES!! _FREEIMAGE stopped it. I think the mystery is solved, thank you all for your attention. Still learning here...

Code: QB64: [Select]
  1. Main& = _NEWIMAGE(200, 200, 32)
  2. Inner& = _NEWIMAGE(24, 24, 32)
  3. SCREEN Main&
  4. _DEST Main&
  5. COLOR _RGBA32(255, 255, 255, 255), _RGBA32(127, 127, 127, 255)
  6.     PRINT "Let us make a box."
  7.     PRINT "Yes, let us."
  8.     _DEST Inner&
  9.     COLOR , _RGBA32(0, 0, 255, 255)
  10.     CLS
  11.     _DEST Main&
  12.     _PUTIMAGE (100, 100), Inner&, Main&
  13.     temp& = _COPYIMAGE(Inner&)
  14.     _DEST temp&
  15.     COLOR , _RGBA32(255, 0, 0, 255)
  16.     CLS
  17.     _DEST Inner&
  18.     _PUTIMAGE (4, 4)-(19, 19), temp&, Inner&
  19.     _DEST Main&
  20.     _FREEIMAGE (temp&)
  21.     _PUTIMAGE (50, 100), Inner&, Main&
  22.     x = x + 1
  23.     LOCATE 12, 1
  24.     PRINT "Loop: "; x
  25.     _DISPLAY
  26.     'SLEEP
  27.     CLS
  28.     _LIMIT 2000
  29.  
  30.  
« Last Edit: August 06, 2019, 07:24:09 am by OldMoses »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Program drops when putting an image in another image
« Reply #14 on: August 06, 2019, 07:25:39 am »
Here's your issue and solution:

Code: QB64: [Select]
  1. Main& = _NEWIMAGE(200, 200, 32)
  2. Inner& = _NEWIMAGE(24, 24, 32)
  3. SCREEN Main&
  4. _DEST Main&
  5. COLOR _RGBA32(255, 255, 255, 255), _RGBA32(127, 127, 127, 255)
  6.     PRINT "Let us make a box."
  7.     PRINT "Yes, let us."
  8.     _DEST Inner&
  9.     COLOR , _RGBA32(0, 0, 255, 255)
  10.     CLS
  11.     _DEST Main&
  12.     _PUTIMAGE (100, 100), Inner&, Main&
  13.     IF temp& THEN _FREEIMAGE temp& 'If there's already an image called temp&, free it OR....
  14.     temp& = _COPYIMAGE(Inner&) 'Here you're making a copy of an image, so it's a new image in memory.
  15.     '                              If you make a copy on a copy machine, what happens to the paper in your print drawer?
  16.     '                              It eventually runs out and you get an ERROR!
  17.     '                           That's what is going to happen here... You'll keep making copy after copy after copy of the image
  18.     '                              until you use up all of your memory and crash.
  19.     _DEST temp&
  20.     COLOR , _RGBA32(255, 0, 0, 255)
  21.     CLS
  22.     _DEST Inner&
  23.     _PUTIMAGE (4, 4)-(19, 19), temp&, Inner&
  24.     _DEST Main&
  25.     _PUTIMAGE (50, 100), Inner&, Main&
  26.     x = x + 1
  27.     LOCATE 12, 1
  28.     PRINT "Loop: "; x
  29.     _DISPLAY
  30.     'SLEEP
  31.     CLS
  32.     _LIMIT 2000
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!