Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draw the overmap with SDL using sprites #43203

Closed
wants to merge 273 commits into from

Conversation

KorGgenT
Copy link
Member

Summary

SUMMARY: Features "Graphical Overmap"

Purpose of change

Draw sprites on the overmap instead of ascii.

Describe the solution

create a new function cata_tiles::draw_om and have that draw sprites using the infrastructure we already have in place for the regular terrain view, and extend it a little bit for extra tile types.

Testing

open overmap, scroll around. press the buttons. click the screen.

Additional context

There has been some PR in the past 14 days that has absolutely major conflicts with this PR, and i'm actually really lost in how to fix it. this actually is the main reason i made the pr in the first place, because i need help understanding what happened.

Additionally, clicking with your mouse on the screen doesn't currently change your cursor to the correct location.

@KorGgenT KorGgenT added Info / User Interface Game - player communication, menus, etc. SDL: Tiles / Sound Tiles visual interface and sounds. labels Aug 25, 2020
@KorGgenT
Copy link
Member Author

#42520

@KorGgenT
Copy link
Member Author

@barsoosayque do you have any advice?

@ZhilkinSerg
Copy link
Contributor

ZhilkinSerg commented Aug 25, 2020

@KorGgenT: It should be as easy as:

  1. Stash three new functions you've added to sdltiles.cpp (get_mission_arrow, get_omt_rotation and draw_om).
  2. Rebase your changes on top of current master in favor of master state of sdltiles.cpp.
  3. Add three functions you have stashed earlier to sdltiles.cpp.

Then there are these small changes required to compile (use const references in function paramaters, call properly named members of font class and provide missing new parameters to OutputChar):

diff --git a/src/sdl_font.cpp b/src/sdl_font.cpp
index 985feb2ede..98681ec28e 100644
--- a/src/sdl_font.cpp
+++ b/src/sdl_font.cpp
@@ -220,7 +220,7 @@ std::unique_ptr<Font> Font::load_font( SDL_Renderer_Ptr &renderer, SDL_PixelForm
 
 // line_id is one of the LINE_*_C constants
 // FG is a curses color
-void Font::draw_ascii_lines( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+void Font::draw_ascii_lines( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
                              unsigned char line_id, const point &p, unsigned char color ) const
 {
     SDL_Color sdl_color = palette[color];
@@ -362,8 +362,8 @@ CachedTTFFont::CachedTTFFont(
     TTF_SetFontStyle( font.get(), TTF_STYLE_NORMAL );
 }
 
-SDL_Texture_Ptr CachedTTFFont::create_glyph( SDL_Renderer_Ptr &renderer, const std::string &ch,
-        const int color )
+SDL_Texture_Ptr CachedTTFFont::create_glyph( const SDL_Renderer_Ptr &renderer,
+        const std::string &ch, const int color )
 {
     const auto function = fontblending ? TTF_RenderUTF8_Blended : TTF_RenderUTF8_Solid;
     SDL_Surface_Ptr sglyph( function( font.get(), ch.c_str(), windowsPalette[color] ) );
@@ -419,7 +419,7 @@ bool CachedTTFFont::isGlyphProvided( const std::string &ch ) const
     return TTF_GlyphIsProvided( font.get(), UTF8_getch( ch ) );
 }
 
-void CachedTTFFont::OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &,
+void CachedTTFFont::OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &,
                                 const std::string &ch, const point &p,
                                 unsigned char color, const float opacity )
 {
@@ -494,7 +494,8 @@ BitmapFont::BitmapFont(
     }
 }
 
-void BitmapFont::draw_ascii_lines( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+void BitmapFont::draw_ascii_lines( const SDL_Renderer_Ptr &renderer,
+                                   const GeometryRenderer_Ptr &geometry,
                                    unsigned char line_id, const point &p, unsigned char color ) const
 {
     BitmapFont *t = const_cast<BitmapFont *>( this );
@@ -569,7 +570,7 @@ bool BitmapFont::isGlyphProvided( const std::string &ch ) const
     }
 }
 
-void BitmapFont::OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+void BitmapFont::OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
                              const std::string &ch, const point &p,
                              unsigned char color, const float opacity )
 {
@@ -577,7 +578,7 @@ void BitmapFont::OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &g
     BitmapFont::OutputChar( renderer, geometry, t, p, color, opacity );
 }
 
-void BitmapFont::OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+void BitmapFont::OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
                              const int t, const point &p,
                              unsigned char color, const float opacity )
 {
@@ -668,7 +669,8 @@ bool FontFallbackList::isGlyphProvided( const std::string & ) const
     return true;
 }
 
-void FontFallbackList::OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+void FontFallbackList::OutputChar( const SDL_Renderer_Ptr &renderer,
+                                   const GeometryRenderer_Ptr &geometry,
                                    const std::string &ch, const point &p,
                                    unsigned char color, const float opacity )
 {
diff --git a/src/sdl_font.h b/src/sdl_font.h
index 72ca8b55ac..31a0b150f7 100644
--- a/src/sdl_font.h
+++ b/src/sdl_font.h
@@ -40,7 +40,7 @@ class Font
         /// @param p Point on the screen where to draw character
         /// @param color Curses color to use when drawing
         /// @param opacity Optional opacity of the character
-        virtual void OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+        virtual void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
                                  const std::string &ch, const point &p,
                                  unsigned char color, float opacity = 1.0f ) = 0;
 
@@ -48,7 +48,8 @@ class Font
         /// @param line_id Character to draw
         /// @param point Point on the screen where to draw character
         /// @param color Curses color to use when drawing
-        virtual void draw_ascii_lines( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+        virtual void draw_ascii_lines( const SDL_Renderer_Ptr &renderer,
+                                       const GeometryRenderer_Ptr &geometry,
                                        unsigned char line_id, const point &p, unsigned char color ) const;
 
         /// Try to load a font by typeface (Bitmap or Truetype).
@@ -79,11 +80,11 @@ class CachedTTFFont : public Font
         ~CachedTTFFont() override = default;
 
         bool isGlyphProvided( const std::string &ch ) const override;
-        void OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,  const std::string &ch,
-                         const point &p,
+        void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
+                         const std::string &ch, const point &p,
                          unsigned char color, float opacity = 1.0f ) override;
     protected:
-        SDL_Texture_Ptr create_glyph( SDL_Renderer_Ptr &renderer, const std::string &ch, int color );
+        SDL_Texture_Ptr create_glyph( const SDL_Renderer_Ptr &renderer, const std::string &ch, int color );
 
         TTF_Font_Ptr font;
         // Maps (character code, color) to SDL_Texture*
@@ -130,12 +131,12 @@ class BitmapFont : public Font
         ~BitmapFont() override = default;
 
         bool isGlyphProvided( const std::string &ch ) const override;
-        void OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry, const std::string &ch,
-                         const point &p,
+        void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
+                         const std::string &ch, const point &p,
                          unsigned char color, float opacity = 1.0f ) override;
-        void OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,  int t, const point &p,
-                         unsigned char color, float opacity = 1.0f );
-        void draw_ascii_lines( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry,
+        void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,  int t,
+                         const point &p, unsigned char color, float opacity = 1.0f );
+        void draw_ascii_lines( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
                                unsigned char line_id, const point &p, unsigned char color ) const override;
     protected:
         std::array<SDL_Texture_Ptr, color_loader<SDL_Color>::COLOR_NAMES_COUNT> ascii;
@@ -156,8 +157,8 @@ class FontFallbackList : public Font
         ~FontFallbackList() override = default;
 
         bool isGlyphProvided( const std::string &ch ) const override;
-        void OutputChar( SDL_Renderer_Ptr &renderer, GeometryRenderer_Ptr &geometry, const std::string &ch,
-                         const point &p,
+        void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
+                         const std::string &ch, const point &p,
                          unsigned char color, float opacity = 1.0f ) override;
     protected:
         std::vector<std::unique_ptr<Font>> fonts;
diff --git a/src/sdltiles.cpp b/src/sdltiles.cpp
index 69470f6d1c..7801918cbd 100644
--- a/src/sdltiles.cpp
+++ b/src/sdltiles.cpp
@@ -932,8 +932,8 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt &center_abs_
     }
 #endif
 
-    int width = ( TERMX - OVERMAP_LEGEND_WIDTH ) * font->fontwidth;
-    int height = OVERMAP_WINDOW_HEIGHT * font->fontheight;
+    int width = ( TERMX - OVERMAP_LEGEND_WIDTH ) * font->width;
+    int height = OVERMAP_WINDOW_HEIGHT * font->height;
 
     {
         //set clipping to prevent drawing over stuff we shouldn't
@@ -1117,7 +1117,7 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt &center_abs_
         const auto abs_sm_to_draw_label = [&]( const tripoint_abs_sm & city_pos, const int label_length ) {
             const tripoint tile_draw_pos = global_omt_to_draw_position( project_to<coords::omt>( city_pos ) );
             point draw_point( tile_draw_pos.x * width / max_col, tile_draw_pos.y * height / max_row );
-            draw_point.x -= label_length * font->fontwidth;
+            draw_point.x -= label_length * font->width;
             draw_point.x += width / max_col;
             return draw_point;
         };
@@ -1133,7 +1133,7 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt &center_abs_
             geometry->rect( renderer, clipRect, SDL_Color() );
 
             const point label_pos( draw_pos.x - ( name.length() * fontwidth / 2 ), draw_pos.y );
-            map_font->OutputChar( name, label_pos, 11 );
+            map_font->OutputChar( renderer, geometry, name, label_pos, 11 );
         };
 
         // the tiles on the overmap are overmap tiles, so we need to use

And it works then:

image

image

data/raw/keybindings.json Outdated Show resolved Hide resolved
data/raw/keybindings.json Outdated Show resolved Hide resolved
data/raw/keybindings.json Outdated Show resolved Hide resolved
src/game.h Outdated Show resolved Hide resolved
src/cata_tiles.h Outdated Show resolved Hide resolved
}
} else if( category == C_OVERMAP_NOTE ) {
sym = id[5];
col = color_from_string( id.substr( 7, id.length() - 1 ) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering that we might want to support unicode overmap note symbols, directly indexing the id might not be the best idea. How about extracting it using some separators, or better still use one of subcategory or subtile to pass the symbol?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can rewrite those two lines, i did not expect that there were symbols that were larger than 1 character, but i construct the map note ids using _ as separators.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if at all possible i'd like to defer this, i'm not really sure the proper way to deal with unicode at this time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Search for the first _, and use utf8_getch to read the first unicode symbol, and treat the rest as color id, maybe?

src/overmap_ui.cpp Outdated Show resolved Hide resolved
src/sdltiles.cpp Outdated Show resolved Hide resolved
src/sdltiles.cpp Outdated Show resolved Hide resolved
@ZhilkinSerg
Copy link
Contributor

ZhilkinSerg commented Sep 2, 2020

Boston airport:

sprite map+MA.sqlite
image

https://cddamapalt.ralreegorganon.com/
image

google maps
image

@Zireael07
Copy link
Contributor

Bridge/roads not showing?
Otherwise looks amazing!

@esotericist
Copy link
Contributor

some quick notes:
should be using global bindings for zoom in and zoom out rather than local bindings, so that if someone has set up a binding for the main map interface, they'll work the same on the overmap
for instance, i have mine set up as:
image

and i expect these to "just work" when i bring up the overmap. (see also < and >, which do use the global bindings)

also any changes to the keybindings screen appears to force a refresh of the map, but not the keybindings screen. that's a bit awkward

as for the mouse position issue, the code that controls calculating location is input:context::get_coordinates() in sdltiles.cpp

and it relies on the ability to match the captured window against g->w_terrain in order to know to switch to tile-based logic. we'll need some way of detecting that we're doing overmap drawing in order for this to work correctly.

i'm not seeing offhand any persistent window definition that can be tested against, so unless i'm missing one somewhere i'm not immediately sure on how to get this information to that function without making a bigger mess.

@stale
Copy link

stale bot commented Nov 6, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. Please do not 'bump' or comment on this issue unless you are actively working on it. Stale issues, and stale issues that are closed are still considered.

@stale stale bot added the stale Closed for lack of activity, but still valid. label Nov 6, 2020
@stale
Copy link

stale bot commented Dec 6, 2020

This issue has been automatically closed due to lack of activity. This does not mean that we do not value the issue. Feel free to request that it be re-opened if you are going to actively work on it

@stale stale bot closed this Dec 6, 2020
@stale stale bot removed the stale Closed for lack of activity, but still valid. label Dec 6, 2020
@int-ua
Copy link
Contributor

int-ua commented Jan 13, 2021

Can this code fallback to font symbols when note_{symbol}_{color_string} sprite is not defined?

@int-ua
Copy link
Contributor

int-ua commented Jan 13, 2021

Trying to compile all the new id values for tileset authors, send corrections.

mission_cursor
mission_arrow_n
mission_arrow_s
mission_arrow_nw
mission_arrow_sw
mission_arrow_ne
mission_arrow_se
mission_arrow_e
mission_arrow_w
mission_arrow_down
mission_arrow_up
overmap_horde_3
overmap_horde_4
overmap_horde_5
overmap_horde_6
overmap_horde_?
  1. What is the maximum size of a horde? Why is it starting with 3 and not 1?

  2. Should all the "type": "overmap_terrain" IDs have a sprite ?

@KorGgenT
Copy link
Member Author

KorGgenT commented Jan 13, 2021

Can this code fallback to font symbols when note_{symbol}_{color_string} sprite is not defined?

yup, it already does.

What is the maximum size of a horde? Why is it starting with 3 and not 1?

i think it's a soft cap but i haven't seen anything larger than 6. i don't have an answer for your second question because that's code that's already there.

Should all the "type": "overmap_terrain" IDs have a sprite?

sure. obviously multiple overmap_terrrains can share a sprite if necessary, like i did with houses already.

@int-ua
Copy link
Contributor

int-ua commented Jan 18, 2021

Do I understand correctly that the weather map (Action menu -> Look -> Look at the sky) was not changed?

@KorGgenT
Copy link
Member Author

actually it does try to draw a sprite. at least the last time i checked a month ago. it's the id of the weather at the tile.

src/sdltiles.cpp Outdated Show resolved Hide resolved
jbytheway and others added 15 commits June 22, 2021 01:32
Rewrite get_all_mods to return multiple lines of output.  Two total
conversions should not be in the same line.  The expectation is that we
run the tests loading all the mods in each line.
* llama support files

Some helpful files for anyone who wants to build CDDA using llama, a
tool for outsourcing builds to Amazon Lambda.

* Link to llama guide from COMPILING.md
* Flight gear
Co-authored-by: Binrui Dong <[email protected]>
Added Two-Way Radio to the helmet when on, in-built radio was a common functionality with the helmets I researched.
Co-authored-by: fae <[email protected]>
Co-authored-by: faefux <[email protected]>
Co-authored-by: Anton Burmistrov <[email protected]>
Co-authored-by: chaohedgehogs <[email protected]>
It isn't currently possible to load a world more than once without
restarting the game, because the enchantment factory isn't being
cleared, and Inline enchantments complain if one with the same name
already exists.
Based on adjust_values.py

I want to make changes to armor_portion_data (add more stuff to it), so
I don't want to maintain two separate JSON interfaces for it.

Add a python script to ease conversion from the old format to
armor_portion_data.
If map extras are specified with invalid weights, this can cause a
runtime error when an extra needs to be selected.  Bring that error
forwards to validation time to make it more reliable.
Classic zombies was setting the weight of various map_extras to zero.
This makes sense, but it was also setting the chance of map extras on
certain extras types for every region.  This is problematic because some
regions' extras types lacked any map extras, so setting the chance
non-zero led to errors.

Change the classic zombies mod to just set the extras weights and not
set the chance, so that the regions with no extras would remain at the
default chance of zero and no errors would arise.

As a side-effect, this dramatically increases the chance of field map
extras for the classic zombies mod which had become out of sync with the
base game, which is probably an improvement.
@kevingranade
Copy link
Member

cherry-picked as 1d04305

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Info / User Interface Game - player communication, menus, etc. SDL: Tiles / Sound Tiles visual interface and sounds.
Projects
None yet
Development

Successfully merging this pull request may close these issues.