1global { menu_mode = 'title' } 2 3level_reset = function(win, notitle) 4 key_empty() 5 if win and not demo_mode then 6 history_store(win) 7 end 8 happy_end_off = 0 9 sprite.copy(sprite.screen(), offscreen) 10 menu_select('level_out', 0) 11 level_load() 12 local st = level_stat() 13 local bant 14 history = {} 15 if demo_mode then 16 bant = sprite.text(fn2, stead.string.format(_("demo:DEMO").." %d", nr_level + 1), 'red', 1) 17 elseif notitle then 18 bant = false 19 else 20 if win then 21 bant = sprite.text(fn2, stead.string.format(_("score:SCORE").." %d", nr_score), 'red', 1) 22 else 23 bant = sprite.text(fn2, stead.string.format(_("try:TRIES").." %d", st.die), 'red', 1) 24 end 25 end 26 demo_mode = false 27 edit_mode = false 28 nr_score = 0; 29 sprite.fill(banner, 'black') 30 if bant then 31 local w, h = sprite.size(bant) 32 sprite.draw(bant, banner, (scr_w - w) / 2, 0) 33 sprite.free(bant) 34 end 35 timer:set(FAST_TIMER) 36 if level_after then 37 level_after() 38 level_after = false 39 end 40end 41 42level_movein = function() 43 local st = level_stat() 44 local bant 45 if not demo_mode then 46 if nr_level == nr_levels then 47 bant = sprite.text(fn2, stead.string.format(_("end:THE END")), 'red', 1) 48 else 49 bant = sprite.text(fn2, stead.string.format(_("level:LEVEL").." %d", nr_level + 1), 'red', 1) 50 end 51 else 52 bant = sprite.text(fn2, stead.string.format(_("demo:DEMO").." %d", nr_level + 1), 'red', 1) 53 end 54 local w, h = sprite.size(bant) 55 sprite.fill(banner, 'black') 56 sprite.draw(bant, banner, (scr_w - w) / 2, 0) 57 sprite.free(bant) 58 59 sound.play(sounds[SLEVELIN], 3) 60 timer:set(FAST_TIMER) 61 menu_select('level_in', scr_h + h) 62end 63 64level_ready = function() 65 menu_select(false) 66 level_render(sprite.screen()); 67 timer:set(TIMER) 68end 69 70level_choose = function() 71 if nr_level >= nr_levels then 72 nr_level = 0 73 end 74 menu_select('level_select', true) 75 level_load() 76 77 select_time = 0 78 79 sprite.fill(offscreen, 'black') 80 level_map(offscreen, (scr_w - 256) / 2, (scr_h - 256) / 2) 81 82 local st = level_stat() 83 local lev = sprite.text(fn, stead.string.format(_("level:LEVEL").." %d", nr_level + 1), 'red', 1) 84 local w, h = sprite.size(lev) 85 86 sprite.fill(offscreen, (scr_w - 256) / 2, (scr_h - 256) / 2 - h - h / 2, 256, h, 'black'); 87 sprite.draw(lev, offscreen, (scr_w - 256) / 2 + (256 - w) / 2, (scr_h - 256) / 2 - h - h / 2); 88 sprite.free(lev) 89 sprite.fill(offscreen, (scr_w - 256) / 2, (scr_h - 256) / 2 + 256 + h /2, 256, h, 'black'); 90 91 if st.completed > 0 then 92 lev = sprite.text(fn, stead.string.format(_("completed:COMPLETED"), st.completed), 'red', 1) 93 local w, h = sprite.size(lev) 94 sprite.draw(lev, offscreen, (scr_w - 256) / 2, (scr_h - 256) / 2 + 256 + h / 2); 95 sprite.free(lev) 96 97 lev = sprite.text(fn, stead.string.format(_("score:SCORE").." %d", st.score), 'red', 1) 98 local w, h = sprite.size(lev) 99 sprite.draw(lev, offscreen, (scr_w - 256) / 2 + (256 - w), (scr_h - 256) / 2 + 256 + h / 2); 100 sprite.free(lev) 101 elseif st.die > 0 then 102 lev = sprite.text(fn, stead.string.format(_("try:TRIES").." %d", st.die), 'red', 1) 103 local w, h = sprite.size(lev) 104 sprite.draw(lev, offscreen, (scr_w - 256) / 2 + (256 - w) / 2, (scr_h - 256) / 2 + 256 + h / 2); 105 sprite.free(lev) 106 end 107 108 sprite.copy(offscreen, sprite.screen()) 109 if (nr_level + 1) ~= nr_levels then 110 sprite.copy(ra_spr, sprite.screen(), scr_w - 24 - 16, 256 - 16) 111 end 112 113 if nr_level > 0 then 114 sprite.copy(la_spr, sprite.screen(), 24, 256 - 16) 115 end 116 117 timer:set(FAST_TIMER / 2) 118end 119 120MAP_SPEED = 32 121 122demo_enter = function() 123 local l 124 local ll = {} 125 for l = 0, nr_levels -1 do 126 if history_check(l) then 127 stead.table.insert(ll, l) 128 end 129 end 130 if #ll == 0 then return end 131 menu_select('demo', false) 132 nr_level = ll[rnd(#ll)] 133 level_load() 134 level_reset(false, true) 135 level_after = title_enter 136 history_load() 137 demo_mode = true 138end 139 140function menu_select(name, var) 141 menu_mode = name 142 if name then 143 _G[name..'_mode'] = var 144 end 145end 146 147function menu_title_mode() 148 title_time = title_time + 1 149 if title_time > 300 then 150 title_time = 0 151 demo_enter() 152 return true 153 end 154 if title_mode ~= true then 155 title_mode = title_mode - 32 156 if title_mode < 32 then title_mode = 32 end 157 title_render(sprite.screen(), 0, title_mode); 158 end 159 if title_mode == 32 then 160 title_mode = true 161 local s 162 if total_score and total_score > 0 then 163 s = sprite.text(tfn, stead.string.format(_("score:SCORE").." %d", total_score), '#00ff00', 1) 164 local w, h = sprite.size(s) 165 sprite.draw(s, sprite.screen(), scr_w - w - 2, 2); 166 sprite.free(s) 167 end 168 169 local s = sprite.text(tfn, stead.string.format(_("version:Version").." 1.4"), '#0000ff', 1) 170 local w, h = sprite.size(s) 171 172 sprite.draw(s, sprite.screen(), 2, 2); 173 sprite.free(s) 174 end 175 if title_mode == true and is_anykey() then 176 key_empty() 177 bank_choose() 178 sound.play(sounds[SPHASER], 3) 179 return true 180 end 181 local w,h = sprite.size(press_any_key) 182 if title_mode == true then 183 sprite.fill(sprite.screen(), 184 (scr_w - w) / 2, scr_h - h * 2, w, h, 'black'); 185 if stead.math.floor(title_time / 10) % 2 ~= 0 then 186 sprite.draw(press_any_key, sprite.screen(), 187 (scr_w - w) / 2, scr_h - h * 2); 188 end 189 end 190 return true 191end 192 193function menu_level_in_mode() 194 local bw,bh = sprite.size(banner) 195 if level_in_mode < 0 then level_in_mode = 0 end 196 sprite.copy(banner, sprite.screen(), 0, level_in_mode - bh) 197 level_render(sprite.screen(), level_in_mode) 198 if level_in_mode == 0 then 199 level_ready() 200 return true 201 end 202 level_in_mode = level_in_mode - 8 203 return true 204end 205 206function menu_level_out_mode() 207 local bw,bh = sprite.size(banner) 208 if level_out_mode >= scr_h + bh then level_out_mode = scr_h + bh end 209 sprite.fill(sprite.screen(), 0, level_out_mode - 8 - bh, scr_h, level_out_mode, 'black') 210 sprite.copy(banner, sprite.screen(), 0, level_out_mode - bh); 211 sprite.copy(offscreen, sprite.screen(), 0, level_out_mode) 212 if level_out_mode == scr_h + bh then 213 level_movein() 214 return true 215 end 216 level_out_mode = level_out_mode + 8 217 return true 218end 219 220function bank_choose() 221 select_time = 0 222 sprite.fill(sprite.screen(), 'black') 223 sprite.copy(sprite.screen(), offscreen); 224 local sw, sh = banks[nr_bank].sw, banks[nr_bank].sh 225 sprite.draw(banks[nr_bank].spr, offscreen, (scr_w - sw) / 2, (scr_h - sh)/ 2); 226 sprite.copy(offscreen, sprite.screen()); 227 if nr_bank < #banks then 228 sprite.copy(ra_spr, sprite.screen(), scr_w - 24 - 16, 256 - 16) 229 end 230 if nr_bank > 1 then 231 sprite.copy(la_spr, sprite.screen(), 24, 256 - 16) 232 end 233 sw, sh = sprite.size(select_maps_spr) 234 sprite.draw(select_maps_spr, sprite.screen(), (scr_w - sw)/2, 32) 235 menu_select('bank_select', true) 236end 237 238function menu_bank_select_mode() 239 if bank_select_mode ~= true then 240 local sw, sh = banks[nr_bank].sw, banks[nr_bank].sh 241 242 local h = (scr_h - sh) / 2 243 244 if bank_select_mode < 0 then 245 sprite.fill(sprite.screen(), scr_w + bank_select_mode, h, sw, sh, 'black') 246 bank_select_mode = bank_select_mode - MAP_SPEED 247 sprite.copy(offscreen, sprite.screen(), bank_select_mode, 0) 248 if bank_select_mode < -scr_w + (scr_w - sw )/ 2 then 249 bank_select_mode = -scr_w + (scr_w - sw )/ 2 250 end 251 sprite.draw(banks[nr_bank].spr, sprite.screen(), scr_w + bank_select_mode, h); 252 else 253 sprite.fill(sprite.screen(), bank_select_mode - sw, h, sw, sh, 'black') 254 bank_select_mode = bank_select_mode + MAP_SPEED 255 sprite.copy(offscreen, sprite.screen(), bank_select_mode, 0) 256 if bank_select_mode > (scr_w + sw )/ 2 then 257 bank_select_mode = (scr_w + sw )/ 2 258 end 259 sprite.draw(banks[nr_bank].spr, sprite.screen(), bank_select_mode - sw, h); 260 end 261 262 if bank_select_mode <= -scr_w + (scr_w - sw )/ 2 or bank_select_mode >= (scr_w + sw )/ 2 then 263 bank_choose(); 264 end 265 266 end 267 if bank_select_mode == true then 268 if (is_key 'down' or is_key 'right') and nr_bank < #banks then 269 _G["_selected_level_"..banks[nr_bank].name] = selected_level -- old selection 270 nr_bank = nr_bank + 1 271 bank_select_mode = -MAP_SPEED 272 elseif (is_key 'up' or is_key 'left') and nr_bank > 1 then 273 _G["_selected_level_"..banks[nr_bank].name] = selected_level -- old selection 274 nr_bank = nr_bank - 1 275 bank_select_mode = MAP_SPEED 276 elseif is_return() then 277 bank_load() 278 key_empty() 279 level_choose() 280 return true 281 end 282 if not select_time then select_time = 0 end 283 select_time = select_time + 1 284 if select_time >= 1000 then select_time = 0 end 285 local w,h = sprite.size(press_enter) 286 sprite.fill(sprite.screen(), (scr_w - w) / 2, scr_h - h * 2, w, h, 'black'); 287 if stead.math.floor(select_time / 10) % 2 ~= 0 then 288 sprite.draw(press_enter, sprite.screen(), (scr_w - w) / 2, scr_h - h * 2); 289 end 290 end 291 return true 292end 293 294function menu_level_select_mode() 295 local level_select = level_select_mode 296 if level_select ~= true then -- scroll 297 sprite.copy(offscreen, sprite.screen(), level_select, 0) 298 if level_select < 0 then 299 sprite.fill(sprite.screen(), level_select + scr_w, 0, MAP_SPEED, scr_h, 'black') 300 level_map(sprite.screen(), scr_w + level_select, (scr_h - 256) / 2) 301 sprite.fill(sprite.screen(), scr_w + level_select + 256, 0, MAP_SPEED, scr_h, 'black') 302 level_select = level_select - MAP_SPEED 303 else 304 sprite.fill(sprite.screen(), level_select, 0, MAP_SPEED, scr_h, 'black') 305 level_map(sprite.screen(), level_select - 256, (scr_h - 256) / 2) 306 sprite.fill(sprite.screen(), level_select - 256 - MAP_SPEED, 0, MAP_SPEED, scr_h, 'black') 307 level_select = level_select + MAP_SPEED 308 end 309 if level_select < -384 or level_select > 400 then 310 level_choose() 311 level_select = true 312 end 313 level_select_mode = level_select 314 end 315 316 if level_select == true then 317 select_time = select_time + 1 318 if select_time >= 1000 then select_time = 0 end 319 local w,h = sprite.size(press_enter) 320 sprite.fill(sprite.screen(), (scr_w - w) / 2, scr_h - h * 2, w, h, 'black'); 321 if stead.math.floor(select_time / 10) % 2 ~= 0 then 322 sprite.draw(press_enter, sprite.screen(), 323 (scr_w - w) / 2, scr_h - h * 2); 324 end 325 if is_key 'down' and nr_level < nr_levels - 1 then 326 nr_level = nr_level + 10 327 if nr_level >= nr_levels then 328 nr_level = nr_levels - 1 329 end 330 selected_level = nr_level 331 level_select_mode = -MAP_SPEED 332 level_load() 333 elseif is_key 'right' and nr_level < nr_levels - 1 then 334 nr_level = nr_level + 1 335 selected_level = nr_level 336 level_select_mode = -MAP_SPEED 337 level_load() 338 elseif is_key 'up' and nr_level > 0 then 339 nr_level = nr_level - 10 340 if nr_level < 0 then 341 nr_level = 0 342 end 343 selected_level = nr_level 344 level_select_mode = MAP_SPEED 345 level_load() 346 elseif is_key 'left' and nr_level > 0 then 347 nr_level = nr_level - 1 348 selected_level = nr_level 349 level_select_mode = MAP_SPEED 350 level_load() 351 elseif is_return() then 352 selected_level = nr_level 353 _G["_selected_level_"..banks[nr_bank].name] = selected_level -- old selection 354 sprite.fill(sprite.screen(), 'black') 355 stop_music(); 356 level_load() 357 level_movein() 358 return true 359 elseif is_demo() and history_check(nr_level) then 360 sprite.fill(sprite.screen(), 'black') 361 level_load() 362 history_load() 363 level_movein() 364 level_after = level_choose 365 demo_mode = true 366 return true 367 elseif is_edit() then 368 sprite.fill(sprite.screen(), 'black') 369 level_load() 370 level_movein() 371 edit_mode = true 372 return true 373 end 374 end 375 return true 376end 377 378function menu_demo_mode() 379end 380 381title = { 382" : : ::: : : ::: :: ", 383" :: :: : :: : : : : ", 384" : : : : : :: :: :: ", 385" : : : : : : : : ", 386" : : ::: : : ::: : : ", 387" ", 388" #### ### ## #### ", 389" ## ## ## ## ## ## ## ", 390" #### ## ## ## ## ## ", 391" ## ## ## ## ## ## ## ", 392" #### ### #### #### ", 393}; 394title_text = { 395" ИНСТРУКЦИЯ:", 396" Ваша задача: собрать все алмазы в лабиринте и перейти", 397"в следующий.", 398" Попадаться в руки бабочкам и минам, а также оказаться", 399"под падающим камнем или алмазом опасно для жизни.", 400" Ваших сил хватит для толкания камней в любом", 401"направлении. Остальное поймете сами по ходу игры.", 402" ", 403" Программа была написана А. В. Меленьтевым в 1989 г.", 404"для БК-0010. Оформлять игру помог Н. Валтер.", 405" Порт игры под INSTEAD выполнен П. А. Косых в 2015 г.", 406} 407 408title_text_en = { 409" INSTRUCTIONS:", 410" ", 411" Your mission: got all jewels on the level. Avoid butterfiles", 412" mines and falling stones.", 413" You are strong enougth to move stones in any direction.", 414" Good luck!", 415" ", 416" Original code was written by A. V. Melentiev in 1989.", 417"for BK-0010 computers. N. Walter helped him.", 418" Ported to INSTEAD by P.A. Kosyh in 2015.", 419} 420happy_end_map = 421 422{ 423"::::::::::::::::", 424" $", 425" ", 426" ", 427" ", 428"+ @@ ", 429"::::::::::::::::", 430"% &", 431" ", 432" ", 433" ", 434" ", 435" ", 436" ", 437" ", 438" ", 439} 440 441happy_end_text = { 442"Поздравляю!", 443"Вы прошли эту непростую игру!", 444" ", 445"Надеюсь, она понравилась вам также", 446"как и мне 25 лет назад...", 447" ", 448"Кстати, вы можете смотреть записанные", 449"демонстрации, нажав на клавишу D", 450"из режима выбора уровня", 451"или прямо во время игры", 452" ", 453"Вы можете посмотреть", 454"другие INSTEAD игры по адресу:", 455"http://instead.syscall.ru", 456" ", 457"Выражаю благодарность и признательность:", 458" ", 459"Жене и детям", 460"за понимание", 461" ", 462"А. В. Мелентьеву и Н. Валтеру", 463"за Bolder Dash для БК-0010", 464" ", 465"Леониду Брухису", 466"За эмулятор БК-0010 для Unix", 467" ", 468"Всем разработчикам БК-0010", 469" ", 470"Без всех этих людей", 471"ремейк игры был бы невозможен...", 472" ", 473" ", 474"В игре использованы треки:", 475" ", 476"Chip never dies от ajaxlemon", 477"IBM 486 66Mhz от ExcelioN", 478" ", 479" ", 480" ", 481" ", 482"КОНЕЦ", 483" ", 484" ", 485" ", 486" ", 487" Косых Петр 2015", 488} 489 490happy_end_text_en = { 491"Congratulations!", 492"You win!", 493" ", 494"I hope you like this small game", 495"It was written 25 years ago...", 496" ", 497"Btw, you may run demo of any level", 498"Just press D key from map selection", 499"menu or just in game", 500" ", 501"Visit http://instead.syscall.ru", 502"for other INSTEAD games", 503" ", 504"Thanks to:", 505" ", 506"My wife and childrens", 507" ", 508"A. V. Melentiev and N. Walter", 509"for they Bolder Dash game", 510" ", 511"Leonid A. Broukhis", 512"for БК-0010 emulator", 513" ", 514"And all BK-0010 developers!", 515" ", 516"Thank you for playing this game!", 517" ", 518" ", 519"Music:", 520" ", 521"Chip never dies by ajaxlemon", 522"IBM 486 66Mhz by ExcelioN", 523" ", 524" ", 525" ", 526" ", 527"THE END", 528" ", 529" ", 530" ", 531" ", 532" Peter Kosyh 2015", 533} 534happy_end_spr = {} 535happy_end_render = function() 536 if not happy_end_off then 537 happy_end_off = 0 538 end 539 local off = happy_end_off 540 local het = happy_end_text 541 if LANG ~= 'ru' then 542 het = happy_end_text_en 543 end 544 local k,v 545 local fh = sprite.font_height(tfn) 546 local off2 = off 547 local bh = scr_h / 2 548 local delta = bh - off 549 local start = 1 550 local start_y = scr_h 551 if not happy_end_spr_w then 552 happy_end_spr_w = 0 553 happy_end_spr_h = 0 554 for k,v in ipairs(het) do 555 local w,h = sprite.text_size(tfn, v) 556 if w > happy_end_spr_w then 557 happy_end_spr_w = w 558 end 559 happy_end_spr_h = happy_end_spr_h + h 560 end 561 end 562 if delta < 0 then 563 for k,v in ipairs(het) do 564 if delta + fh >= 0 then 565 start = k 566 start_y = delta 567 break 568 end 569 if happy_end_spr[k] then 570 sprite.free(happy_end_spr[k]) 571 happy_end_spr[k] = nil 572 end 573 delta = delta + fh 574 end 575 else 576 start_y = delta 577 end 578--prite.fill(sprite.screen(), (scr_w - happy_end_spr_w)/2, scr_h /2, happy_end_spr_w, scr_h / 2, "black") 579 local ox = (scr_w - happy_end_spr_w)/2 580 for k = start, #het do 581 v = het[k] 582 if v == '' then v = ' ' end 583 if not happy_end_spr[k] then 584 happy_end_spr[k] = sprite.text(tfn, v, '#ff0000', 1) 585 end 586 local w, h = sprite.size(happy_end_spr[k]) 587 if delta < 0 and k == start then 588 sprite.draw(happy_end_spr[k], 0, -delta, w, h + delta, sprite.screen(), ox + (happy_end_spr_w - w)/2, scr_h /2 + start_y - delta) 589 else 590 sprite.draw(happy_end_spr[k], sprite.screen(), ox + (happy_end_spr_w - w)/2, scr_h/2 + start_y) 591 end 592 start_y = start_y + fh 593 if start_y >= scr_h then 594 break 595 end 596 end 597 happy_end_off = happy_end_off + 2 598 if happy_end_off > (happy_end_spr_h + bh) then 599 happy_end_off = 0 600 end 601end 602 603title_render = function(where, ox, oy) 604 local char2map = { 605 [' '] = 0, 606 [':'] = 1, 607 ['@'] = 2, 608 ['$'] = 3, 609 ['+'] = 4, 610 ['#'] = 5, 611 ['&'] = 6, 612 ['%'] = 7, 613 } 614 local x 615 local y 616 for y = 1, #title do 617 for x = 1, 32 do 618 local c = string.sub(title[y], x, x); 619 c = char2map[c] 620 sprite.copy(sprites_small[c + 1], where, 621 ox + (x - 1) * 16, oy + (y - 1) * 16); 622 end 623 end 624 sprite.fill(where, 0, oy + #title * 16, 512, 32, 'black'); 625 sprite.fill(where, 0, oy - 32, 512, 32, 'black'); 626 local k,v 627 if not title_tspr then 628 tspr_width = 0 629 title_tspr = {} 630 local t = title_text_en 631 if LANG == "ru" then 632 t = title_text 633 end 634 for k,v in ipairs(t) do 635 title_tspr[k] = sprite.text(tfn, v, '#00ff00', 1) 636 local w, h = sprite.size(title_tspr[k]) 637 if w > tspr_width then tspr_width = w end 638 end 639 end 640 local dh = #title * 16 + 16 641 local fh = sprite.font_height(tfn) 642 fh = fh + stead.math.floor(fh / 3) 643 for k, v in ipairs(title_tspr) do 644 sprite.fill(where, ox, oy + dh + (k - 1) * fh, scr_w, h, 'black') 645 end 646 local dy 647 for k, v in ipairs(title_tspr) do 648 local w, h = sprite.size(v) 649 dy = oy + dh + (k - 1) * fh 650 sprite.draw(v, where, ox + (scr_w - tspr_width) / 2, dy) 651 end 652 sprite.fill(where, 0, dy + fh, scr_w, 32, 'black') 653end 654 655title_enter = function() 656 set_music('snd/chipneve.xm') 657 menu_select('title', scr_h) 658 demo_mode = false 659 edit_mode = false 660 title_time = 0 661 timer:set(FAST_TIMER) 662-- sound.stop(-1) 663 sound.play(sounds[STRILL], 3) 664 level_after = false 665 key_empty() 666 local k,v 667 668 local score = 0 669 670 for k,v in pairs(bank_stat()) do 671 if v.score then 672 score = score + v.score 673 end 674 end 675 total_score = score 676end 677