Skip to content

Commit

Permalink
Work on autofire
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkwhoffmann committed Jul 22, 2024
1 parent 07ce900 commit 5dd1ae7
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 162 deletions.
5 changes: 3 additions & 2 deletions Emulator/Base/Defaults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,9 @@ Defaults::Defaults()
setFallback(OPT_MOUSE_VELOCITY, 100, { 0, 1} );

setFallback(OPT_JOY_AUTOFIRE, false, { 0, 1} );
setFallback(OPT_JOY_AUTOFIRE_BULLETS, -3, { 0, 1} );
setFallback(OPT_JOY_AUTOFIRE_DELAY, 125, { 0, 1} );
setFallback(OPT_JOY_AUTOFIRE_BURSTS, false, { 0, 1} );
setFallback(OPT_JOY_AUTOFIRE_BULLETS, 3, { 0, 1} );
setFallback(OPT_JOY_AUTOFIRE_DELAY, 5, { 0, 1} );
setFallback(OPT_AUD_SAMPLING_METHOD, SMP_NONE);
setFallback(OPT_AUD_FILTER_TYPE, FILTER_A500);
setFallback(OPT_AUD_PAN0, 50);
Expand Down
1 change: 1 addition & 0 deletions Emulator/Base/Option.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ OptionParser::create(Option opt, i64 arg)
case OPT_MOUSE_VELOCITY: return numParser();

case OPT_JOY_AUTOFIRE: return boolParser();
case OPT_JOY_AUTOFIRE_BURSTS: return boolParser();
case OPT_JOY_AUTOFIRE_BULLETS: return numParser();
case OPT_JOY_AUTOFIRE_DELAY: return numParser();

Expand Down
10 changes: 7 additions & 3 deletions Emulator/Base/OptionTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,11 @@ enum_long(OPT)
OPT_MOUSE_VELOCITY,

// Joystick
OPT_JOY_AUTOFIRE,
OPT_JOY_AUTOFIRE_BULLETS,
OPT_JOY_AUTOFIRE_DELAY,
// Joystick
OPT_JOY_AUTOFIRE, ///< Autofire status [on/off]
OPT_JOY_AUTOFIRE_BURSTS, ///< Burst mode [on/off]
OPT_JOY_AUTOFIRE_BULLETS, ///< Number of bullets per burst
OPT_JOY_AUTOFIRE_DELAY, ///< Delay between two shots [frames]

// Paula audio
OPT_AUD_SAMPLING_METHOD,
Expand Down Expand Up @@ -302,6 +304,7 @@ struct OptionEnum : util::Reflection<OptionEnum, Option>
case OPT_MOUSE_VELOCITY: return "MOUSE.VELOCITY";

case OPT_JOY_AUTOFIRE: return "JOY.AUTOFIRE";
case OPT_JOY_AUTOFIRE_BURSTS: return "JOY.AUTOFIRE_BURSTS";
case OPT_JOY_AUTOFIRE_BULLETS: return "JOY.AUTOFIRE_BULLETS";
case OPT_JOY_AUTOFIRE_DELAY: return "JOY.AUTOFIRE_DELAY";

Expand Down Expand Up @@ -444,6 +447,7 @@ struct OptionEnum : util::Reflection<OptionEnum, Option>
case OPT_MOUSE_VELOCITY: return "Mouse velocity";

case OPT_JOY_AUTOFIRE: return "Autofire";
case OPT_JOY_AUTOFIRE_BURSTS: return "Burst mode";
case OPT_JOY_AUTOFIRE_BULLETS: return "Number of bullets per burst";
case OPT_JOY_AUTOFIRE_DELAY: return "Autofire delay in frames";

Expand Down
157 changes: 114 additions & 43 deletions Emulator/Peripherals/Joystick/Joystick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ i64
Joystick::getOption(Option option) const
{
switch (option) {

case OPT_JOY_AUTOFIRE: return (i64)config.autofire;
case OPT_JOY_AUTOFIRE_BURSTS: return (i64)config.autofireBursts;
case OPT_JOY_AUTOFIRE_BULLETS: return (i64)config.autofireBullets;
case OPT_JOY_AUTOFIRE_DELAY: return (i64)config.autofireDelay;

Expand All @@ -48,27 +49,27 @@ void
Joystick::setOption(Option option, i64 value)
{
switch (option) {

case OPT_JOY_AUTOFIRE:

config.autofire = bool(value);
reload();
return;

// Release button immediately if autofire-mode is switches off
if (value == false) button = false;
case OPT_JOY_AUTOFIRE_BURSTS:

config.autofireBursts = bool(value);
reload();
return;

case OPT_JOY_AUTOFIRE_BULLETS:

config.autofireBullets = isize(value);

// Update the bullet counter if we're currently firing
if (bulletCounter > 0) reload();

config.autofireBullets = isize(value);
reload();
return;

case OPT_JOY_AUTOFIRE_DELAY:

config.autofireDelay = isize(value);
return;

Expand All @@ -81,14 +82,14 @@ void
Joystick::_dump(Category category, std::ostream& os) const
{
using namespace util;

if (category == Category::Config) {

dumpConfig(os);
}

if (category == Category::State) {

os << tab("Button 1 pressed") << bol(button) << std::endl;
os << tab("Button 2 pressed") << bol(button2) << std::endl;
os << tab("Button 3 pressed") << bol(button3) << std::endl;
Expand All @@ -106,10 +107,65 @@ Joystick::_didLoad()
axisY = 0;
}

void
Joystick::setButton(bool value)
{
button = value;
printf("button = %d\n", button);
}


bool
Joystick::isAutofiring()
{
return bulletCounter > 0;
}

void
Joystick::startAutofire()
{
debug(true, "startAutofire()\n");

// Load magazine
reload(config.autofireBursts ? config.autofireBullets : INT64_MAX);

// Fire the first shot
setButton(true);

// Schedule the release event
nextAutofireReleaseFrame = agnus.pos.frame + 2;
}

void
Joystick::stopAutofire()
{
debug(true, "stopAutofire()\n");

// Release button and empty the bullet counter
setButton(false);
bulletCounter = 0;

// Clear all events
nextAutofireFrame = nextAutofireReleaseFrame = 0;
}

void
Joystick::reload()
{
bulletCounter = (config.autofireBullets < 0) ? INT64_MAX : config.autofireBullets;
if (config.autofire) {

reload(config.autofireBursts ? config.autofireBullets : INT64_MAX);

} else {

reload(0);
}
}

void
Joystick::reload(isize bullets)
{
bulletCounter = bullets;
}

void
Expand Down Expand Up @@ -149,7 +205,7 @@ u16
Joystick::joydat() const
{
// debug("joydat\n");

u16 result = 0;

/* 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
Expand Down Expand Up @@ -184,7 +240,7 @@ Joystick::trigger(GamePadAction event)
debug(PRT_DEBUG, "trigger(%s)\n", GamePadActionEnum::key(event));

switch (event) {

case PULL_UP: axisY = -1; break;
case PULL_DOWN: axisY = 1; break;
case PULL_LEFT: axisX = -1; break;
Expand All @@ -199,30 +255,42 @@ Joystick::trigger(GamePadAction event)


case PRESS_FIRE:

// If autofire is enabled...
if (config.autofire) {
if (bulletCounter) {

// Cease fire
bulletCounter = 0;
button = false;


// ...check if we are currently firing.
if (isAutofiring()) {

// If yes, the required action depends on the autofire mode.
if (config.autofireBursts) {

// In burst mode, reload the magazine.
reload(config.autofireBullets);

} else {

// Otherwise, stop firing.
stopAutofire();
}

} else {

// Load magazine
button = true;
reload();
scheduleNextShot();
// We are currently not firing. Initiate the first shot.
startAutofire();
}

} else {
button = true;

setButton(true);
}
break;

case RELEASE_FIRE:
if (!config.autofire) button = false;

if (!config.autofire) setButton(false);
break;

default:
break;
}
Expand All @@ -232,22 +300,25 @@ Joystick::trigger(GamePadAction event)
void
Joystick::eofHandler()
{
// Only proceed if auto fire is enabled
if (!config.autofire || config.autofireDelay < 0) return;
if (isAutofiring()) {

// Only proceed if a trigger frame has been reached
if (agnus.pos.frame != nextAutofireFrame) return;
if (agnus.pos.frame == nextAutofireFrame) {

// Only proceed if there are bullets left
if (bulletCounter == 0) return;

if (button) {
button = false;
bulletCounter--;
} else {
button = true;
setButton(true);
nextAutofireReleaseFrame = nextAutofireFrame + 2;
}

if (agnus.pos.frame == nextAutofireReleaseFrame) {

setButton(false);
if (--bulletCounter > 0) {
nextAutofireFrame = nextAutofireReleaseFrame + config.autofireDelay;
printf("bullets = %lld delay = %ld\n", bulletCounter, config.autofireDelay);
} else {
stopAutofire();
}
}
}
scheduleNextShot();
}

}
17 changes: 15 additions & 2 deletions Emulator/Peripherals/Joystick/Joystick.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Joystick : public SubComponent, public Inspectable<JoystickInfo> {
ConfigOptions options = {

OPT_JOY_AUTOFIRE,
OPT_JOY_AUTOFIRE_BURSTS,
OPT_JOY_AUTOFIRE_BULLETS,
OPT_JOY_AUTOFIRE_DELAY
};
Expand All @@ -55,12 +56,13 @@ class Joystick : public SubComponent, public Inspectable<JoystickInfo> {
// Vertical joystick position (-1 = up, 1 = down, 0 = released)
int axisY = 0;

// Bullet counter used in multi-fire mode
// Bullet counter used in autofire mode
i64 bulletCounter = 0;

// Next frame to auto-press or auto-release the fire button
i64 nextAutofireFrame = 0;

i64 nextAutofireReleaseFrame = 0;


//
// Initializing
Expand Down Expand Up @@ -167,8 +169,19 @@ class Joystick : public SubComponent, public Inspectable<JoystickInfo> {

private:

// Sets the button state
void setButton(bool value);

// Checks whether autofiring is active
bool isAutofiring();

// Starts or stops autofire mode
void startAutofire();
void stopAutofire();

// Reloads the autofire magazine
void reload();
void reload(isize bullets);

// Updates variable nextAutofireFrame
void scheduleNextShot();
Expand Down
1 change: 1 addition & 0 deletions Emulator/Peripherals/Joystick/JoystickTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct GamePadActionEnum : util::Reflection<GamePadActionEnum, GamePadAction>
typedef struct
{
bool autofire;
bool autofireBursts;
isize autofireBullets;
isize autofireDelay;
}
Expand Down
12 changes: 8 additions & 4 deletions GUI/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ extension Keys {

// Joysticks
static let autofire = "Controls.Autofire"
static let autofireBursts = "Controls.AutofireBursts"
static let autofireBullets = "Controls.AutofireBullets"
static let autofireFrequency = "Controls.AutofireFrequency"

Expand Down Expand Up @@ -505,8 +506,9 @@ extension DefaultsProxy {

// Joysticks
register(Keys.Con.autofire, false)
register(Keys.Con.autofireBullets, -3)
register(Keys.Con.autofireFrequency, 2.5)
register(Keys.Con.autofireBursts, false)
register(Keys.Con.autofireBullets, 3)
register(Keys.Con.autofireFrequency, 25)

// Mouse
register(Keys.Con.retainMouseKeyComb, 0)
Expand Down Expand Up @@ -556,6 +558,7 @@ extension Preferences {
defaults.set(Keys.Con.disconnectJoyKeys, disconnectJoyKeys)

defaults.set(Keys.Con.autofire, autofire)
defaults.set(Keys.Con.autofireBursts, autofireBursts)
defaults.set(Keys.Con.autofireBullets, autofireBullets)
defaults.set(Keys.Con.autofireFrequency, autofireFrequency)

Expand All @@ -581,9 +584,10 @@ extension Preferences {
disconnectJoyKeys = defaults.bool(Keys.Con.disconnectJoyKeys)

autofire = defaults.bool(Keys.Con.autofire)
autofireBursts = defaults.bool(Keys.Con.autofireBursts)
autofireBullets = defaults.int(Keys.Con.autofireBullets)
autofireFrequency = defaults.double(Keys.Con.autofireFrequency)
autofireFrequency = defaults.int(Keys.Con.autofireFrequency)

retainMouseKeyComb = defaults.int(Keys.Con.retainMouseKeyComb)
retainMouseWithKeys = defaults.bool(Keys.Con.retainMouseWithKeys)
retainMouseByClick = defaults.bool(Keys.Con.retainMouseByClick)
Expand Down
Loading

0 comments on commit 5dd1ae7

Please sign in to comment.