553 * change that when setting stuff, copy back on clicking 'OK' */ |
553 * change that when setting stuff, copy back on clicking 'OK' */ |
554 memcpy(&_opt_mod_temp, _opt_ptr, sizeof(GameOptions)); |
554 memcpy(&_opt_mod_temp, _opt_ptr, sizeof(GameOptions)); |
555 AllocateWindowDesc(&_game_difficulty_desc); |
555 AllocateWindowDesc(&_game_difficulty_desc); |
556 } |
556 } |
557 |
557 |
558 typedef uint PatchEntry; |
558 static const char *_patches_ui[] = { |
559 |
559 "vehicle_speed", |
560 static const PatchEntry _patches_ui[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; |
560 "status_long_date", |
561 static const PatchEntry _patches_construction[] = {13, 14, 15, 16, 17, 18}; |
561 "show_finances", |
562 static const PatchEntry _patches_stations[] = {43, 44, 45, 46, 47, 48, 49, 50, 51}; |
562 "autoscroll", |
563 static const PatchEntry _patches_economy[] = {52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62}; |
563 "reverse_scroll", |
564 static const PatchEntry _patches_ai[] = {63, 64, 65, 66, 67, 68}; |
564 "errmsg_duration", |
565 static const PatchEntry _patches_vehicles[] = { |
565 "toolbar_pos", |
566 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, |
566 "window_snap_radius", |
567 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, |
567 "invisible_trees", |
568 }; |
568 "population_in_label", |
|
569 "map_x", |
|
570 "map_y", |
|
571 "link_terraform_toolbar", |
|
572 }; |
|
573 |
|
574 static const char *_patches_construction[] = { |
|
575 "build_on_slopes", |
|
576 "extra_dynamite", |
|
577 "longbridges", |
|
578 "signal_side", |
|
579 "always_small_airport", |
|
580 "drag_signals_density", |
|
581 }; |
|
582 |
|
583 static const char *_patches_stations[] = { |
|
584 "join_stations", |
|
585 "full_load_any", |
|
586 "improved_load", |
|
587 "selectgoods", |
|
588 "new_nonstop", |
|
589 "nonuniform_stations", |
|
590 "station_spread", |
|
591 "serviceathelipad", |
|
592 "modified_catchment", |
|
593 }; |
|
594 |
|
595 static const char *_patches_economy[] = { |
|
596 "inflation", |
|
597 "build_rawmaterial_ind", |
|
598 "multiple_industry_per_town", |
|
599 "same_industry_close", |
|
600 "bribe", |
|
601 "snow_line_height", |
|
602 "colored_news_date", |
|
603 "starting_date", |
|
604 "ending_date", |
|
605 "smooth_economy", |
|
606 "allow_shares", |
|
607 }; |
|
608 |
|
609 static const char *_patches_ai[] = { |
|
610 "ainew_active", |
|
611 "ai_in_multiplayer", |
|
612 "ai_disable_veh_train", |
|
613 "ai_disable_veh_roadveh", |
|
614 "ai_disable_veh_aircraft", |
|
615 "ai_disable_veh_ship", |
|
616 }; |
|
617 |
|
618 static const char *_patches_vehicles[] = { |
|
619 "realistic_acceleration", |
|
620 "forbid_90_deg", |
|
621 "mammoth_trains", |
|
622 "gotodepot", |
|
623 "roadveh_queue", |
|
624 "new_pathfinding_all", |
|
625 "train_income_warn", |
|
626 "order_review_system", |
|
627 "never_expire_vehicles", |
|
628 "lost_train_days", |
|
629 "autorenew", |
|
630 "autorenew_months", |
|
631 "autorenew_money", |
|
632 "max_trains", |
|
633 "max_roadveh", |
|
634 "max_aircraft", |
|
635 "max_ships", |
|
636 "servint_ispercent", |
|
637 "servint_trains", |
|
638 "servint_roadveh", |
|
639 "servint_ships", |
|
640 "servint_aircraft", |
|
641 "no_servicing_if_no_breakdowns", |
|
642 "wagon_speed_limits", |
|
643 }; |
|
644 |
|
645 typedef struct PatchEntry { |
|
646 const SettingDesc *setting; |
|
647 uint index; |
|
648 } PatchEntry; |
569 |
649 |
570 typedef struct PatchPage { |
650 typedef struct PatchPage { |
571 const PatchEntry *entries; |
651 const char **names; |
|
652 PatchEntry *entries; |
572 byte num; |
653 byte num; |
573 } PatchPage; |
654 } PatchPage; |
574 |
655 |
575 static const PatchPage _patches_page[] = { |
656 /* PatchPage holds the categories, the number of elements in each category |
576 {_patches_ui, lengthof(_patches_ui)}, |
657 * and (in NULL) a dynamic array of settings based on the string-representations |
577 {_patches_construction, lengthof(_patches_construction)}, |
658 * of the settings. This way there is no worry about indeces, and such */ |
578 {_patches_vehicles, lengthof(_patches_vehicles)}, |
659 static PatchPage _patches_page[] = { |
579 {_patches_stations, lengthof(_patches_stations)}, |
660 {_patches_ui, NULL, lengthof(_patches_ui)}, |
580 {_patches_economy, lengthof(_patches_economy)}, |
661 {_patches_construction, NULL, lengthof(_patches_construction)}, |
581 {_patches_ai, lengthof(_patches_ai)}, |
662 {_patches_vehicles, NULL, lengthof(_patches_vehicles)}, |
|
663 {_patches_stations, NULL, lengthof(_patches_stations)}, |
|
664 {_patches_economy, NULL, lengthof(_patches_economy)}, |
|
665 {_patches_ai, NULL, lengthof(_patches_ai)}, |
582 }; |
666 }; |
583 |
667 |
584 /** The main patches window. Shows a number of categories on top and |
668 /** The main patches window. Shows a number of categories on top and |
585 * a selection of patches in that category. |
669 * a selection of patches in that category. |
586 * Uses WP(w, def_d) macro - data_1, data_2, data_3 */ |
670 * Uses WP(w, def_d) macro - data_1, data_2, data_3 */ |
589 static Patches *patches_ptr; |
673 static Patches *patches_ptr; |
590 |
674 |
591 switch (e->event) { |
675 switch (e->event) { |
592 case WE_CREATE: { |
676 case WE_CREATE: { |
593 extern Patches _patches_newgame; |
677 extern Patches _patches_newgame; |
|
678 static bool first_time = true; |
|
679 |
594 patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches; |
680 patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches; |
|
681 |
|
682 /* Build up the dynamic settings-array only once per OpenTTD session */ |
|
683 if (first_time) { |
|
684 PatchPage *page; |
|
685 for (page = &_patches_page[0]; page != endof(_patches_page); page++) { |
|
686 uint i; |
|
687 |
|
688 page->entries = malloc(page->num * sizeof(*page->entries)); |
|
689 for (i = 0; i != page->num; i++) { |
|
690 uint index; |
|
691 const SettingDesc *sd = GetPatchFromName(page->names[i], &index); |
|
692 assert(sd != NULL); |
|
693 |
|
694 page->entries[i].setting = sd; |
|
695 page->entries[i].index = index; |
|
696 } |
|
697 } |
|
698 first_time = false; |
|
699 } |
595 } break; |
700 } break; |
596 |
701 |
597 case WE_PAINT: { |
702 case WE_PAINT: { |
598 int x, y; |
703 int x, y; |
599 const PatchEntry *pe; |
|
600 const PatchPage *page = &_patches_page[WP(w,def_d).data_1]; |
704 const PatchPage *page = &_patches_page[WP(w,def_d).data_1]; |
601 uint i; |
705 uint i; |
602 |
706 |
603 /* Set up selected category */ |
707 /* Set up selected category */ |
604 w->click_state = 1 << (WP(w, def_d).data_1 + 4); |
708 w->click_state = 1 << (WP(w, def_d).data_1 + 4); |
605 DrawWindowWidgets(w); |
709 DrawWindowWidgets(w); |
606 |
710 |
607 x = 5; |
711 x = 5; |
608 y = 47; |
712 y = 47; |
609 for (i = 0, pe = page->entries; i != page->num; i++, pe++) { |
713 for (i = 0; i != page->num; i++) { |
610 const SettingDesc *sd = GetSettingDescription(*pe); |
714 const SettingDesc *sd = page->entries[i].setting; |
611 const SettingDescBase *sdb = &sd->desc; |
715 const SettingDescBase *sdb = &sd->desc; |
612 const void *var = ini_get_variable(&sd->save, patches_ptr); |
716 const void *var = ini_get_variable(&sd->save, patches_ptr); |
613 bool editable = true; |
717 bool editable = true; |
614 bool disabled = false; |
718 bool disabled = false; |
615 |
719 |
751 SetWindowDirty(w); |
855 SetWindowDirty(w); |
752 break; |
856 break; |
753 |
857 |
754 case WE_ON_EDIT_TEXT: { |
858 case WE_ON_EDIT_TEXT: { |
755 if (e->edittext.str != NULL) { |
859 if (e->edittext.str != NULL) { |
756 const uint index = _patches_page[WP(w,def_d).data_1].entries[WP(w,def_d).data_3]; |
860 const PatchEntry *pe = &_patches_page[WP(w,def_d).data_1].entries[WP(w,def_d).data_3]; |
757 const SettingDesc *sd = GetSettingDescription(index); |
861 const SettingDesc *sd = pe->setting; |
758 void *var = ini_get_variable(&sd->save, patches_ptr); |
862 void *var = ini_get_variable(&sd->save, patches_ptr); |
759 int32 value = atoi(e->edittext.str); |
863 int32 value = atoi(e->edittext.str); |
760 |
864 |
761 /* Save the correct currency-translated value */ |
865 /* Save the correct currency-translated value */ |
762 if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate; |
866 if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate; |
763 |
867 |
764 SetPatchValue(index, patches_ptr, value); |
868 SetPatchValue(pe->index, patches_ptr, value); |
765 SetWindowDirty(w); |
869 SetWindowDirty(w); |
766 |
870 |
767 if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); |
871 if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); |
768 } |
872 } |
769 break; |
873 break; |