Posté le 18/10/2016 à 16:53 Membre depuis le 21/03/2014, 187 messages
Thank you a lot for all of your thoughts and suggestions - these are all things I haven't seen anymore - I think it is because of "routine-blindness".

- I will experiment with the shadows of paddle, blocks, font and background to obtain a better 3D effect.
- The greenish-brownish color scheme was intention (in regards to Irem's color palettes) but I have planned to change the design and color palettes every 10 stages (maybe matching to the boss colors of these stages).
- The regular ball color is yellow but it changes to pink if a "Power Ball" item is collected (ball can destroy a block instantly and changes direction) and to green if a "Hyper Ball" item is collected (ball can destroy a block instantly and does not change direction).
- Shaking the enviroment if a boss gets hit is a nice idea - I will experiment with that also.
- I will add a some kind of effect if the guardline is hit (currently it only changes the color palette according to the guardline hit points), maybe an "electric" sound + flashing effect. Not sure about the random ball direction change but I will try it out. Speed up the ball as a "penalty" could be an option too.
- I need also to add a "splash" animation if a laser shot bullet has hit a block / the end of the playfield frame.
- Yes, I want to add optional spinner controls (HPMAN has suggested it also) and currently I am researching on how this could be done.
Posté le 18/10/2016 à 22:30 Membre depuis le 05/04/2016, 50 messages
Routine blindness affects as all, you are not alone there. That is why its always good to listen to the opinion of others. It does not take away from what you have done but when you listen to what others say you can then relook at your work with fresh eyes.

Make sure you also look into what I suggested about making the bats shadow with alternating pixel checkered board. You could also do the same with the block shadows in normal game play and it will not take any cpu penalty. You will only used extra space in the 'C' ROM space given you need the same sprite tile drawn 4 times (2 times the same of each with alternating checkered board). If you look at my NeoGeo land tech demo on youtube you can see that in action in the drop shadows and ghost in the main menu. Just make sure you view at 720p60 (browser that supports that).

HPman can defo help you with the spinner situation, thats a good call.
Posté le 18/10/2016 à 23:39 Membre depuis le 21/03/2014, 187 messages
Just watched your NeoGeo-Land videos again - these half-transparent shadows look really awesome in 720p.
I will try to recreate this effect - hopefully the frame-rate of my code is not to slow for it triso

Posté le 19/10/2016 à 00:11 Membre depuis le 07/07/2015, 117 messages
NeoHomeBrew (./62) :
..hopefully the frame-rate of my code is not to slow for it triso

do you ever tried the auto-anim-flag in SCB1?
maybe you can use this, it's code-independent.
Posté le 19/10/2016 à 04:34 Membre depuis le 23/10/2015, 48 messages
All I know is this truly epic! Your new boss looks totally kickass!
Pixel Art + Coding + Hardcore Dedication= NeoHomeBrew!
Keep up the good work! and thanks for sharing !!! cyborg
The cyborg represents me scanning these golden pages hungry for what will happen next!
Posté le 19/10/2016 à 13:51 Membre depuis le 05/04/2016, 50 messages
blastar (./63) :
NeoHomeBrew (./62) :
..hopefully the frame-rate of my code is not to slow for it triso

do you ever tried the auto-anim-flag in SCB1?maybe you can use this, it's code-independent.

Yup this is right, it does not matter if your game is even 10fps, the anim will always be 60fps on NTSC systems, 50fps on PAL. Its a win win for transparent effect using cycling checkerboard and i'm surprised more neogeo games never used it. Im guessing you have though about some ways to abuse this feature blaster wink
Posté le 19/10/2016 à 17:18 Membre depuis le 21/03/2014, 187 messages
I have played around with a checkerboard graphic today and had some success but not the desired result...

HPMAN's DATlib documentation explains auto-animation only in "scroller" graphics but unfortunately not in regular "picture" graphics.
But anyway I have saved the following to the "chardata.xml" to add the auto-animation feature to a "picture":

 <pict id="shadow_test">
	<file>gfx\shadow_test0.png</file>
	<auto1>gfx\shadow_test1.png</auto1>
	<auto2>gfx\shadow_test2.png</auto2>
	<auto3>gfx\shadow_test3.png</auto3>
	<flips>xyz</flips>
 </pict>

And have done the initialisation in main.c like a regular (static) "picture"
	pictureInit(&shadow_1, &shadow_test,  54, 40, 98, 20, FLIP_NONE); // 4 sprites
	palJobPut(40, shadow_test_Palettes.palCount, shadow_test_Palettes.data);
	SCClose();

It has worked but I have to write "LSPCmode=0x0000;" in every frame to speed up auto-animation - otherwise it will be overwritten with "LSPCmode=0x1000;" for an unknown reason (maybe a bug in my code?).
It seems a bit to slow and produces a slight "stroboscope-like" effect on the real system (even more noticeable in MAME emulation).

- Not sure if that was a correct way to do this - what would be your opinion HPMAN?
- By the way, is setting LSPCmode ($3C0006) to 0x0000 the fastest auto-animation speed possible?
Posté le 19/10/2016 à 20:10 Membre depuis le 05/04/2016, 50 messages
Yes, you need to set relevant bits in LSPCmode to 0x0 to get the transparency correct. You must be overwriting the value somewhere else in your code if you have to set it every frame. If you can't find it, MAME debugger will be your friend friend... wp 3c0006,2,w

Raz
Posté le 19/10/2016 à 21:36 Membre depuis le 27/04/2006, 59400 messages
NeoHomeBrew (./66) :
It seems a bit to slow and produces a slight "stroboscope-like" effect on the real system (even more noticeable in MAME emulation).
The cycling checkerboard technique does cause flicker at 30 Hz (NTSC) or 25 Hz (PAL). Some people don't notice it or aren't bothered, I tend to find it annoying (but I'm sensitive to flicker, I don't like the 50/60 Hz flicker of CRTs either).

The result will also depend on the kind of monitor you're using. Computer LCD monitors are the worst case, CRTs monitors are nicer, LCD video monitors may be even better (some of them use processing that removes the flicker in that case).

The best is to do beta-testing with different people and monitors smile
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Posté le 20/10/2016 à 00:01 Membre depuis le 21/03/2014, 187 messages
Thanks Zerosquare - Wow, that's very interesting - testing was done on a 60 hz CRT, will test now the image processing abilities on LCD-TV.

Thanks Razoola - will give MAME debugger a try.
BTW: How did you have reached this awesome 720p video quality in Youtube with your NeoGeo-Land demos? I would like to upload a video but it does look not like the original video before uploading it to Youtube.
My current way is:
- to use the -aviwrite parameter to export an unfiltered 320x224 pix .avi-video out of MAME
- upscale the video to 720x480 MP4 > it looks like original at this point
- upload the video to Youtube > their video converter messes up the image quality (max 480p) ...

Here is how it looks now:

Posté le 20/10/2016 à 02:14 Membre depuis le 28/01/2003, 160 messages
NeoHomeBrew (./66) :
It has worked but I have to write "LSPCmode=0x0000;" in every frame to speed up auto-animation - otherwise it will be overwritten with "LSPCmode=0x1000;" for an unknown reason (maybe a bug in my code?).
It seems a bit to slow and produces a slight "stroboscope-like" effect on the real system (even more noticeable in MAME emulation).

- Not sure if that was a correct way to do this - what would be your opinion HPMAN?- By the way, is setting LSPCmode ($3C0006) to 0x0000 the fastest auto-animation speed possible?


LSPCmode is used to set LSPC when using the timer IRQ compatible VBlank interrupt (DAT_vblankTI).
If you use the regular VBLank interrupt (DAT_vblank) it has no effect and you must write to the LSPC directly (volMEMWORD(0x3c0006)=0x0000).
Posté le 20/10/2016 à 04:13 Membre depuis le 21/03/2014, 187 messages
Thanks HPMAN replacing "_IRQ2 = DAT_vblankTI" with "_IRQ2 = DAT_vblank" (in crt0_cart.s) has removed the LSPC writes per frame.
The transparency effect is of the checkerboard graphic is faster now and looks way better on the real system than before (but still stutters in MAME emulation).

On the real system some random red pixels appear in the upper left corner of the screen (only if auto-animation is actively used, they does not appear if the checkerboard graphic is not displayed).
Are they maybe caused by the red job meter? If yes, Is there a way to deactivate the job meter?

@Raz - Thanks for pointing me to the Mame-debugger - it was interesting to see the ASM code running. I was able to identify the LSPC writes with "wp 3c0006,2,w" + "go":

mame-debugger.png
Posté le 20/10/2016 à 04:26 Membre depuis le 28/01/2003, 160 messages
Job meter should be off by default, unless you set it up.
Make sure devmode is off and all debug dips are 0.
Posté le 21/10/2016 à 23:58 Membre depuis le 21/03/2014, 187 messages
Hi HPMAN - thanks for clearing this up, must be something caused by my code - I am checking this currently...

I have another more basic question:
Would it be possible to manipulate a single tile inside a sprite without defining it as animation before?
I am asking because I am running into a sprite problem (exceeding the 381 sprites limit) if I want to use semi-transparent shadows with my current setup.
For instance, is there a way to replace tile 5 of sprite strip A (of my background sprite) with tile 2 of a different sprite strip B (which is not part of the background image but is saved inside the C1/2 roms).
Posté le 22/10/2016 à 01:19 Membre depuis le 28/01/2003, 160 messages
You can use SC1Put for tilemap jobs, you will have to calculate vram addr of changed tile & data addr of tile data.
Posté le 22/10/2016 à 23:04Edité par Razoola le 23/10/2016 à 08:58 Membre depuis le 05/04/2016, 50 messages
I use fraps to capture video (make sure 60fps option set). Then I use virtual dub to correct the levels, double up the resolution (so its just over 720p) and encode as losless mp4. Then upload to youtube. My videos when not watching at 720p60 look the same as the one you posted there.

Like Zerosquare says, once you get it working you should play with the color of the chekered board. Choosing the wrong color can sometimes spoil the effect in a big way. For example, if the background is genurally red, you will be better using a very dark red color for the checkered board instead of black. If the background is already quite dark then black is the way to go.
Posté le 23/10/2016 à 00:38 Membre depuis le 21/03/2014, 187 messages
@ HPMAN and Raz thanks a lot for your advices smile
Currently, I am trying out different ideas how I could save sprites in certain areas - will post results as soon as I have finished something...
Posté le 30/10/2016 à 17:37 Membre depuis le 21/03/2014, 187 messages
I have spent the last week with testing out different ways to display shadows for all game objects.
Now, the greater distances from object to shadow and from outer frame to background generate a more convincing 3D effect (thank you for pointing me to it Razoola wink ) .

This is the current concept:
Ball(s) - checkerboard shadow with regular animation (animation needs more than 8 frames)
Laser-Bullets - checkerboard shadow with regular animation (animation needs more than 8 frames)
Guard-Line - checkerboard shadow with regular animation (animation needs more than 8 frames)
Items - checkerboard shadow with auto-animation
Paddle (+ Laser-Cannon) - solid shadow without animation (to avoid strange looking artefacts when overlapping with Guard-Line shadow)
Blocks - solid shadows without animation but with a slight dithering (I am not really happy with it... )

Originally, I had the Block shadows auto-animated with checkerboard but that has caused too much flickering on the screen - even when viewed on the real system + CRT monitor (it was much more noticable on my LCD monitor).
When an auto-animated checkerboard shadow is moving on the screen (like the Item shadows) there is no flickering noticeable and it looks great.
But when a checkerboard shadow is not moving (like the Block shadows) always a slight flickering appears in the "peripheral field of view". (http://en.wikipedia.org/wiki/File:Peripheral_vision.svg)

Just watched Blastar's latest "lens effect" demo again (topics/186542-new-ngcd-demo) on my real NGCD-System - when the B-Button is pressed the "lens" switches to a circle with a nice "flicker-free" blue transparency effect.
@Blastar - Do you think your "palette ram trick" could be used for my Block shadows (projected on a static background sprite)? If yes, are you maybe in the mood to share some more details on how you have obtained this effect?

This is how it looks now:
Posté le 30/10/2016 à 23:16 Membre depuis le 21/03/2014, 187 messages
@Blastar Just understood the message of your explanation video ... this effect seems to be limited by palette ram size to a max. image resolution of 60 x 60 pix loupe
Unfortunately, that would not be enough for all 108 24x12 pix Block shadows ... #trigol#

Posté le 31/10/2016 à 13:35 Membre depuis le 07/07/2015, 117 messages
yes, you are right - you found an answer by yourself.
this effect is very limited, not only by palette ram. it also needs an image (static backgound) in neogeo-rgb-raw format (304 * 224 * word ~136kb).
you can not use this for shadows... but I got another idea... also palette-based...

bg_0_o.png

I would change the background from 16x16 to 12x12 (using sprite shrinking) because your 'stones' are based on this... now you can use a darker palette to fake a flicker-free static shadow! wink
Posté le 31/10/2016 à 15:28 Membre depuis le 05/04/2016, 50 messages
NeoHomeBrew, You have made a great improovement here and I am glad my suggestion has helped you. I really hope everyone else can also see how different this change has made hypernoid look. the game looks graphically 10x better to me from such a small detail change.

I see you have also altered the inner shadow of the play area making the left side and top shodow more pronounced. I feel this part you might have over done a little. You could try to make the left border and top border shadow to how the right side shadow looks now and remove the right shadow totally (or just remove the right shadow). That would be more in line with the mock up picture I did on the previous page.

Your going to want to look at the small black shadows around the popup information windows that appear when you complete the level also but I guess you have this on your todo list already.

But man, what an improovement so far! The bat / guard shadow is especially impressive now.

[edit] Just spotted the block message smile
Posté le 31/10/2016 à 17:51 Membre depuis le 05/04/2016, 50 messages
blastar (./79) :
I would change the background from 16x16 to 12x12 (using sprite shrinking) because your 'stones' are based on this... now you can use a darker palette to fake a flicker-free static shadow! wink

Doing what blaster suggests here does have some advantages also that may not be instantly apparent.
Posté le 31/10/2016 à 18:06 Membre depuis le 27/04/2006, 59400 messages
./77 : looks good to me smile
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Posté le 31/10/2016 à 19:11 Membre depuis le 21/03/2014, 187 messages
@Blastar - Scaling the tiles to match up with the "block shadow raster" is a smart idea, thanks a lot for suggesting it and for creating the mockup graphic.
I was racking my brain for several days thinking about how I could use pre-rendered shadows (since they are not moving and not animated) - without finding a solution.
But I think that your idea could be the way to go... scale down the tile size and swap out the tiles which have a shadow on it if needed - will post results as soon as possible #marion20n#

@Raz - I am glad you like it - I am very happy with the new visuals also, in comparison it has looked too flat before, now the game objects literally "pop out" of the screen.
Thank you for your additional suggestions:
- I will adjust the frame shadows of the background but I can't remove the right-side shadow completely because the (non-shaded) background green and the frame grey
don't provide a sufficient contrast to divide the play area from the outer frame properly - but I will make it much smaller (left and top shadow will be adjusted too).
- Yes, the missing transparent message box shadows were already on my todo list - but thanks for suggesting it nevertheless.
Posté le 31/10/2016 à 21:41Edité par Razoola le 01/11/2016 à 12:24 Membre depuis le 05/04/2016, 50 messages
You could maybe simply use a black pixel width line on the right boarder to hilight the edges contour of the border that side to try and define the play area better. That might be enough but I understand what you are saying in needing to make the edge stand out.

With the suggestion blaster made you would not actually need to swap out tiles for the shadow effect. You would simply change the palette number for that tile that needed shadow in the background (so its even easier). In effect you would have 2 palletes for the background. One where there is no shadow (normal) and the same palette again but darker (where there is a tile shadow). This would allow you to have a true shadow effect in the background providing the brick tiles are always alligned correctly and never move. The only pain may be designing the backgrounds taking the shrinking into account. Once you did it though you open yourself up to new graphic effects during the game.

The other thing I feel you need to address are the falling pickups although I'm not sure if what you have now (the arkanoid type) are just placeholder graphics. I never liked those in the original arkanoid game but they do not fit with the other graphics of hypernoid. I feel it would look better with larger falling rotating 3d rectangle bricks (slightly smaller than the bricks you destroy with the ball), or even falling eyes that are inside the bricks. If you also make the shadow for them less width (so they appeared closed to the ground) you could make them drop under the remaining static tiles instead of over them. I'm not sure how that would look but it may look nice. Espicially if they disintegrated if they hit the guard and only fell off the screen when the guard was inactive.

I also like the small effect you added with the guard shadow btw going black when the guard is hit.
Posté le 01/11/2016 à 06:19 Membre depuis le 28/01/2003, 160 messages
I prototyped block environment destruction a while back (broforce like).

What I came up with was using a single scroller to hold both states of the stage. Copy the "filled" state section to a ram work copy scroller data, then replacing with "empty" data as blocks gets destroyed.

You can use a similar technique, as your background is static you likely won't need a ram work copy, just edit vram on the go.
Given block size/alignment don't fit exact tiles, you will need to produce a set of tiles to match every combination (96 tiles from what I can see on video about alignment, maybe more to account for border shadow).


Test raw map:
161101061940780895.png

Play result:
161101061940652638.png
Posté le 01/11/2016 à 11:19 Membre depuis le 21/03/2014, 187 messages
@RAZ - I know what you mean, the item pick-up graphics are rolling over the blocks which makes no sense... will focus on that later when I have solved the "shadows problem."

@ HPMAN - that is a clever technique too!

Just played around with SC1 writes with the functions provided by DATlib and have some questions:

1.) SC1Put - function

Since there is no example available how to use this function, I am not sure if this way is correct?

SC1Put(0x0000+64+6, 0x08, 20, bg_shadow.maps[0]); // VRAM SC1 start + sprite-number*64 + tile-number*2, tile count, palette-number, tile-map pointer of source image

This example copies to sprite strip 1 into the 4th tile the data of 8 tiles with palette-number 20 of the source image "bg_shadow".
But it starts always from the first tile of the source image - how I could start copying for instance from 5th tile of the source image?

2.) SC234Put - function

palJobPut(24, bg_shadow_Palettes.palCount, bg_shadow_Palettes.data); // set-up palette 24
SC234Put(0x0000+512+7, 0x1800); // VRAM SC1 start + sprite-nr*64 + tile number*2+1, first 2 digits of the WORD is the palette-no. in hex

In this example I want to write the data of palette number 24 to the palette of the 4th tile of spritestrip 8 (which contains the same image like "bg_shadow" but with a regular (brighter) palette).
It works but the order of the colors seems to be wrong and it results in a messed-up palette - is there a way to assign the colors of the palette in a correct order?
Posté le 01/11/2016 à 12:40 Membre depuis le 05/04/2016, 50 messages
NeoHomeBrew (./86) :
@RAZ - I know what you mean, the item pick-up graphics are rolling over the blocks which makes no sense... will focus on that later when I have solved the "shadows problem."

Yes, if it did not look good going under the blocks either you could simply have an algorhythm that would check the pickup has a path to the bottom of the screen before its given. That way it would never give one that gos over or under a block.

I guess there is no law saying that you have to follow the arkanoid rule of dropping pickups at all. You could for example have static pickups (appear over the destroyed block) that the ball would need to go over to activate (or even pickups moving in different directions but could not move though blocks). The ball would need to travel though them and not bounce off and they could vanish after a short time too. Doing something like that would change the game a little but but it would add a unique aspect compared to arkanoid. It would probably also add a frustration aspect to the game because they would be harder to get and some may appear you don't want but you still hit them with the ball.
Posté le 01/11/2016 à 16:10 Membre depuis le 28/01/2003, 160 messages
NeoHomeBrew (./86) :
1.) SC1Put - function

Since there is no example available how to use this function, I am not sure if this way is correct?

SC1Put(0x0000+64+6, 0x08, 20, bg_shadow.maps[0]); // VRAM SC1 start + sprite-number*64 + tile-number*2, tile count, palette-number, tile-map pointer of source image

This example copies to sprite strip 1 into the 4th tile the data of 8 tiles with palette-number 20 of the source image "bg_shadow".
But it starts always from the first tile of the source image - how I could start copying for instance from 5th tile of the source image?
uint *shadowMap;
shadowMap=(uint*)bg_shadow.maps[0];

SC1Put(0x0000+64+6,0x08,20,&shadowMap[4]); //5th tile


NeoHomeBrew (./86) :
2.) SC234Put - function

palJobPut(24, bg_shadow_Palettes.palCount, bg_shadow_Palettes.data); // set-up palette 24
SC234Put(0x0000+512+7, 0x1800); // VRAM SC1 start + sprite-nr*64 + tile number*2+1, first 2 digits of the WORD is the palette-no. in hex

In this example I want to write the data of palette number 24 to the palette of the 4th tile of spritestrip 8 (which contains the same image like "bg_shadow" but with a regular (brighter) palette). It works but the order of the colors seems to be wrong and it results in a messed-up palette - is there a way to assign the colors of the palette in a correct order?

Did you generate palettes separately? You can't be sure how colors end up sorted with buildchar with two different files.
If your picture is 16 colors, process a single picture, and have first two tiles hold palettes (just draw a 15px color strip). Have color order sorted accordingly into thoses color strips. Ii will generate a single picture with the two palettes.
Not sure if that's clear fou
Posté le 01/11/2016 à 18:57 Membre depuis le 21/03/2014, 187 messages
@Raz - these are nice ideas - will work out something soon... thanks again for your suggestions #Alcooli4#
@HPMAN - Your SC1Put method works perfectly to pick a tile and write it to a different map - thank you a lot for the code #bonjour#
I will explain what I want to do with the SC234Put function with a more detailed sample code and demo-pics in the next days.
Posté le 07/11/2016 à 14:05 Membre depuis le 21/03/2014, 187 messages
Success #alandon# ! Thanks to all who have helped!
Now, I have shrinked the tilemap to my desired grid size (12x12 pix) and thanks to HPMAN's code snippet I can swap out the shrinked tiles with tiles from a different image which is located in the C1/C2 ROMs (but not loaded into VRAM before).

During experimenting, I have found out that vertical shrinking is done by the system by up-scaling or down-scaling of the 16th "pixel line" of the 16th tile (marked in orange color in the following image/video).
That means, if you want to shrink a sprite with a tile-size of 16 or more, you have to split the image and re-assemble it again at the "repeating point" between tile 1 and tile 32 to avoid pixel distortion at the 16th line of tile 16.

Here is a short video which shows the vertical shrinking behavior:


And here are the two images without shadows and with shadows:
background_scale.png background_scale_dark.png

And the code:
void load_background()
{
	short i=0;
	short x=44;
	short y=184;
	short exit_loop=0;

	uint *BGscaleDarkMap; // setup tilemap pointer
	picture background_1;

	volMEMWORD(0x401ffe)=0x0000; // set BG color to black

	initGfx();
	clearFixLayer();
	clearSprites(1, 381);

	palJobPut(1, hypernoid_font_Palettes.palCount, hypernoid_font_Palettes.data); // fix layer palette

	// set up background sprite
	pictureInit(&background_1, &background_scale, 100, 24, x, y, FLIP_NONE); // 19 sprites, 2 palettes
	palJobPut(24, background_scale_Palettes.palCount, background_scale_Palettes.data);

	// load palette of source image
	palJobPut(26, background_scale_dark_Palettes.palCount, background_scale_dark_Palettes.data); // 2 palettes

	SCClose();

	// assign source image tilemap to pointer
	BGscaleDarkMap=(uint*)background_scale_dark.maps[0];

	do
	{
		waitVBlank();

		fixPrintf(2,3,1,3,"i: %05d", i);
		fixPrintf(2,4,1,3,"y: %05d", y);

		p1=volMEMBYTE(P1_CURRENT);
		ps=volMEMBYTE(PS_CURRENT);

		if(p1&JOY_A){if(i<64) i+=1;}
		if(p1&JOY_B){if(i>-191)i-=1;}
		if(p1&JOY_D) exit_loop=1;

		if(p1&JOY_UP)   {y-=1;}
		if(p1&JOY_DOWN) {y+=1;}

		pictureSetPos(&background_1, x, y);

		SCClose();

		// manipulate tilemap -> SCB1 VRAM $0000-$6FFF
		// VRAM SC1 start + start_sprite_no + (64*sprite_no_diff) + start_tile_no + (2*tile_no), tile_count, source_img_palette_no, &source_img_map[18+(32*sprite_no_diff) + tile_no]

		// smiley eyes

		SC1Put(0x0000+6400+(64*7)+36+(2*5),0x01, 26, &BGscaleDarkMap[18+(32*7)+5]); 	// sprite 107 tile 7 = shadow 49 left
		SC1Put(0x0000+6400+(64*8)+36+(2*5),0x01, 26, &BGscaleDarkMap[18+(32*8)+5]); 	// sprite 108 tile 7 = shadow 49 right

		SC1Put(0x0000+6400+(64*7)+36+(2*6),0x01, 26, &BGscaleDarkMap[18+(32*7)+6]); 	// sprite 107 tile 8 = shadow 58 left
		SC1Put(0x0000+6400+(64*8)+36+(2*6),0x01, 26, &BGscaleDarkMap[18+(32*8)+6]); 	// sprite 108 tile 8 = shadow 58 right

		SC1Put(0x0000+6400+(64*7)+36+(2*7),0x01, 26, &BGscaleDarkMap[18+(32*7)+7]); 	// sprite 107 tile 9 = shadow 67 left
		SC1Put(0x0000+6400+(64*8)+36+(2*7),0x01, 26, &BGscaleDarkMap[18+(32*8)+7]); 	// sprite 108 tile 9 = shadow 67 right

		SC1Put(0x0000+6400+(64*11)+36+(2*5),0x01, 26, &BGscaleDarkMap[18+(32*11)+5]); 	// sprite 111 tile 7 = shadow 51 left
		SC1Put(0x0000+6400+(64*12)+36+(2*5),0x01, 26, &BGscaleDarkMap[18+(32*12)+5]); 	// sprite 112 tile 7 = shadow 51 right

		SC1Put(0x0000+6400+(64*11)+36+(2*6),0x01, 26, &BGscaleDarkMap[18+(32*11)+6]); 	// sprite 111 tile 8 = shadow 60 left
		SC1Put(0x0000+6400+(64*12)+36+(2*6),0x01, 26, &BGscaleDarkMap[18+(32*12)+6]); 	// sprite 112 tile 8 = shadow 60 right

		SC1Put(0x0000+6400+(64*11)+36+(2*7),0x01, 26, &BGscaleDarkMap[18+(32*11)+7]); 	// sprite 111 tile 9 = shadow 69 left
		SC1Put(0x0000+6400+(64*12)+36+(2*7),0x01, 26, &BGscaleDarkMap[18+(32*12)+7]); 	// sprite 112 tile 9 = shadow 69 right

		// smiley mouth

		SC1Put(0x0000+6400+(64*3)+36+(2*9),0x01, 26, &BGscaleDarkMap[18+(32*3)+9]); 	// sprite 103 tile 11 = shadow 83 left
		SC1Put(0x0000+6400+(64*4)+36+(2*9),0x01, 26, &BGscaleDarkMap[18+(32*4)+9]); 	// sprite 104 tile 11 = shadow 83 right

		SC1Put(0x0000+6400+(64*5)+36+(2*10),0x01, 26, &BGscaleDarkMap[18+(32*5)+10]); 	// sprite 105 tile 12 = shadow 93 left
		SC1Put(0x0000+6400+(64*6)+36+(2*10),0x01, 26, &BGscaleDarkMap[18+(32*6)+10]); 	// sprite 106 tile 12 = shadow 93 right

		SC1Put(0x0000+6400+(64*7)+36+(2*11),0x01, 26, &BGscaleDarkMap[18+(32*7)+11]); 	// sprite 107 tile 13 = shadow 103 left
		SC1Put(0x0000+6400+(64*8)+36+(2*11),0x01, 26, &BGscaleDarkMap[18+(32*8)+11]); 	// sprite 108 tile 13 = shadow 103 right

		SC1Put(0x0000+6400+(64*9)+36+(2*11),0x01, 26, &BGscaleDarkMap[18+(32*9)+11]);	// sprite 109 tile 13 = shadow 104 left
		SC1Put(0x0000+6400+(64*10)+36+(2*11),0x01, 26, &BGscaleDarkMap[18+(32*10)+11]);	// sprite 110 tile 13 = shadow 104 right

		SC1Put(0x0000+6400+(64*11)+36+(2*11),0x01, 26, &BGscaleDarkMap[18+(32*11)+11]);	// sprite 111 tile 13 = shadow 105 left
		SC1Put(0x0000+6400+(64*12)+36+(2*11),0x01, 26, &BGscaleDarkMap[18+(32*12)+11]);	// sprite 112 tile 13 = shadow 105 right

		SC1Put(0x0000+6400+(64*13)+36+(2*10),0x01, 26, &BGscaleDarkMap[18+(32*13)+10]);	// sprite 113 tile 12 = shadow 97 left
		SC1Put(0x0000+6400+(64*14)+36+(2*10),0x01, 26, &BGscaleDarkMap[18+(32*14)+10]);	// sprite 114 tile 12 = shadow 97 right

		SC1Put(0x0000+6400+(64*15)+36+(2*9),0x01, 26, &BGscaleDarkMap[18+(32*15)+9]);	// sprite 115 tile 11 = shadow 89 left
		SC1Put(0x0000+6400+(64*16)+36+(2*9),0x01, 26, &BGscaleDarkMap[18+(32*16)+9]);	// sprite 116 tile 11 = shadow 89 right

		 // shrink tilemap to 12x12 tiles  -> SCB2 VRAM $8000-$81FF shrinking coefficients

		SC234Put(0x8000+100, 0x0BBF+i); // shrink sprite no. 100
		SC234Put(0x8000+101, 0x0BBF+i); // shrink sprite no. 101
		SC234Put(0x8000+102, 0x0BBF+i); // shrink sprite no. 102
		SC234Put(0x8000+103, 0x0BBF+i); // shrink sprite no. 103
		SC234Put(0x8000+104, 0x0BBF+i); // shrink sprite no. 104
		SC234Put(0x8000+105, 0x0BBF+i); // shrink sprite no. 105
		SC234Put(0x8000+106, 0x0BBF+i); // shrink sprite no. 106
		SC234Put(0x8000+107, 0x0BBF+i); // shrink sprite no. 107
		SC234Put(0x8000+108, 0x0BBF+i); // shrink sprite no. 108
		SC234Put(0x8000+109, 0x0BBF+i); // shrink sprite no. 109
		SC234Put(0x8000+110, 0x0BBF+i); // shrink sprite no. 110
		SC234Put(0x8000+111, 0x0BBF+i); // shrink sprite no. 111
		SC234Put(0x8000+112, 0x0BBF+i); // shrink sprite no. 112
		SC234Put(0x8000+113, 0x0BBF+i); // shrink sprite no. 113
		SC234Put(0x8000+114, 0x0BBF+i); // shrink sprite no. 114
		SC234Put(0x8000+115, 0x0BBF+i); // shrink sprite no. 115
		SC234Put(0x8000+116, 0x0BBF+i); // shrink sprite no. 116
		SC234Put(0x8000+117, 0x0BBF+i); // shrink sprite no. 117
		SC234Put(0x8000+118, 0x0BBF+i); // shrink sprite no. 118

	}while(!(exit_loop==1));
}