diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..685dc6ca8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +.config +*.o +.include_mach +.mach +err +include/gendefine_gid.h +include/mach +tools/csum/csum +tools/imgld/imgld +tools/sched/sched +tools/srec2bin/srec2bin +tools/wpcdebug/wpcdebug +build/* +mach +.vagrant +.vscode +doc/doxygen/html/ +doc/doxygen/latex/ diff --git a/INSTALL b/INSTALL index 46f3bd01d..8ade47d98 100644 --- a/INSTALL +++ b/INSTALL @@ -26,3 +26,6 @@ there as well (replacing any zip file that was already there, which will get backed up to a .original file; sound ROMs from the original will also get copied into the new zip archive). +6. Dependencies + +On Debian/Ubuntu you need to install build-essentials and libpth-dev. diff --git a/Makefile b/Makefile index cb70d068e..dd4d558e5 100644 --- a/Makefile +++ b/Makefile @@ -252,6 +252,9 @@ CFLAGS += -DGCC_VERSION=$(GCC_VERSION) CFLAGS += -Wall CONLY_FLAGS += -Wstrict-prototypes +# fix compilation on never GCC versions +CFLAGS += -fgnu89-inline + # # Define lots of other things based on make parameters # @@ -1015,7 +1018,7 @@ callset.in : # 'make clean' does what you think. # .PHONY : clean -clean: clean_derived clean_build clean_gendefines clean_tools +clean: clean_derived clean_build clean_gendefines clean_tools clean_time $(Q)for dir in `echo . kernel common effect fonts images test $(MACHINE_DIR) $(PLATFORM_DIR) sim cpu/$(CPU)`;\ do echo "Cleaning in '$$dir' ..." && \ pushd $$dir >/dev/null && rm -f $(TMPFILES) && \ @@ -1037,6 +1040,10 @@ clean_build: clean_tools: $(Q)rm -f $(HOST_OBJS) $(TOOLS) +.PHONY : clean_time +clean_time: + $(Q)touch * + .PHONY : show_objs show_objs: $(Q)echo $(OBJS) diff --git a/README b/README index 4337c88c9..a38948ea9 100644 --- a/README +++ b/README @@ -1,23 +1,27 @@ - -This is FreeWPC, an open source operating system for the Williams -Pinball Controller (WPC) family of pinball machines. FreeWPC is -licensed under the GNU General Public License, Version 2. - -The sources for the core routines are located in 'kernel'; -other common code is in 'common', and game-specific code can be found -in a subdirectory based on the machine name, under 'machine'. -There are also a number of tools included with the distribution -for generating some of the source code and for building ROM images -that are under 'tools'. - -You will also need several tools not here in order to build. -See the file doc/build.html for more detailed information. Most -importantly, you'll need a copy of the gcc6809 cross-compiler. -Many standard UNIX utilities are needed as well. FreeWPC has been -built successfully on Linux and Cygwin. - -Email suggestions/comments/questions to . - -Visit the homepage at http://www.oddchange.com/freewpc for more -information. - +This is FreeWPC, an open source operating system for the Williams +Pinball Controller (WPC) family of pinball machines. FreeWPC is +licensed under the GNU General Public License, Version 2. + +To quickly get started, install vagrant from vagrantup.com, +clone this repository, and run the command 'vagrant up' from within +the freewpc directory. Within 30 minutes you'll have a fully configured +linux build environment! + +The sources for the core routines are located in 'kernel'; +other common code is in 'common', and game-specific code can be found +in a subdirectory based on the machine name, under 'machine'. +There are also a number of tools included with the distribution +for generating some of the source code and for building ROM images +that are under 'tools'. + +You will also need several tools not here in order to build. +See the file doc/build.html for more detailed information. Most +importantly, you'll need a copy of the gcc6809 cross-compiler. +Many standard UNIX utilities are needed as well. FreeWPC has been +built successfully on Linux and Cygwin. + +Email suggestions/comments/questions to . + +Visit the homepage at http://www.oddchange.com/freewpc for more +information. + diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 000000000..122f50311 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,47 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # see https://docs.vagrantup.com for more information + + # We're going to run on ubuntu, 32 bit, 14.04 + config.vm.box = "ubuntu/trusty32" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + config.vm.provider "virtualbox" do |vb| + vb.memory = "1024" + end + + # We're going to mount this repository within the virtual machine at /freewpc + config.vm.synced_folder ".", "/freewpc" + config.vm.synced_folder ".", "/vagrant", disabled: true + # Change this line to the Visual Pinball pinmame rom directory + config.vm.synced_folder "C:\\Program Files (x86)\\Visual Pinball\\VPinMAME\\roms", "/roms" + + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + config.vm.provision "shell", inline: <<-SHELL + apt-get update + sudo apt-get install -y git + sudo apt-get install -y zip + # 1) clone the gcc6809 source. TODO: it may be better to just have the binary + git clone https://LuskeyNoah@bitbucket.org/LuskeyNoah/gcc-4.3.4-6809.git + # 2) get the necessary dependencies to build gcc + sudo apt-get install -y libgmp-dev libmpfr-dev + # 3) go into the gcc6809 directory and build everything + cd gcc-4.3.4-6809/build-6809 + sudo make everything + SHELL +end diff --git a/config.example b/config.example index 902ef3ecd..f53cfd789 100644 --- a/config.example +++ b/config.example @@ -35,7 +35,7 @@ #MACHINE := tz #MACHINE := afm #MACHINE := wcs -#MACHINE := t2 +MACHINE := t2 #MACHINE := fh #MACHINE := tester #MACHINE := tspp diff --git a/include/t2/cannon_driver.h b/include/t2/cannon_driver.h new file mode 100644 index 000000000..061c667b9 --- /dev/null +++ b/include/t2/cannon_driver.h @@ -0,0 +1,14 @@ + #include + +// Cannon reset : places the cannon back home and empty +// This is automatically called at the beginning and end of a ball +void cannon_reset(void); + +// Cannon fire : Shoot the ball (if possible) or do nothing +void cannon_fire(void); + +// Cannon is loaded : Check if the cannon contains a ball +bool cannon_is_loaded(void); + +// Cannon start sequence : Start the sequence of swinging the cannon out with a ball +void cannon_start_sequence(void); \ No newline at end of file diff --git a/machine/t2/Makefile b/machine/t2/Makefile index 116a18e70..d315cc023 100644 --- a/machine/t2/Makefile +++ b/machine/t2/Makefile @@ -61,11 +61,12 @@ PINMAME_OTHER_ROMS = t2_u* # and leffs. RTTs must go into GAME_OBJS. # -GAME_OBJS = +GAME_OBJS = GAME_TEST_OBJS = GAME_INCLUDES = -GAME_PAGED_OBJS = amode.o targets.o drop.o misc.o +GAME_PAGED_OBJS = skull.o shots.o combo.o cannon_driver.o +GAME2_OBJS = amode.o diff --git a/machine/t2/cannon_driver.c b/machine/t2/cannon_driver.c new file mode 100644 index 000000000..594aff24d --- /dev/null +++ b/machine/t2/cannon_driver.c @@ -0,0 +1,347 @@ +/* model this after wcs/whatever_driver.c */ + +/* + * Copyright 2017 by Noah Luskey + * + * This file is part of FreeWPC. + * + * FreeWPC is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * FreeWPC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FreeWPC; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + /* this file is how one should interact with the cannon. It will (hopefully) + * prevent balls from being fired at the wrong time or wrong thing + * + * See the cannon state machine diagram drawing in machines/t2/notes + * for a clearer picture of what's going on here (if you're curious) + */ + + +// TODO: add an api call to start the cannon sequence. It shouldn't automatically start +// the cannon state machine sequence just when the ball enters the gun. + #include + #include + #include + +typedef enum +{ + HOME_STATIONARY=0, + CANNON_READY, + HOME_MOVING, + ON_MARK, + FIRE_READY, + FORGOTTEN, + FIRED, + GET_HOME, // like a demand "GET HOME!" (and empty) + FINDING_HOME // just gets the cannon home +} cannon_state_t; + +cannon_state_t cannon_state; +bool fireable; + +bool cannon_check_valid_state_transition(const cannon_state_t from, const cannon_state_t to); +void cannon_fire(void); + +void cannon_error_handler(void) +{ + //TODO: something bad happened + // print a debug statement or possibly try to fix it +} + +void cannon_motor_on(void) +{ + gun_motor_start_forward(); +} + +void cannon_motor_off(void) +{ + gun_motor_stop(); +} + +void cannon_enable_firing(void) +{ + fireable = true; +} + +void cannon_disable_firing(void) +{ + fireable = false; +} + +void cannon_set_ball_count(U8 count) +{ + if (count == 1) { + device_entry(DEVNO_GUN)->max_count = 1; + } else if (count == 0) { + device_request_empty(device_entry(DEVNO_GUN)); + } else { + // TODO: invalid argument, print some debug statement + } +} + +// +// Force set the cannon_state +// This really shouldn't ever be called by the user. Just me. +// +void cannon_force_state(const cannon_state_t state) +{ + switch (state) { + case HOME_STATIONARY: + case CANNON_READY: + cannon_motor_off(); + cannon_disable_firing(); + cannon_set_ball_count(1); + break; + case HOME_MOVING: + case ON_MARK: + cannon_motor_on(); + cannon_disable_firing(); + cannon_set_ball_count(1); + break; + case FIRE_READY: + cannon_motor_on(); + cannon_enable_firing(); + cannon_set_ball_count(1); + break; + case FORGOTTEN: + cannon_motor_on(); + cannon_enable_firing(); + cannon_fire(); + break; + case FIRED: + cannon_motor_on(); + cannon_disable_firing(); + cannon_set_ball_count(1); + break; + case GET_HOME: + cannon_motor_off(); + cannon_disable_firing(); + cannon_set_ball_count(1); + break; + case FINDING_HOME: + cannon_motor_on(); + cannon_disable_firing(); + cannon_set_ball_count(1); + break; + } + cannon_state = state; +} + +// +// set the state safely - will only allow valid transitions +// if the requested transitions is illegal, nothing happens +// +void cannon_set_state(const cannon_state_t state) { + if (cannon_check_valid_state_transition(cannon_state, state)) { + cannon_force_state(state); + } else { + // TODO: print a debug message + } +} + +// +// Triggers for state transitions +// Here, we have the various callset entries that will set the state of the cannon +// State may also be set manually (externally) by the API functions at the bottom of this file +// + +//callset entry for home switch +CALLSET_ENTRY(cannon, SW_GUN_HOME) +{ + switch (cannon_state) { + case FIRED: + cannon_set_state(HOME_STATIONARY); + break; + case FINDING_HOME: + cannon_set_state(GET_HOME); + if (cannon_is_loaded()) { + cannon_set_state(HOME_MOVING); + } else { + cannon_set_state(HOME_STATIONARY); + } + break; + default: + cannon_error_handler(); + } +} + +// callset entry for mark switch +// The mark switch is triggered on low-high and high-low edges, so we need to +// determine what the exact condition is before we do anything else +void gun_mark_on(void) +{ + switch (cannon_state) { + case HOME_MOVING: + cannon_set_state(ON_MARK); + break; + default: + cannon_error_handler(); + } +} + +void gun_mark_off(void) +{ + switch (cannon_state) { + case ON_MARK: + cannon_set_state(FIRE_READY); + break; + case FIRE_READY: + cannon_set_state(FORGOTTEN); + break; + default: + cannon_error_handler(); + } +} + + +CALLSET_ENTRY(cannon, SW_GUN_MARK) +{ + score(SC_100K); + if (switch_poll_logical(SW_GUN_MARK)) { + gun_mark_on(); + } else { + gun_mark_off(); + } + +} + +// event for when the gun contains a ball +CALLSET_ENTRY(cannon, DEV_GUN_ENTER) +{ + switch (cannon_state) { + case HOME_STATIONARY: + cannon_set_state(CANNON_READY); + break; + default: + cannon_error_handler(); + } +} + +// event for when the ball is shot from the cannon +CALLSET_ENTRY(cannon, DEV_GUN_KICK_SUCCESS) +{ + switch (cannon_state) { + case FIRE_READY: + case FORGOTTEN: + cannon_set_state(FIRED); + break; + default: + cannon_error_handler(); + } +} + +// TODO: callset_invoke for cannon events +// TODO: cannon loaded +// TODO: cannon fired - when the user intentionally shoots the ball +// TODO: cannon fireable - when the cannon has a ball and is past the mark +// TODO: cannon forgotten - when the user forgot to pull the trigger + + + + +// +// return true if the state transition is valid +// +bool cannon_check_valid_state_transition(const cannon_state_t from, const cannon_state_t to) +{ + // not changing state is always valid + if (from == to) { + return true; + } + + // jumping to the GET_HOME state is always valid + if (to == GET_HOME) { + return true; + } + + // here's the real meat and potatoes. See machines/t2/notes + switch (from) { + case HOME_STATIONARY: + return (to == CANNON_READY); + case CANNON_READY: + return (to == HOME_MOVING); + case HOME_MOVING: + return (to == ON_MARK); + case ON_MARK: + return (to == FIRE_READY); + case FIRE_READY: + return (to == FORGOTTEN) || (to == FIRED); + case FORGOTTEN: + return (to == FIRED); + case FIRED: + return (to == HOME_STATIONARY); + case GET_HOME: + return (to == FINDING_HOME) || (to == HOME_MOVING) || (to == HOME_STATIONARY); + case FINDING_HOME: + return (to == GET_HOME); + default: + return false; + // TODO: print some debug that this should NEVER happen + } +} + + +// +// Cannon API functions: Use these functions to interact with the cannon +// from outside of this file (in game code). These are the only functions that are +// defined the the cannon_driver.h file +// A typical use would be: +// TODO: write typical use +// + +// Reset cannon : Get rid of any balls and place the cannon at home positions +void cannon_reset(void) +{ + fireable = false; + cannon_set_state(GET_HOME); +} + +// Cannon fire : Shoot the ball (if possible) or do nothing +void cannon_fire(void) +{ + if (fireable) { + cannon_set_ball_count(0); + } +} + +// Cannon start sequence : Start the sequence of swinging the cannon out with a ball +void cannon_start_sequence(void) +{ + cannon_set_state(HOME_MOVING); +} + +// Cannon is loaded : Check if the cannon contains a ball +bool cannon_is_loaded(void) +{ + return (device_full_p(device_entry(DEVNO_GUN))); +} + + +// At the start/end of the ball, make sure the cannon is empty and home +CALLSET_ENTRY(cannon, start_ball, end_ball) +{ + cannon_reset(); +} + +// attempt to fire the cannon when the trigger is pulled, always +// TODO: this should be left up to the individual modes, not here +CALLSET_ENTRY(cannon_test, SW_LAUNCH_BUTTON) +{ + cannon_fire(); +} + +CALLSET_ENTRY(cannon_test, DEV_GUN_ENTER) +{ + cannon_start_sequence(); +} \ No newline at end of file diff --git a/machine/t2/combo.c b/machine/t2/combo.c new file mode 100644 index 000000000..d6f92213c --- /dev/null +++ b/machine/t2/combo.c @@ -0,0 +1,48 @@ +/* + * Copyright 2017 by Noah Luskey + * + * This file is part of FreeWPC. + * + * FreeWPC is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * FreeWPC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FreeWPC; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Combos - Handles lighting the shots that can be done as a combo and + awarding points. + TODO: Light effects for Combos + TODO: Display effects for making Combos + TODO: Scoring + TODO: Generate events on made Combos? + TODO: figure out more todos +*/ + +#include + +typedef enum { + SHOT_DATABASE=0, /* furthest left little hole thing */ + SHOT_ESCAPE_ROUTE, /* left loop */ + SHOT_AI_RAMP, /* left ramp */ + SHOT_SKULL, /* skull, obviously */ + SHOT_COMMAND_RAMP, /* right ramp */ + SHOT_CHASE_LOOP, /* right loop */ +} previous_shot_t; + +#define COMBO_TIME_LIMIT TIME_4S + + +CALLSET_ENTRY (combo, start_ball) +{ +} + + diff --git a/machine/t2/misc.c b/machine/t2/misc.c deleted file mode 100644 index a2267a25c..000000000 --- a/machine/t2/misc.c +++ /dev/null @@ -1,34 +0,0 @@ - -#include -#include - -CALLSET_ENTRY (misc, sw_left_sling) -{ - sound_send (SND_SLING); - score (SC_110); -} - - -CALLSET_ENTRY (misc, sw_right_sling) -{ - sound_send (SND_SLING); - score (SC_110); -} - -CALLSET_ENTRY (misc, sw_left_jet) -{ - sound_send (SND_DATABASE_BEEP1); - score (SC_5K); -} - -CALLSET_ENTRY (misc, sw_right_jet) -{ - sound_send (SND_DATABASE_BEEP2); - score (SC_5K); -} - -CALLSET_ENTRY (misc, sw_bottom_jet) -{ - sound_send (SND_DATABASE_BEEP3); - score (SC_5K); -} diff --git a/machine/t2/notes/cannon state machine.png b/machine/t2/notes/cannon state machine.png new file mode 100644 index 000000000..3fb5bc774 Binary files /dev/null and b/machine/t2/notes/cannon state machine.png differ diff --git a/machine/t2/notes/rules sketch.leo b/machine/t2/notes/rules sketch.leo new file mode 100644 index 000000000..75c590922 Binary files /dev/null and b/machine/t2/notes/rules sketch.leo differ diff --git a/machine/t2/notes/rules sketch.png b/machine/t2/notes/rules sketch.png new file mode 100644 index 000000000..eb77991e5 Binary files /dev/null and b/machine/t2/notes/rules sketch.png differ diff --git a/machine/t2/shots.c b/machine/t2/shots.c new file mode 100644 index 000000000..2e5dd9030 --- /dev/null +++ b/machine/t2/shots.c @@ -0,0 +1,143 @@ +/* + * Copyright 2017 by Noah Luskey + * + * This file is part of FreeWPC. + * + * FreeWPC is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * FreeWPC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FreeWPC; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Loops/Ramps: Handles the completion of shots with multiple switches + * The events generated by this file are: + * EV_SHOT_AI_RAMP_MADE + * EV_SHOT_CHASE_LOOP_MADE + * EV_SHOT_CHASE_LOOP_TO_JETS + * EV_SHOT_COMMAND_RAMP_MADE + * EV_SHOT_ESCAPE_ROUTE_MADE + * EV_SHOT_ESCAPE_ROUTE_TO_JETS + */ + +#include + +/* ball entered the AI ramp (left) */ +CALLSET_ENTRY(shot_ai, SW_LEFT_RAMP_ENTRY) +{ + sound_send(SND_RAMP_ENTRY); + event_can_follow(left_ramp_entry, left_ramp_made, TIME_1S); +} + +/* ball completed the AI ramp (left) */ +CALLSET_ENTRY(shot_ai, SW_LEFT_RAMP_MADE) +{ + if (event_did_follow(left_ramp_entry, left_ramp_made)) { + callset_invoke(EV_SHOT_AI_RAMP_MADE); + } +} +/* ball enetered the command ramp (right) */ +CALLSET_ENTRY(shot_command, SW_RIGHT_RAMP_ENTRY) +{ + event_can_follow(right_ramp_entry, right_ramp_made, TIME_1S); +} + +/* ball completed the command ramp (right) */ +CALLSET_ENTRY(shot_command, SW_RIGHT_RAMP_MADE) +{ + if (event_did_follow(right_ramp_entry, right_ramp_made)) { + callset_invoke(EV_SHOT_COMMAND_RAMP_MADE); + } +} + + + +/* chase loop event progression */ +CALLSET_ENTRY(shot_chase, SW_LOWER_CHASE_LOOP) +{ + event_can_follow(chase_loop_enter_1, chase_loop_enter_2, TIME_100MS); +} + +/* there are two switches in a row +TODO: deal with the fact that of the two may be broken and that's ok */ +CALLSET_ENTRY(shot_chase, SW_UPPER_CHASE_LOOP) +{ + if (event_did_follow(chase_loop_enter_1, chase_loop_enter_2)) { + event_can_follow(chase_loop_enter_2, chase_loop_complete, TIME_500MS); + event_can_follow(chase_loop_enter_2, chase_loop_to_jets, TIME_500MS); + } +} + +/* there are also two switches in a row coming down the escape route +but it doesn't matter if only one is it */ +// TODO: make sure this only triggers once per loop made +CALLSET_ENTRY(shot_chase, SW_UPPER_ESCAPE_ROUTE, SW_LOWER_ESCAPE_ROUTE) +{ + if (event_did_follow(chase_loop_enter_2, chase_loop_complete)) { + callset_invoke(EV_SHOT_CHASE_LOOP_MADE); + } +} + +/* if a ball was just kicked out of the top lock, don't confuse this for an incomplete loop shot */ +CALLSET_ENTRY(shot, dev_top_lock_kick_success) { + timer_restart_free(GID_BLOCK_SHOTS_TO_JETS, TIME_5S); +} + +/* This covers both the chase loop and the escape route falling into the lanes */ +CALLSET_ENTRY(shot, SW_TOP_LANE_LEFT, SW_TOP_LANE_CENTER, SW_TOP_LANE_RIGHT) +{ + /* was a ball recently fired out of the top lock? Don't fire these events */ + if (task_find_gid(GID_BLOCK_SHOTS_TO_JETS)) { + return; + } + + if (event_did_follow(chase_loop_enter_2, chase_loop_to_jets)) { + callset_invoke(EV_SHOT_CHASE_LOOP_TO_JETS); + } else if (event_did_follow(escape_route_enter_2, escape_route_to_jets)) { + callset_invoke(EV_SHOT_ESCAPE_ROUTE_TO_JETS); + } +} + + + +/* escape route progression */ +CALLSET_ENTRY(shot_escape, SW_LOWER_ESCAPE_ROUTE) +{ + event_can_follow(escape_route_enter_1, escape_route_enter_2, TIME_100MS); +} + +/* escape route has two switches, apparently */ +CALLSET_ENTRY(shot_escape, SW_UPPER_ESCAPE_ROUTE) +{ + sound_send(SND_REVVING); + if (event_did_follow(escape_route_enter_1, escape_route_enter_2)) { + event_can_follow(escape_route_enter_2, escape_route_complete, TIME_1S); + event_can_follow(escape_route_enter_2, escape_route_to_jets, TIME_2S); + } +} + +/* escape route to the hole */ +CALLSET_ENTRY(shot_escape, SW_TOP_LOCK) +{ + if (event_did_follow(escape_route_enter_2, escape_route_complete)) { + /* start a timer that blocks the escape route to jets event */ + callset_invoke(EV_SHOT_ESCAPE_ROUTE_MADE); + } +} + + +/* things won't compile if these don't exist somewhere in the code at least once */ +CALLSET_ENTRY(shots, EV_SHOT_COMMAND_RAMP_MADE) {sound_send(SND_RAMP_MADE);} +CALLSET_ENTRY(shots, EV_SHOT_AI_RAMP_MADE) {sound_send(SND_RAMP_MADE);} +CALLSET_ENTRY(shots, EV_SHOT_CHASE_LOOP_MADE) {sound_send(SND_BIKE_1);} +CALLSET_ENTRY(shots, EV_SHOT_CHASE_LOOP_TO_JETS) {sound_send(SND_BIKE_2);} +CALLSET_ENTRY(shots, EV_SHOT_ESCAPE_ROUTE_MADE) {sound_send(SND_LOOP);} +CALLSET_ENTRY(shots, EV_SHOT_ESCAPE_ROUTE_TO_JETS) {sound_send(SND_BOOM);} \ No newline at end of file diff --git a/machine/t2/drop.c b/machine/t2/skull.c similarity index 71% rename from machine/t2/drop.c rename to machine/t2/skull.c index dd546ae65..3d13e007b 100644 --- a/machine/t2/drop.c +++ b/machine/t2/skull.c @@ -5,13 +5,12 @@ CALLSET_ENTRY (drop, skull_drop_down) { sound_send (SND_SPLAT); - score (SC_100K); - skull_drop_reset (); + //skull_drop_reset (); } CALLSET_ENTRY (drop, start_ball) { - skull_drop_reset (); + //skull_drop_reset (); } diff --git a/machine/t2/t2.md b/machine/t2/t2.md index 325f79626..19316785f 100644 --- a/machine/t2/t2.md +++ b/machine/t2/t2.md @@ -28,8 +28,6 @@ include platform/wpc/wpc-dmd.md ########################################################################## define MACHINE_LACKS_PROTOS_H define MACHINE_CUSTOM_AMODE -define MACHINE_BALL_IN_PLAY_MUSIC MUS_T2_IN_PLAY -define MACHINE_START_BALL_MUSIC MUS_T2_PLUNGER #define MACHINE_SCORE_DIGITS #define MACHINE_REPLAY_SCORE_CHOICES 10 @@ -135,9 +133,9 @@ define MACHINE_START_BALL_MUSIC MUS_T2_PLUNGER 12: Left Flipper, button, intest, c_decl(sw_left_button) 13: Start Button, start-button, intest 14: Plumb Bob Tilt, c_decl(sw_tilt), tilt, ingame, novalid, cabinet -15: Trough Left, c_decl(sw_trough), novalid -16: Trough Center, c_decl(sw_trough), novalid -17: Trough Right, c_decl(sw_trough), novalid +15: Trough Left, edge, c_decl(sw_trough), novalid +16: Trough Center, edge, c_decl(sw_trough), novalid +17: Trough Right, edge, c_decl(sw_trough), novalid 18: Outhole, outhole, intest, novalid 21: Slam Tilt, slam-tilt, ingame, cabinet 23: Ticket Opto, opto, cabinet @@ -145,8 +143,8 @@ define MACHINE_START_BALL_MUSIC MUS_T2_PLUNGER 26: Left Return Lane, lamp(LM_LEFT_RETURN_LANE) 27: Right Return Lane, lamp(LM_RIGHT_RETURN_LANE) 28: Right Outlane -31: Gun Loaded -32: Gun Mark, novalid, intest, service +31: Gun Loaded, edge +32: Gun Mark, edge, novalid, intest, service 33: Gun Home, novalid, intest, service # TODO : it *must* be named this, even though T2 prefers 'grip trigger' 34: Launch Button, cabinet, launch-button, novalid @@ -161,10 +159,10 @@ define MACHINE_START_BALL_MUSIC MUS_T2_PLUNGER 46: Standup Right Top, lamp(LM_RELIGHT_KICK_TOP) 47: Standup Right Mid., lamp(LM_RELIGHT_KICK_MIDDLE) 48: Standup Right Bot., lamp(LM_RELIGHT_KICK_BOTTOM) -51: Left Lock +51: Left Lock, edge 53: Lower Escape Route 54: Upper Escape Route -55: Top Lock +55: Top Lock, edge 56: Top Lane Left, lamp(LM_TOP_LANE_LEFT) 57: Top Lane Center, lamp(LM_TOP_LANE_MIDDLE) 58: Top Lane Right, lamp(LM_TOP_LANE_RIGHT) @@ -179,7 +177,7 @@ define MACHINE_START_BALL_MUSIC MUS_T2_PLUNGER 73: Target 3, lamp(LM_SKILL_3) 74: Target 4, lamp(LM_SKILL_4) 75: Target 5 Low, lamp(LM_SKILL_5) -76: Ball Popper +76: Ball Popper, edge 77: Drop Target, edge 78: Shooter, edge, shooter, novalid, debounce(TIME_200MS) @@ -213,7 +211,7 @@ H8: Kickback L1: Plunger, launch L2: Top Lock L3: Gun Motor, motor, nosearch -L4: Skull Drop Down, nosearch +L4: Skull Drop Down L5: Left Jet L6: Right Jet L7: Bottom Jet @@ -280,8 +278,8 @@ Left Hole: Left Lock, Database Return Lanes: Left Return Lane, Right Return Lane Skull Lamps: Super Jackpot, Load Gun, Extra Ball, Load For Jackpot, Drop Target Right Loop: 250K, 500K, 750K, 1 Million, 3 Million, 5 Million +Locks: Left Lock, Top Lock, Load Gun -Locks: Left Lock, Top Lock ########################################################################## # Containers @@ -333,6 +331,7 @@ Skull Lock: Ball Popper, Ball Popper [scores] 110: 1K: +10K: 5K: 25K: 100K: @@ -357,17 +356,18 @@ Skull Lock: Ball Popper, Ball Popper ########################################################################## [flags] + ########################################################################## # Display effects ########################################################################## [deffs] -Amode: runner, PRI_AMODE, page(MACHINE_PAGE) +Amode: runner, PRI_AMODE, page(MACHINE2_PAGE) ########################################################################## # Lamp effects ########################################################################## [leffs] -Amode: runner, PRI_LEFF1, LAMPS(ALL), GI(ALL), page(MACHINE_PAGE) +Amode: runner, PRI_LEFF1, LAMPS(ALL), GI(ALL), page(MACHINE2_PAGE) ########################################################################## # Fonts used in this game. @@ -382,6 +382,11 @@ Left Jet: driver(jet), sw=SW_LEFT_JET, sol=SOL_LEFT_JET Upper Jet: driver(jet), sw=SW_RIGHT_JET, sol=SOL_RIGHT_JET Lower Jet: driver(jet), sw=SW_BOTTOM_JET, sol=SOL_BOTTOM_JET +# TODO: this is an abuse of the bivariable motor driver +Gun Motor: driver(bivar), + forward_sol=SOL_GUN_MOTOR, + reverse_sol=SOL_GUN_MOTOR + Kickback Driver: driver(spsol), sw=SW_LEFT_OUTLANE, sol=SOL_KICKBACK, ontime=12, offtime=18 diff --git a/machine/t2/targets.c b/machine/t2/targets.c deleted file mode 100644 index 08adfd1c8..000000000 --- a/machine/t2/targets.c +++ /dev/null @@ -1,294 +0,0 @@ - -#include - -extern inline const switch_info_t *switch_lookup_current (void) -{ - extern const switch_info_t switch_table[]; - const U8 sw = (U8)task_get_arg (); - return &switch_table[sw]; -} - - -typedef const struct -{ - void (*made) (void); - void (*make_unlit) (void); - void (*make_lit) (void); - void (*make_flash) (void); - void (*light_all) (void); - void (*flash_all) (void); -} bank_ops_t; - - -typedef const struct -{ - bank_ops_t *ops; - const char *name; - U8 gid; - U8 sw_count; - U8 switches[8]; - U8 lamplist; -} bank_properties_t; - -#define BANK_SKILL 0 -#define BANK_CENTER 1 -#define BANK_RIGHT 2 -#define BANK_TOP 3 - - -extern void callset_bank_center_made (void); /* callset_invoke (bank_center_made) */ -extern void callset_bank_center_make_unlit (void); /* callset_invoke (bank_center_make_unlit) */ -extern void callset_bank_center_make_lit (void); /* callset_invoke (bank_center_make_lit) */ -extern void callset_bank_center_make_flash (void); /* callset_invoke (bank_center_make_flash) */ -extern void callset_bank_center_light_all (void); /* callset_invoke (bank_center_light_all) */ -extern void callset_bank_center_flash_all (void); /* callset_invoke (bank_center_flash_all) */ - -const bank_ops_t bank_center_ops = { - .made = callset_bank_center_made, - .make_unlit = callset_bank_center_make_unlit, - .make_lit = callset_bank_center_make_lit, - .make_flash = callset_bank_center_make_flash, - .light_all = callset_bank_center_light_all, - .flash_all = callset_bank_center_flash_all, -}; - -extern void callset_bank_top_made (void); /* callset_invoke (bank_top_made) */ -extern void callset_bank_top_make_unlit (void); /* callset_invoke (bank_top_make_unlit) */ -extern void callset_bank_top_make_lit (void); /* callset_invoke (bank_top_make_lit) */ -extern void callset_bank_top_make_flash (void); /* callset_invoke (bank_top_make_flash) */ -extern void callset_bank_top_light_all (void); /* callset_invoke (bank_top_light_all) */ -extern void callset_bank_top_flash_all (void); /* callset_invoke (bank_top_flash_all) */ - -const bank_ops_t bank_top_ops = { - .made = callset_bank_top_made, - .make_unlit = callset_bank_top_make_unlit, - .make_lit = callset_bank_top_make_lit, - .make_flash = callset_bank_top_make_flash, - .light_all = callset_bank_top_light_all, - .flash_all = callset_bank_top_flash_all, -}; - - -const bank_properties_t bank_properties_table[] = { - [BANK_SKILL] = { - .name = "SKILL 5-BANK", - .gid = GID_BANK_SKILL, - .sw_count = 5, - .lamplist = LAMPLIST_SKILL, - }, - - [BANK_CENTER] = { - .ops = &bank_center_ops, - .name = "CENTER 3-BANK", - .gid = GID_BANK_CENTER, - .sw_count = 3, - .switches = { SW_STANDUP_MID_LEFT, SW_STANDUP_MID_CENTER, SW_STANDUP_MID_RIGHT, }, - .lamplist = LAMPLIST_CENTER, - }, - - [BANK_RIGHT] = { - .name = "RIGHT 3-BANK", - .gid = GID_BANK_RIGHT, - .sw_count = 3, - .lamplist = LAMPLIST_RELIGHT_KICKBACK, - }, - - [BANK_TOP] = { - .ops = &bank_top_ops, - .name = "TOP LANES", - .gid = GID_BANK_TOP, - .sw_count = 3, - .switches = { SW_TOP_LANE_LEFT, SW_TOP_LANE_CENTER, SW_TOP_LANE_RIGHT, }, - .lamplist = LAMPLIST_TOP_LANES, - }, -}; - - -U8 bank_get_lamplist (const U8 bankno) -{ - return bank_properties_table[bankno].lamplist; -} - - -void bank_clear (const U8 bankno) -{ - const bank_properties_t *bank = &bank_properties_table[bankno]; - U8 i; - for (i=0 ; i < bank->sw_count; i++) - lamp_tristate_off (switch_lookup_lamp (bank->switches[i])); -} - -void bank_flash (const U8 bankno) -{ - const bank_properties_t *bank = &bank_properties_table[bankno]; - U8 i; - for (i=0 ; i < bank->sw_count; i++) - lamp_tristate_flash (switch_lookup_lamp (bank->switches[i])); -} - -void bank_set (const U8 bankno) -{ - const bank_properties_t *bank = &bank_properties_table[bankno]; - U8 i; - for (i=0 ; i < bank->sw_count; i++) - lamp_tristate_on (switch_lookup_lamp (bank->switches[i])); -} - -bool bank_test_all (const U8 bankno) -{ - const bank_properties_t *bank = &bank_properties_table[bankno]; - U8 i; - for (i=0 ; i < bank->sw_count; i++) - if (!lamp_test (switch_lookup_lamp (bank->switches[i]))) - return FALSE; - return TRUE; -} - - -U8 bank_active; -const switch_info_t *bank_swinfo; - - -void bank_target_off (void) -{ - lamp_tristate_off (bank_swinfo->lamp); -} - - -void bank_target_on (void) -{ - lamp_tristate_on (bank_swinfo->lamp); - if (bank_test_all (bank_active)) - { - dbprintf ("yep, completed it\n"); - far_indirect_call_handler (bank_properties_table[bank_active].ops->light_all, EVENT_PAGE); - } -} - - -void bank_target_flash (void) -{ - lamp_tristate_flash (bank_swinfo->lamp); -} - - -/** Handle any switch that is part of a target bank. */ -void bank_sw_handler (const U8 bankno) -{ - const bank_properties_t *bank = &bank_properties_table[bankno]; - - /* Debounce hits to the entire target bank, not just to - individual switches. Each bank has its timer for this. */ - if (timer_find_gid (bank->gid)) - { - dbprintf ("bank %d skipped debounce, gid %d\n", bankno, bank->gid); - return; - } - else - timer_restart_free (bank->gid, TIME_200MS); - - /* Lookup information on the specific switch that triggered */ - bank_swinfo = switch_lookup_current (); - bank_active = bankno; - - /* Throw an event just saying that the bank was hit */ - far_indirect_call_handler (bank->ops->made, EVENT_PAGE); - - /* Throw an event based on the state of the lamp for the - affected switch */ - if (lamp_flash_test (bank_swinfo->lamp)) - { - dbprintf ("bank %d made flashing\n", bankno); - far_indirect_call_handler (bank->ops->make_flash, EVENT_PAGE); - dbprintf ("called %p\n", bank->ops->make_flash); - } - else if (lamp_test (bank_swinfo->lamp)) - { - dbprintf ("bank %d made lit\n", bankno); - far_indirect_call_handler (bank->ops->make_lit, EVENT_PAGE); - } - else - { - dbprintf ("bank %d made unlit\n", bankno); - far_indirect_call_handler (bank->ops->make_unlit, EVENT_PAGE); - } -} - - -CALLSET_ENTRY (centerbank, bank_center_make_lit) -{ - sound_send (SND_TARGET_1); -} - - -CALLSET_ENTRY (centerbank, bank_center_make_flash) -{ - sound_send (SND_TARGET_5); - score (SC_25K); - bank_target_on (); -} - -CALLSET_ENTRY (centerbank, bank_center_light_all) -{ - bank_flash (BANK_CENTER); - score (SC_250K); - sound_send (SND_EXTRA_BALL_COLLECT); -} - - - -CALLSET_ENTRY (bonus_x, bank_top_make_unlit) -{ - sound_send (SND_DATABASE_CLICK); - score (SC_5K); - bank_target_on (); -} - - -CALLSET_ENTRY (bonus_x, bank_top_light_all) -{ - sound_send (SND_COPTER_1); - score (SC_100K); - bank_clear (BANK_TOP); -} - - -CALLSET_ENTRY (centerbank, start_game) -{ - bank_flash (BANK_CENTER); - bank_clear (BANK_TOP); - bank_clear (BANK_RIGHT); - bank_clear (BANK_SKILL); -} - - -CALLSET_ENTRY (lanes, sw_left_button) -{ - if (in_live_game) - { - lamplist_rotate_previous (LAMPLIST_TOP_LANES, lamp_matrix); - } -} - -CALLSET_ENTRY (lanes, sw_right_button) -{ - if (in_live_game) - { - lamplist_rotate_next (LAMPLIST_TOP_LANES, lamp_matrix); - } -} - -CALLSET_ENTRY (bank, sw_standup_mid_left) -{ bank_sw_handler (BANK_CENTER); } -CALLSET_ENTRY (bank, sw_standup_mid_center) -{ bank_sw_handler (BANK_CENTER); } -CALLSET_ENTRY (bank, sw_standup_mid_right) -{ bank_sw_handler (BANK_CENTER); } - -CALLSET_ENTRY (bank, sw_top_lane_left) -{ bank_sw_handler (BANK_TOP); } -CALLSET_ENTRY (bank, sw_top_lane_center) -{ bank_sw_handler (BANK_TOP); } -CALLSET_ENTRY (bank, sw_top_lane_right) -{ bank_sw_handler (BANK_TOP); } - diff --git a/tools/imgld/imgld.make b/tools/imgld/imgld.make index c8be306c0..431ee880d 100644 --- a/tools/imgld/imgld.make +++ b/tools/imgld/imgld.make @@ -2,7 +2,7 @@ IMGLD := $(D)/imgld TOOLS += $(IMGLD) OBJS := $(D)/imgld.o tools/imglib/imglib.o -$(OBJS) : TOOL_CFLAGS=-Itools/imglib -Iinclude -DNO_MAIN -DCONFIG_NATIVE -DWPC_DMD_LOW_PAGE=0 -DWPC_DMD_HIGH_PAGE=0 +$(OBJS) : TOOL_CFLAGS=-Itools/imglib -Iinclude -DNO_MAIN -DCONFIG_NATIVE -DWPC_DMD_LOW_PAGE=0 -DWPC_DMD_HIGH_PAGE=0 -fgnu89-inline HOST_OBJS += $(OBJS) $(IMGLD) : $(OBJS) diff --git a/tools/imglib/Makefile b/tools/imglib/Makefile index ea8779f38..a5568f065 100644 --- a/tools/imglib/Makefile +++ b/tools/imglib/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS = -g -I../../include -I../../build -I../wpclib -DCONFIG_NATIVE -DWPC_DMD_LOW_PAGE=0 -DWPC_DMD_HIGH_PAGE=0 +CFLAGS = -g -I../../include -I../../build -I../wpclib -DCONFIG_NATIVE -DWPC_DMD_LOW_PAGE=0 -DWPC_DMD_HIGH_PAGE=0 -fgnu89-inline FONT_DIR = ../../fonts WPCLIB_DIR = ../../../wpclib