Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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