Page 2 of 4

Re: Project - Mega Dracula - Help / Updates

Posted: Thu Sep 03, 2015 4:12 pm
by matteus
Thanks for this I've had to do things slightly differently but I've made use of your example :)

Code: Select all

          
           
            // set boundaries
            u16 PositionCalc = 0;
            PositionCalc = (PositionInt) % 20;

            u16 RowTopInt;
            u16 RowBottomInt;

            RowBottomInt = PositionCalc * 20;
            RowTopInt = (PositionCalc * 20) + 20;

            if ((PositionInt + 1) == RowTopInt) { LT = 1; } // CAN'T GO LEFT
            if (PositionInt < 20) { DN = 1; } // CAN'T GO DOWN
            if (PositionInt == RowBottomInt) { RT = 1; } // CAN'T GO RIGHT
            if (PositionInt > 279) { UP = 1; } // CAN'T GO UP


Re: Project - Mega Dracula - Help / Updates

Posted: Thu Sep 03, 2015 4:29 pm
by matteus
I wondered if someone could tell me if there was an easier way of delaying text than doing this!

Code: Select all

	case 6 :
            if (drawnScreen == 0) {
                ind = TILE_USERINDEX;
                VDP_drawImageEx(BPLAN, &roomNorth_image, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, ind), 0, 0, TRUE, TRUE);
                ind += roomNorth_image.tileset->numTile;
                clearMessageBox();
                drawnScreen = 1;
            }
            if (SubStageInt == 60) {
                VDP_drawText("Welcome inside...", 2, 23);
            } else if (SubStageInt == 120) {
                VDP_drawText("You have entered the tomb of Dracula.", 2, 24);
            } else if (SubStageInt == 180) {
                VDP_drawText("The door closes behind you...", 2, 25);
                SubStageInt = 0;
                StageInt = 7;
            }
            SubStageInt++;
            handleInput();
            break;
        case 7 :
I'd love to get it writing the text character by character but I'm not sure how easy that is to do!

Re: Project - Mega Dracula - Help / Updates

Posted: Thu Sep 03, 2015 5:42 pm
by djcouchycouch
You'll need a more generic system to store all your text and to print them.
Hard coding them like that will become a huge chore.

The first thing to do is to Store all your text as const strings and have your rooms reference them when needed. Having all of them in one spot will help with organization.

I'm on my phone so I can do a full example, but you should think about how you'd write a system that takes one of those strings and prints it to the screen generically.

Re: Project - Mega Dracula - Help / Updates

Posted: Thu Sep 03, 2015 8:27 pm
by matteus
I'm presently trying to use the Sprites engine and getting an issue!

src\main.c|150|warning: passing arg 2 of `SPR_initSprite' discards qualifiers from pointer target type|

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 12:03 am
by djcouchycouch
matteus wrote:I'm presently trying to use the Sprites engine and getting an issue!

src\main.c|150|warning: passing arg 2 of `SPR_initSprite' discards qualifiers from pointer target type|
It would help if you show us the line and the types you're using :)

I've seen this message most often when passing const parameters to functions that use non-const parameters. It's warning you because since the function's parameter is non-const, it can change the values of the variable you're passing.

So you'll get the warning for something like:

Code: Select all


Sprite mySprite = { blah blah };
const SpriteDefinition mySpriteDef = { blah blah blah }; // notice it's const

SPR_initSprite(mySprite, &mySpriteDef, x, y, attribut); // should give you a warning here

I think the function should use const parameters but that's for Stef to decide :)

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 12:45 am
by djcouchycouch
matteus wrote:I wondered if someone could tell me if there was an easier way of delaying text than doing this!

Code: Select all

	case 6 :
            if (drawnScreen == 0) {
                ind = TILE_USERINDEX;
                VDP_drawImageEx(BPLAN, &roomNorth_image, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, ind), 0, 0, TRUE, TRUE);
                ind += roomNorth_image.tileset->numTile;
                clearMessageBox();
                drawnScreen = 1;
            }
            if (SubStageInt == 60) {
                VDP_drawText("Welcome inside...", 2, 23);
            } else if (SubStageInt == 120) {
                VDP_drawText("You have entered the tomb of Dracula.", 2, 24);
            } else if (SubStageInt == 180) {
                VDP_drawText("The door closes behind you...", 2, 25);
                SubStageInt = 0;
                StageInt = 7;
            }
            SubStageInt++;
            handleInput();
            break;
        case 7 :
I'd love to get it writing the text character by character but I'm not sure how easy that is to do!
What you have there are basically scripted events. At a certain time value, you do something different. If you really want to avoid writing your event /text code this way, you're going to need a more generic way to do it.

The following is just to give you ideas. There are most likely much better ways.

Every room has events like "show a picture" and "print text", right? You could put them in a structure like. (pseudo-C ahead)


Code: Select all

// event types
#define EVENT_SHOWSCREEN 0
#define EVENT_CLEARTEXT 1
#define EVENT_PRINTTEXT   2
#define EVENT_WAIT 3
#define EVENT_END 4

// event struct
typedef struct
{
    u16 eventType;
    void* parameter;
} Event;

typedef struct
{
    u16 plan;
    const Image *image;
    u16 basetile;
    u16 x; 
    u16 y; 
    u16 load pal;
    u16 use_dma
} BackgroundParameters;

And then for each room, you define a series of events.

Code: Select all


BackgroundParameters roomt20Image = { BPLAN, &roomNorth_image, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, ind), 0, 0, TRUE, TRUE } 

Event room20Events[] = {
{  EVENT_SHOWSCREEN, (void*)&room20Image},
{  EVENT_CLEARTEXT, 0 },
{  EVENT_WAIT, 60 }, // 60 is the amount of time to wait
{  EVENT_PRINTTEXT, "Welcome inside..."}, // your text box manager will know where to print this
{  EVENT_WAIT, 60 },
{  EVENT_PRINTTEXT, "You have entered the tomb of Dracula."}, // your textbox manager will know to print this after the first line
{  EVENT_WAIT, 60 },
{  EVENT_PRINTTEXT, "The door closes behind you...""},
{ EVENT_WAIT_FOR_KEYPRESS, 0},
{ EVENT_END, 0}
}
You would have a manager that acts as a state machine. It takes an array of those events and processes them.

So when you enter room #20, some code somewhere will call:

Code: Select all

EventManager_runEvents(room20Events);
The EventManager, run every frame, will process those events. It'll be pretty much a big switch statement.

Code: Select all

void EventManager_runEvents(Event* events)
{
   EventMananger_ResetVariables();
   currentEvents = events;
}

// run every frame
void EventManager_UpdateEvents()
{
	if (timer > 0)
	{
	    timer--;
	    return;
	}
	
	while (currentEvent != 0)
	{
	switch (currentEvent->eventType)
	{
	case EVENT_SHOWSCREEN:
	    BackgroundParameters* parameters = (BackgroundParameters*)currentEvent->eventType;
	    VDP_drawImageEx(parameter->plan, parameter->image, etc, etc.);
	break;
	case EVENT_CLEARTEXT:
	    // clears the text box
	break;
	case EVENT_PRINT:
	    char* text = currentEvent->parameter;
	    VDP_drawText(text, 2, 23 + currentLine); // change the 23 (or whatever the y of the first line is) to a define or a constant.
	    currentLine++
	    if (currentLine > maxNumberOfLines)
	    {
	       currentLine = 0;
	    }
	break;
	case EVENT_WAIT
	 timer = currentEvent->parameter;
	 currentEvent++;
	 return;
	case EVENT_END:
	currentEvent = null.
	return;
	 }

	currentEvents++;
	} 
}
It's really rough, but something like that. Don't expect the above to work or compile :) I can't build it for you, but you should be able to get ideas from it.

You can add new events like EVENT_CHANGEROOM which will load up another series of events. Anything you want.

For printing one letter at time, you'd add an extra event like EVENT_PRINTSLOW and use a timer inside the update function to print one letter at a time.

You're basically building a state machine for your game. There's a lot of information about them out there.

A system like that is more complicated up front than writing everything like you are now, but it's more flexible in the long term. Maybe not for your current game, but maybe for the next one.

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 6:22 am
by matteus
Thanks as someone on sega 16 noted this is a port of a zx spectrum basic game :) the code is already way more advanced than the original tho :)

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 10:16 am
by matteus
I'm really learning a lot from you guys and I really appreciate it!

Still have an error with sprites: `SPR_initSprite' discards qualifiers from pointer target type

Code: Select all

 
int main()
{
    //u16 palette[64];
    u16 ind;

    // disable interrupt when accessing VDP
    SYS_disableInts();
    // initialization
    VDP_setScreenWidth320();

    // init sprites engine
    SPR_init(256);

    // set all palette to black
    //VDP_setPaletteColors(0, palette_black, 64);

    // VDP process done, we can re enable interrupts
    SYS_enableInts();

    JOY_setEventHandler(joyEvent);

    ind = TILE_USERINDEX;

// sprites structure
Sprite sprites[2];	
   
    while(TRUE)
    {
 
 	if (animationLoop < 3) {
                if (animationDirection == 0) {
                    if (animationFrame < 8) {
                        animationFrame++;
                        SPR_initSprite(&sprites[0], &ghoulHead_sprite, 70, 60+animationFrame, TILE_ATTR(PAL3, TRUE, FALSE, FALSE));
                        VDP_setPalette(PAL3, ghoulHead_sprite.palette->data);
                    } else {
                        animationDirection = 1;
                    }
                } else if (animationDirection == 1) {
                    if (animationFrame > 1) {
                        animationFrame--;
                        SPR_initSprite(&sprites[0], &ghoulHead_sprite, 70, 60+animationFrame, TILE_ATTR(PAL3, TRUE, FALSE, FALSE));
                        VDP_setPalette(PAL3, ghoulHead_sprite.palette->data);
                    } else {
                        animationDirection = 0;
                        animationLoop++;
                    }
                }
            }
            SPR_initSprite(&sprites[1], &ghoulBody_sprite, 70, 100, TILE_ATTR(PAL3, TRUE, FALSE, FALSE));
            
     }       

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 11:08 am
by djcouchycouch
What does the declaration of the ghoul head and parts look like?

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 12:36 pm
by matteus
SPRITE ghoulHead_sprite "ghoulHead.png" 6 5 -1 5
SPRITE ghoulBody_sprite "ghoulBody.png" 6 5 -1 5

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 12:40 pm
by djcouchycouch
Oh, I see. It's declared in the resource file.

It's probably generating them as const structures and that's why the function is just complaining about it.

You can cast the parameter to a SpriteDefintion pointer and the warning will go away.

Code: Select all

SPR_initSprite(mySprite, (SpriteDefinition*)&mySpriteDef, x, y, attribut);

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 1:06 pm
by matteus
Sorry about that miscommunication couchy! I should have been more precise :( I'll give that a go and see what happens!

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 9:10 pm
by matteus
I've been trying to be clever unfortunately this code doesn't work! It says the structure has no member named 'palette'?

Code: Select all

void animateEnemy(Sprite headSprite, Sprite bodySprite) {
    if (animationLoop < 3) {
        if (animationDirection == 0) {
            if (animationFrame < 8) {
                animationFrame++;
                SPR_initSprite(&sprites[0], (SpriteDefinition*)&headSprite, EnemySpriteXInt, EnemySpriteYInt+animationFrame, TILE_ATTR(PAL3, TRUE, FALSE, FALSE));
                VDP_setPalette(PAL3, headSprite.palette->data);
            } else {
                animationDirection = 1;
            }
        } else if (animationDirection == 1) {
            if (animationFrame > 0) {
                animationFrame--;
                SPR_initSprite(&sprites[0], (SpriteDefinition*)&headSprite, EnemySpriteXInt, EnemySpriteYInt+animationFrame, TILE_ATTR(PAL3, TRUE, FALSE, FALSE));
                VDP_setPalette(PAL3, headSprite.palette->data);
            } else {
                animationDirection = 0;
                animationLoop++;
            }
        }
    }
    SPR_initSprite(&sprites[1], (SpriteDefinition*)&bodySprite, EnemySpriteXInt, EnemySpriteYInt+40, TILE_ATTR(PAL3, TRUE, FALSE, FALSE));
    VDP_setPalette(PAL3, bodySprite.palette->data);
    SPR_update(sprites, 2);
}

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 9:33 pm
by djcouchycouch
There are several instances of palettes in the code. Which is giving you problems ? What's the actual error code?

Re: Project - Mega Dracula - Help / Updates

Posted: Fri Sep 04, 2015 9:40 pm
by matteus
All 3 Couchy