|
Post by 0x8bitdev on Mar 18, 2023 10:26:20 GMT
It seems that the functionality of MPD/SPD libraries has long been stabilized and is unlikely to change. I remember 'someone' lacked 500+ HuC procedures in a project... So it's time to help a bit on my part and optimize their number in the libraries. Hope I am not too late. Overall, I managed to get rid of 46 public and internal procedures: MPD -25 and SPD -21. Not a bad harvest... In this regard, the __macro modifier came in handy. Small, simple ASM routines are replaced by __macros. Some HuC functions have been inlined. Simple single-line functions are replaced by #defines. MPD v0.8: [#define] mpd_get_curr_screen_ind() [#define] mpd_clear_update_flags() [#define] mpd_copy_screen(...) [#define] mpd_get_map_size(...) [#define] mpd_get_start_screen(...) [#define] mpd_init_base_ent_arr() [#define] mpd_get_base_ent_cnt() [#define] mpd_draw_screen_by_ind(...) [#define] mpd_draw_screen_by_data(...) [#define] mpd_draw_screen() [macro] mpd_load_palette(...) The use of local variables and function arguments has also been optimized in the remaining functions. SPD v0.7: [macro] spd_init() [macro] spd_SG_bank_get_ind() [macro] spd_sprite_params(...) [macro] spd_get_dbl_buff_ind() [macro] spd_SATB_get_pos() [macro] spd_SATB_set_pos(...) [macro] spd_SATB_to_VRAM() [macro] spd_set_palette_LT(...) [macro] spd_get_palette_LT() [macro] spd_set_pri_LT(...) [macro] spd_set_x_LT(...) [macro] spd_get_x_LT() [macro] spd_set_y_LT(...) [macro] spd_get_y_LT() [macro] spd_show_LT() [macro] spd_hide_LT() [macro] spd_SG_data_params(...) [macro] spd_copy_SG_data_to_VRAM.4(...) Just in case... This means that all these functions will be inlined in your code when using, otherwise they will be ignored and not compiled.
|
|
|
Post by hyperfighting on Mar 18, 2023 21:20:13 GMT
0x8bitdev - This is HUGE! Thanks for harvesting the crops! I've got the updated library plugged in and no complaints things seem to be running great! Really "someone" had over 500 procedures at one point?! Crazy
|
|
|
Post by 0x8bitdev on Mar 19, 2023 10:48:25 GMT
hyperfighting - This can be a temporary relief. Only refactoring will help!.. or CD version... or refactoring and CD version... In any case, refactoring will definitely come in handy.
|
|
|
Post by hyperfighting on Mar 19, 2023 14:32:55 GMT
0x8bitdev - I know I likely have a long way to go but I am pretty happy with the current state of the code. That said there is all always room for improvement I definitely see lots of optimizations in my future One thing I have been struggling with is the "How To Play" example where "How To Play" remains fixed at the top of the screen as a "Banner". This part works great...The "Banner" is always fixed at the top of the screen while the screen scrolls. My initialization looks like this... disp_off(); vsync(); //BANNER aka "How To Play" scroll(0, 0, 224, 0, 31, 0xC0); // BAT Location (Vertical) 0-224 (BAT Bottom) / Map Window Size (Vertical) 0-31 mpd_init(5, 0); mpd_draw_screen_by_ind_offs( 0, 1792, FALSE);// (224/8=28 / 320/8=40) 28x40 = 1792 BAT Bottom //Horizontal Scrollable Map scroll(1, mpd_scroll_x, 32, 32, 223, 0xC0); //BAT Location (Vertical) 0-32 (Just after status bar) (BAT Bottom) //Window Size 32-223 mpd_init(6, 1); mpd_draw_screen(); disp_on(); vsync(); Main Loop looks like this mpd_update_screen();
scroll(0, 0, 224, 0, 31, 0xC0); scroll(1, mpd_scroll_x, 32, 32, 223, 0xC0); //Window Size 32-224 The next part I attempted but am failing at is I have 3 speed icons that indicate which speed is selected. This will likely look overkill but this is how I tried to handle it. I figured the "How To Play" screen just has blue space so I had room to include 4 variations of the "Banner" I want to jump to the appropriate banner variation when a new speed is triggered but I am constantly failing to correctly access these areas in the Map. Currently I abandoned this approach and used "mpd_draw_block2x2(...);" at the points the icons need to appear. It does work great when the screen is static but when the screen scrolls the icons scroll out of the window. Would you mind helping me get my bearings on the best way to handle this problem?
|
|
|
Post by 0x8bitdev on Mar 20, 2023 11:02:13 GMT
hyperfighting - If I understand you correctly... You have the fixed banner - 'How To Play' and there is a scrollable part of the screen. And you are trying to use the 'mpd_draw_block2x2(...)' to insert speed icons into the scrollable part of the screen. That in the scrollable part of the screen these icons scroll along with the screen is the correct, expected behavior. Because you're writing new tiles into the scrollable area of the BAT, which will scroll the same way as the rest of the scrollable screen area. Because there is no difference between screen tiles and speed icon tiles. They are all located in the scrollable BAT area. Either draw the speed icon tiles into the fixed banner area. "How to Play" doesn't scroll anywhere, does it? Either draw the icons on the scrollable part of the screen with sprites, not tiles(!) Tiles are always scrolled with the screen. But sprites have to be moved each individually. If you don't move them, they will stand still anywhere on the screen.
|
|
|
Post by hyperfighting on Mar 20, 2023 13:48:19 GMT
0x8bitdev - You are correct in your analysis of my issue. - I used "mpd_draw_block2x2(...);" as a place holder so I could continue programming around my problem. I realize it isn't designed for this purpose. - I do not want to use sprites because I know I can draw the speed icons in the 320x32 "How To Play" "Banner" area that remains fixed. - I created a screen in MAPeD that has 4 - 320x32 variant "Banner" gfx embedded in it and I hope to "jump" between each of the "Banners" every time a new icon needs to be displayed. Is the way to handle this issue to call "mpd_draw_screen_by_ind_offs( 0, BAT_LOCATION, FALSE);" when I need the "Banner" to change? I have tried this method and the gfx always get messed up. I'm not sure where I am going wrong. I am hoping where I have coded "mpd_draw_block2x2(...);" I can replace those instances with "mpd_draw_screen_by_ind_offs(...);" assuming my BAT LOCATION value is correct. EX: BAT_LOCATION - BANNER 1 = (224/8=28 / 320/8=40) 28x40 = 1792 EX: BAT_LOCATION - BANNER 2 = (32/8=4 / 320/8=40) 4x40 = 160 + 1792 = 1952
|
|
|
Post by 0x8bitdev on Mar 20, 2023 14:15:29 GMT
hyperfighting - Don't complicate the simple task... Use one banner image - "How To Play" without icons and mpd_draw_CHR(...) for drawing the speed icons 1-3 on the fixed area. There is nothing easier. That's it! mpd_draw_screen_by_ind_offs(...) - draws whole screen with BAT offset and that is not a main problem in your case. Just don't complicate the simple things...
|
|
|
Post by hyperfighting on Mar 20, 2023 21:51:24 GMT
0x8bitdev - You know I complicate simple things its what I do! Thanks for getting me on track here but I can't seem get this working....I can't draw in the Banner window but the scrollable map area is fine. Main Loop mpd_clear_update_flags();
mpd_update_screen(); scroll(0, 0, 224, 0, 31, 0xC0); //BANNER
//Also tried inserting mpd_draw_CHR(...); //No result if CHR is placed between Y(0-31)
scroll(1, mpd_scroll_x, 32, 32, 223, 0xC0); //Window Size 32-224 //Scrollable Map
//This fails for some reason because it is drawn inside of the static Banner window Y (0-31) //I have tried many values they all seem to fail //mpd_draw_CHR(8, 24, 0xA6, 0x03); //Drawn inside of the Banner window
//This works anything drawn outside of the Banner window range mpd_draw_CHR(8, 32, 0xA6, 0x03); //This works because it is below Y (32-223)
spd_SATB_to_VRAM(); mpd_update_screen(); pokew( 0x220c, mpd_scroll_x ); pokew( 0x2210, mpd_scroll_y );
vsync();
|
|
|
Post by 0x8bitdev on Mar 21, 2023 8:53:05 GMT
hyperfighting , You are right. Your code will not work as you expect. The problem is that you don't understand how the HuC's scroll(...) works. You just copied a couple of lines from the MPD doc, but forgot to copy the comments... So read the HuC doc, how the 'scroll' works. Then look at your code and find out where in BAT memory your banner is placed and why your code doesn't work. "Don't copy blindly someone else's code. Try to understand why it is written that way..." Someone Programming is a very tricky thing. You have to always be on your guard. p.s.:
scroll(...)
and
pokew( 0x220c, mpd_scroll_x ); pokew( 0x2210, mpd_scroll_y );
in one loop... Are you sure? Read the doc again... We have already talked about this.
|
|
|
Post by hyperfighting on Mar 21, 2023 16:09:06 GMT
0x8bitdev - My apologies we have already talked about the "poke" and when to use and when not to. Thank you for pointing me in this direction. My main loop uses this function...I made an error in the last post my current HUD code does not use the "poke" it is directed to the vsync(); only in this case. void RENDER_SPRITE_MAP() { //load all sprites to VRAM SAT spd_SATB_to_VRAM();
if(C_RENDER_MAPED) { //NO HUD //Multi-directional Scrolling mpd_update_screen(); pokew( 0x220c, mpd_scroll_x ); pokew( 0x2210, mpd_scroll_y ); vsync(); } else if (!(C_SKIP_VSYNC)) { vsync(); } } I revised my previous init code... removing unnecessary lines void INIT_HUD_AND_MAP() { disp_off(); vsync(); //STATUS BAR aka "How To Play" // init HUD out of the visible BAT area scroll(0, 0, 224, 0, 31, 0xC0); mpd_init(5, 0); mpd_draw_screen_by_ind_offs( 0, 1792, FALSE); //224x8=1792 //init horizontally scrollable MAP mpd_init(6, 1); mpd_draw_screen(); disp_on(); vsync(); }
Main Loop spd_SATB_to_VRAM();//Load Sprite Data mpd_update_screen(); scroll(1, mpd_scroll_x, 32, 32, 223, 0xC0); //Horizontal Scrollable Area vsync();
The Banner appears correctly. The Map scrolls in X while the Banner remains fixed. I still can't get the speed icon to appear using EX: mpd_draw_CHR(8, 16, 0xA6, 0x03);//This does work if the Y value (16) is greater than 32 (Bleeding into the Scrollable Map Window Region) Things seem clear to me.... -Banner visible window (Top is 0x Bottom is 31y) / virtual screen reference area is 0x and 224y pixels from the top of the virtual screen /Banner is loaded and stored outside of the visible area using mpd_draw_screen_by_ind_offs(...) -Scrollable Map is loaded / visible window (Top is 32x Bottom is 223y) / virtual screen reference area is "variable x" and 32y pixels from the top of the virtual screen / Scrollable Map is updated in X when required. -Sprite data appears on top of the background. 1- I read the HuC doc on scroll again...I think I get it. 2- I searched "poke" in mph.h - I saw you note where you clearly describe the two methods regarding using HUD and not having a HUD I'm not sure what I am missing?
|
|
|
Post by 0x8bitdev on Mar 21, 2023 16:49:23 GMT
hyperfighting So, after figuring everything out and knowing that your banner is outside the visible area, you still believe that your icons should jump there by themselves? That's not the case. They appear exactly where you draw them. [drum roll] ... Come on! I believe in you!
|
|
|
Post by hyperfighting on Mar 21, 2023 16:55:15 GMT
0x8bitdev - I just got it!!!!!!!!!!!!!!!!! Damn it you beat me to the post! Thanks for believing in me! mpd_draw_CHR(8, 248, 0xA6, 0x03); //The magic is in 248! In BAT I am drawing to 224 and beyond so I need to adjust my Y value to reflect this! **Edit I know I can be super annoying THANK YOU! For your help and patience!
|
|
|
Post by 0x8bitdev on Apr 14, 2023 11:07:50 GMT
It seems that the functionality of MPD/SPD libraries has long been stabilized and is unlikely to change. But... No! Sometimes optimization opens up new opportunities... And for some, long-awaited ones. Hi, hyperfighting ! No one knew, but... Yes, dynamic maps... you wanted that!!! Long story short... MPD v0.9: Dynamic tilemaps:~~~~~~~~~~~~~ The information below applies mainly to multi-directional maps. By default, all maps data are stored in ROM. Accessing them requires constant switching of memory banks. This can be avoided by placing the map data in RAM. This greatly speeds up data access and gives new features such as dynamically changing map and tile properties. Dynamic map changing can be used to change a map topology, procedural generation of levels, also it's fastest way for storing collectable items etc... There are three types of data that can be located in RAM: - tilemap data - tilemap LUT - tile properties This data can be initialized into RAM independently of each other. It all depends on the amount of free RAM available. You can do this by placing the following declarations before the MPD library is included in your program: #define MPD_RAM_MAP #define MPD_RAM_MAP_TBL#define MPD_RAM_TILE_PROPS <-- can be used with any type of maps(!) All these defines speed up getting a tile property and slightly speed up static screens drawing and scrolling. MPD_RAM_MAP - enables the following functions: [macro] u8 mpd_get_tile( u16 _x, u16 _y, bool _pixels ) / _pixels = TRUE - pixel coordinates, FALSE - tile coordinates [macro] void mpd_set_tile( u16 _x, u16 _y, bool _pixels, u8 _tile_ind ) / _pixels = TRUE - pixel coordinates, FALSE - tile coordinates, _tile_ind - 0..255 MPD_RAM_TILE_PROPS - enables the following functions: #if FLAG_PROP_ID_PER_CHR[macro] u8 mpd_get_tile_property( u8 _tile_ind, u8 _CHR_ind ) / _tile_ind - 0..255, _CHR_ind - 0..3 [macro] void mpd_set_tile_property( u8 _tile_ind, u8 _CHR_ind, u8 _new_prop ) / _tile_ind - 0..255, _CHR_ind - 0..3, _new_prop - a new property value #else //FLAG_PROP_ID_PER_BLOCK[macro] u8 mpd_get_tile_property( u8 _tile_ind ) / _tile_ind - 0..255 [macro] void mpd_set_tile_property( u8 _tile_ind, u8 _new_prop ) / _tile_ind - 0..255, _new_prop - a new property value #endif //FLAG_PROP_ID_PER_CHRBy default, implementations of these functions are unsafe. You can write data outside the arrays by mistake. Use MPD_DEBUG when developing, to enable safe function implementations. If you write data outside of the allocated memory, you will get an error message, function name and its arguments. The amount of memory that will be allocated for the data can be seen in <my_exported_tilemap>.h#define MAX_MAP_SIZE ... #define MAX_MAP_TBL_SIZE ... #define MAX_TILE_PROPS_SIZE ...NOTE: If several maps are exported, memory will be allocated for the largest map(!)Transferring this data to RAM will have a positive effect on performance, even if you don't intend to use dynamic maps and tile properties features. It all depends on the amount of free RAM in your project and the size of your maps. The size of a map can far exceed the amount of available RAM. So plan and allocate memory in your project carefully to effectively use the MPD library. There are two example projects that demonstrate dynamic maps functionality: Simple map editor:./samples/pce/tilemap_render/multidir_scroll_map_editor/ Procedural generation of a random maze (3x3 screens):./samples/pce/tilemap_render/multidir_scroll_maze_generator/ NOTE: Dynamic maps support RLE-compression(!).New read-only public variables are also available~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Map width/height in tiles:R: u16 mpd_map_tiles_width R: u16 mpd_map_tiles_height Size of the tile properties array of a current map when declaring the MPD_RAM_TILE_PROPS:R: u16 mpd_tile_props_arr_size ASM MPD_DEBUG/SPD_DEBUG changed to HuC ' #define MPD_DEBUG' / ' #define SPD_DEBUG' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [upd]: Forgot to say... Some changes have been made in MAPeD-PCE and a few bugs have been fixed. So re-export your projects.
|
|
|
Post by hyperfighting on Apr 15, 2023 14:59:37 GMT
Obviously this post needs to start with this Thanks so much for this incredible update!!! Plugged in your update! Love your examples! The Map editor is so cool!!!! At first I got compilation errors on my project but I missed your final note... I re-exported my MAPeD project and I saw immediate speed gains when scrolling. Should I always use RLE compression from this point forward? I haven't tested this yet? To think I was inching toward a proper update in the second quarter now I have to incorporate animated tiles! Lucky the second quarter just started! I think I can do it! I'll run by you my approach to cycling tiles when I get a some code brewing.... Off the top I'm thinking this... Animated Tiles: Tiles that cycle more than one frame of animation... Similar to the concept of scrolling a map left to right a "for" loop searches the next off screen column of vertical 4x4 blocks. If the "for" loop locates an animated tile it flags it. All flagged tiles animate based on the number of 4x4 blocks in the animation. At the duration assigned to 4x4 block. I know this is pushing it... I know, I know give them the world and they just keep asking for more...would you ever consider building that functionality into MAPeD Editor now that speed is there to look up each block. Whatever I end up writing will likely be slower than whatever ASM you whip up under the hood to facilitate this behavior. Just asking your thoughts not trying to be a little B! Thanks again this is tremendous! *Edit upon further review I am starting to see that one use is to ensure the tile property is swapped when the map is updated....I might have missed the point here... Previously we can put blocks anywhere on the MAP we want after the MAP is loaded. EX: mpd_draw_tile4x4( tile_x, tile_y, curr_tile_ind ); I never needed to test if the new 4x4 tile had a different property if that property was swapped in or the previous blocks property was maintained. In this case lets say you had a "Floor" with a property of 1 and you replaced it with a "Sky" property of 0 the floor property of 1 would maintain itself letting the player stand on the sky. I'm not sure if that is the previous functionality before the update or not... I tried playing around in the editor example and I disabled the "mpd_set_tile( tile_x, tile_y, TRUE, curr_tile_ind );" and the editor still seemed to function correctly. I am failing to grasp the significance of this function..."show tile()" already draws the tile to the screen so why do we need "mpd_set_tile( tile_x, tile_y, TRUE, curr_tile_ind );" in this case? void put_tile()
{ show_tile(); //mpd_set_tile( tile_x, tile_y, TRUE, curr_tile_ind ); // TRUE - coordinates in pixels update_property(); } *Edit again! To answer my own question.... "mpd_set_tile( tile_x, tile_y, TRUE, curr_tile_ind );" officially sets the tile in MAP space so if you are somewhere other than the first screen The new tiles X,Y co-ordinates are maintained making traversing the MAP seamless! ** Edit Once more..... The idea mill is turning...lets say you meet a condition of a secret door.... So you play the level no secret door... You play the level again and you meet a condition and a secret door appears! How cool is that lol this functionality caters to that functionality oooooh the possibilities! Tom Cruise jumping on Oprah's coach "Anything is Possible!!!!!!"
|
|
|
Post by hyperfighting on Apr 16, 2023 14:35:32 GMT
Hi 0x8bitdev Caught up in the hype of your update I was inspired to attempt my animated tile idea. I imported some tiles and off I went. Three frames per tile... I realize that in this case my approach is wrong. A) Drawing these tiles to screen every 5 ticks is taxing B) I am wasting tile space by having three frames of animation. The real method here would be palette cycling. A) Cycling a few colours in a palette must be way less intensive than drawing new tiles to the screen. B) I only have one tiles worth of space. The setup... The tile has 4 colours. 1. Blue - Background 2. Black - Border 3. Green - Inner Background 4. Light Green - Decoration Create a tile with 6 colours 1. Blue - Background 2. Black - Border 3. Green - Inner Background 4. Light Green - Decoration -Frame 1 5. Amber - Decoration -Frame 2 6. Red - Decoration -Frame 2 The trick is 2 of the 4,5,6 colours are muted with the Inner Background (colour 3) per frame and 1 of the colours has the Light Green Decoration Colour set. On Frame 1 - Colour 5,6 are set to Colour 3 - Inner Background On Frame 2 - Colour 5 is set to Colour 4 - Light Green Decoration Colour 4 is set to Colour 3- Inner Background On Frame 3 - Colour 6 is set to Colour 5 - Light Green Decoration Colour 5 is set to Colour 3- Inner Background etc... With MAPeD I can get as far as inserting the 6 colour tile...would you ever consider incorporating this palette shifting functionality? Or is this better suited being manually coded? In either case I'm very excited about this prospect but I'm not sure how to proceed with offsetting and injecting colours into specific indexes any insights would be a big help. I don't know of any examples of this behavior off hand.
|
|