Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,14 @@ file(GLOB MAIN_SOURCES
Source/PokemonLA/Resources/PokemonLA_PokemonSprites.h
Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.cpp
Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.h
Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.cpp
Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h
Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.cpp
Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.h
Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.cpp
Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.h
Source/PokemonRSE/Programs/TestPrograms/PokemonRSE_SoundListener.cpp
Source/PokemonRSE/Programs/TestPrograms/PokemonRSE_SoundListener.h
Source/PokemonRSE/PokemonRSE_Panels.cpp
Source/PokemonRSE/PokemonRSE_Panels.h
Source/PokemonRSE/PokemonRSE_Settings.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/* Dialog Detector
*
* From: https://github.com/PokemonAutomation/Arduino-Source
*
*/

#include "CommonTools/Images/SolidColorTest.h"
#include "CommonTools/Images/ImageFilter.h"
#include "CommonFramework/ImageTools/ImageBoxes.h"
#include "CommonFramework/ImageTypes/ImageRGB32.h"
#include "CommonFramework/ImageTools/ImageStats.h"
#include "CommonFramework/ImageTypes/ImageViewRGB32.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "PokemonRSE_DialogDetector.h"

#include <iostream>
using std::cout;
using std::endl;

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonRSE{

/*
DialogDetector::DialogDetector(Color color)
: m_left_box(0.155, 0.727, 0.015, 0.168)
, m_right_box(0.837, 0.729, 0.008, 0.161)
{}
void DialogDetector::make_overlays(VideoOverlaySet& items) const{
items.add(COLOR_RED, m_left_box);
items.add(COLOR_RED, m_right_box);
}
bool DialogDetector::detect(const ImageViewRGB32& screen) const{
ImageViewRGB32 left_image = extract_box_reference(screen, m_left_box);
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
if (is_solid(left_image, { 0.335, 0.331, 0.332 }) && is_solid(right_image, { 0.335, 0.331, 0.332 })){
return true;
}
return false;
}
*/

BattleDialogDetector::BattleDialogDetector(Color color)
: m_left_box(0.158, 0.725, 0.011, 0.176)
, m_right_box(0.827, 0.722, 0.013, 0.178)
{}
void BattleDialogDetector::make_overlays(VideoOverlaySet& items) const{
items.add(COLOR_RED, m_left_box);
items.add(COLOR_RED, m_right_box);
}
bool BattleDialogDetector::detect(const ImageViewRGB32& screen) const{
ImageViewRGB32 left_image = extract_box_reference(screen, m_left_box);
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
if (is_solid(left_image, { 0.335, 0.331, 0.332 }) && is_solid(right_image, { 0.335, 0.331, 0.332 })){
return true;
}
return false;
}


BattleMenuDetector::BattleMenuDetector(Color color)
: m_left_box(0.439, 0.717, 0.021, 0.192)
, m_right_box(0.821, 0.725, 0.030, 0.181)
{}
void BattleMenuDetector::make_overlays(VideoOverlaySet& items) const{
items.add(COLOR_RED, m_left_box);
items.add(COLOR_RED, m_right_box);
}
bool BattleMenuDetector::detect(const ImageViewRGB32& screen) const{
ImageViewRGB32 left_image = extract_box_reference(screen, m_left_box);
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
if (is_solid(left_image, { 0.335, 0.331, 0.332 }) && is_solid(right_image, { 0.25, 0.38, 0.369 })){
return true;
}
return false;
}


AdvanceBattleDialogDetector::AdvanceBattleDialogDetector(Color color)
: m_dialog_box(0.156, 0.715, 0.686, 0.193)
, m_left_box(0.156, 0.724, 0.010, 0.176)
, m_right_box(0.836, 0.717, 0.008, 0.189)
{}
void AdvanceBattleDialogDetector::make_overlays(VideoOverlaySet& items) const{
items.add(COLOR_RED, m_dialog_box);
items.add(COLOR_RED, m_left_box);
items.add(COLOR_RED, m_right_box);
}
bool AdvanceBattleDialogDetector::detect(const ImageViewRGB32& screen) const{
const bool replace_color_within_range = false;

//Filter out background
ImageRGB32 filtered_region = filter_rgb32_range(
extract_box_reference(screen, m_dialog_box),
combine_rgb(185, 0, 1), combine_rgb(255, 32, 33), Color(0), replace_color_within_range
);
ImageStats stats = image_stats(filtered_region);

/*
filtered_region.save("./filtered_only.png");
cout << stats.average.r << endl;
cout << stats.average.g << endl;
cout << stats.average.b << endl;
*/

ImageViewRGB32 left_image = extract_box_reference(screen, m_left_box);
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);

if (is_solid(left_image, { 0.335, 0.331, 0.332 })
&& is_solid(right_image, { 0.335, 0.331, 0.332 })
&& (stats.average.r > stats.average.b + 200)
&& (stats.average.r > stats.average.g + 200)
)
{
return true;
}
return false;
}



}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* Dialog Detector
*
* From: https://github.com/PokemonAutomation/Arduino-Source
*
*/

#ifndef PokemonAutomation_PokemonRSE_DialogDetector_H
#define PokemonAutomation_PokemonRSE_DialogDetector_H

#include <chrono>
#include <atomic>
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "Common/Cpp/Color.h"
#include "CommonFramework/ImageTools/ImageBoxes.h"
#include "CommonTools/VisualDetector.h"
#include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h"

namespace PokemonAutomation{
class CancellableScope;
class VideoFeed;
namespace NintendoSwitch{
namespace PokemonRSE{

/*
// TODO: Detect that a dialog box is on screen by looking for the white of the box
class DialogDetector : public StaticScreenDetector{
public:
DialogDetector(Color color);

virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool detect(const ImageViewRGB32& screen) const override;

private:
ImageFloatBox m_left_box;
ImageFloatBox m_right_box;
};
class DialogWatcher : public DetectorToFinder<DialogDetector>{
public:
DialogWatcher(Color color)
: DetectorToFinder("DialogWatcher", std::chrono::milliseconds(250), color)
{}
};
*/

// Battle dialog boxes are teal
class BattleDialogDetector : public StaticScreenDetector{
public:
BattleDialogDetector(Color color);

virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool detect(const ImageViewRGB32& screen) const override;

private:
ImageFloatBox m_left_box;
ImageFloatBox m_right_box;
};
class BattleDialogWatcher : public DetectorToFinder<BattleDialogDetector>{
public:
BattleDialogWatcher(Color color)
: DetectorToFinder("BattleDialogWatcher", std::chrono::milliseconds(250), color)
{}
};


// Battle menu is up when it is white on the right and teal on the left
// For emerald the text is more flush to the left, so we target the right of the battle menu box
class BattleMenuDetector : public StaticScreenDetector{
public:
BattleMenuDetector(Color color);

virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool detect(const ImageViewRGB32& screen) const override;

private:
ImageFloatBox m_left_box;
ImageFloatBox m_right_box;
};
class BattleMenuWatcher : public DetectorToFinder<BattleMenuDetector>{
public:
BattleMenuWatcher(Color color)
: DetectorToFinder("BattleMenuWatcher", std::chrono::milliseconds(250), color)
{}
};



// Detect the red advancement arrow by filtering for red.
// This works for now, I don't think there's colored text?
// TODO: Change this to detect that the dialog arrow is in the dialog box by filtering for the red arrow
class AdvanceBattleDialogDetector : public StaticScreenDetector{
public:
AdvanceBattleDialogDetector(Color color);

virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool detect(const ImageViewRGB32& screen) const override;

private:
ImageFloatBox m_dialog_box;
ImageFloatBox m_left_box;
ImageFloatBox m_right_box;
};
class AdvanceBattleDialogWatcher : public DetectorToFinder<AdvanceBattleDialogDetector>{
public:
AdvanceBattleDialogWatcher(Color color)
: DetectorToFinder("AdvanceBattleDialogWatcher", std::chrono::milliseconds(250), color)
{}
};

// Future note: when given a choice popup, there is no advance arrow.
// FRLG doesn't have an advance arrow, that's a future issue.


}
}
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* Shiny Number Detector
*
* From: https://github.com/PokemonAutomation/Arduino-Source
*
*/

#include "Common/Cpp/Color.h"
#include "CommonFramework/ImageTools/ImageBoxes.h"
#include "CommonFramework/ImageTools/ImageStats.h"
#include "CommonFramework/ImageTypes/ImageRGB32.h"
#include "CommonFramework/ImageTypes/ImageViewRGB32.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "CommonTools/Images/ImageFilter.h"
#include "PokemonRSE_ShinyNumberDetector.h"

//#include <iostream>
//using std::cout;
//using std::endl;

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonRSE{

ShinyNumberDetector::ShinyNumberDetector(Color color)
: m_box_number(0.136, 0.156, 0.123, 0.072)
{}
void ShinyNumberDetector::make_overlays(VideoOverlaySet& items) const{
items.add(COLOR_RED, m_box_number);
}
bool ShinyNumberDetector::read(Logger& logger, const ImageViewRGB32& frame){
const bool replace_color_within_range = true;

//Filter out background
ImageRGB32 filtered_region = filter_rgb32_range(
extract_box_reference(frame, m_box_number),
combine_rgb(138, 97, 221), combine_rgb(200, 181, 239), Color(0), replace_color_within_range
);
ImageStats stats = image_stats(filtered_region);

/*
filtered_region.save("./filtered_only.png");
cout << stats.average.r << endl;
cout << stats.average.g << endl;
cout << stats.average.b << endl;
*/

/*
Shiny:
R: 196.632, G: 196.771, B: 145.863
Not shiny:
R: 181.862, G: 180.686, B: 193.999
*/

if (stats.average.b + 20 < stats.average.r){
return true;
}
return false;
}


}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* Shiny Number Detector
*
* From: https://github.com/PokemonAutomation/Arduino-Source
*
*/

#ifndef PokemonAutomation_PokemonRSE_ShinyNumberDetector_H
#define PokemonAutomation_PokemonRSE_ShinyNumberDetector_H

#include "Common/Cpp/AbstractLogger.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonRSE{

// In the summary screen, the dex number will be yellow if a shiny, white if not.
// Additionally, the background behind the sprite will be white if shiny, grey if not.
// Number is easier to check as the background is scan lines.
class ShinyNumberDetector{
public:
ShinyNumberDetector(Color color);

virtual void make_overlays(VideoOverlaySet& items) const;
bool read(Logger& logger, const ImageViewRGB32& frame);

private:
ImageFloatBox m_box_number;
};



}
}
}
#endif
Loading