Project - Mega Dracula - Help / Updates

SGDK only sub forum

Moderator: Stef

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Project - Mega Dracula - Help / Updates

Post by matteus » Tue Sep 01, 2015 9:12 am

It was bound to happen eventually :) I'm writing a game! It's going to be pretty basic but I'm going to post my progress and need for help here! My experiment with animation may even come in handy with this project!

I'm having to get back into the swing of writing purely in C rather than C#.

First stumbling block, I'm not sure how to strcat strings in C!

Code: Select all

                // add string item to ling string
                strcat(lineStr, " " & tempStr);
Okay so I fixed the problem in this instance I need to call strcat twice! Once for the space and then once again to add the number

Code: Select all

                strcat(lineStr, " ");
                strcat(lineStr, tempStr);
Last edited by matteus on Tue Sep 01, 2015 4:49 pm, edited 2 times in total.

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Project - Mega Space Heist - Help / Updates

Post by matteus » Tue Sep 01, 2015 10:23 am

Strings are really driving me nuts! The following function is flagging me with the error:

incompatible types in assignment

I'm confused surely a 1 character char should be assigned the character s without an issue?

Code: Select all

static char mapItemLookup(u16 P)
{
    char returnStr[1] = "";
    switch (P)
    {
        case 143 :
            returnStr = "s";
            break;
        case 90 :
            returnStr = "z";
            break;
        case 71 :
            returnStr = "g";
            break;
        case 68 :
            returnStr = "d";
            break;
        case 63 :
            returnStr = "?";
            break;
        case 61 :
            returnStr = "\061";
            break;
        case 42 :
            returnStr = "\042";
            break;
        case 45 :
            returnStr = "\095";
            break;
        case 43 :
            returnStr = "\043";
            break;
        default :
            returnStr = "0";
    }
    return returnStr;
}

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Re: Project - Mega Space Heist - Help / Updates

Post by djcouchycouch » Tue Sep 01, 2015 10:58 am

It's because you've got them double quotes (") which means it's a string (char*) and not a single character. You need to put them in single quotes (') for single characters.

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Project - Mega Space Heist - Help / Updates

Post by matteus » Tue Sep 01, 2015 3:11 pm

Thanks Couchy! I've another one you might be able to help me with!

I'm not great with the whole concept of writing to the screen on every refresh. I've got this code structure so far:

Code: Select all

    while(TRUE)
    {
    
        handleInput();
        
        if (stage == 0) {
            VDP_drawText("Hello......", 1, 10);
        } else if (stage == 1) {
            VDP_resetScreen();
            stage = 2;
        } else if (stage == 2) {
             VDP_drawText("How are you?", 1, 10);
        } 
        
    }

static void handleInput()
{
    u16 value = JOY_readJoypad(JOY_1);

    if (value & BUTTON_START) {
            stage++;
    }

}
The problem is because the start button is so sensitive to being held down my stage increment jumps the gun too quickly and I end up with stage==6 or stage==7 with one press. How do you get around this sort of thing?

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Re: Project - Mega Dracula - Help / Updates

Post by djcouchycouch » Tue Sep 01, 2015 5:59 pm

I think it's because JOY_readJoypad just returns the state of the button, pressed or not pressed. The code checks whether it's pressed, increments the stage variable but when it comes back on the next frame, sees that it's still pressed and does the work again. It'll do it as long as the button is held down.

What you need is to know when the button was released. To know if the button was released, you need to check what the state of the button was on the previous frame. If the button was pressed on the previous frame and not pressed on the current frame, that means the button was released and you can increment stage.

so something like:

Code: Select all

// this is somewhere
u16 lastStartState = 0;

static void handleInput()
{
    u16 value = JOY_readJoypad(JOY_1);

    u16 currentStartState = value & BUTTON_START;

    if (lastStartState && !currentStartStage) { // lastStartState is 1 and currentStartState is 0
            stage++;
    }

    lastStartState = currentStartState;

}

You can also generalize the "last state" stuff so that it handles all the buttons, to figure out if a button was just pressed or just released, etc.

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Re: Project - Mega Dracula - Help / Updates

Post by tryphon » Tue Sep 01, 2015 6:15 pm

Personnally, I make something like that:

Code: Select all

u16 joy_value;
u16 joy_change;

void handle_input() {
    u16 old_value = joy_value;
    joy_value = JOY_readJoypad(JOY_1);

    joy_change = ~old_value & joy_value;
}
This way joy_change contains states of all buttons that were just "clicked". You can access to a particular button the same way you do with joy_value.

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Project - Mega Dracula - Help / Updates

Post by matteus » Tue Sep 01, 2015 8:14 pm

Thank you guys! You've sorted my problem, I'm about 25% through the build :) Should have something to show very shortly! I want to try and get a pixel artist helping me first though!

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Project - Mega Dracula - Help / Updates

Post by matteus » Tue Sep 01, 2015 8:18 pm

Does anyone know how to access the window plan?

KanedaFr
Administrateur
Posts: 1139
Joined: Tue Aug 29, 2006 10:56 am
Contact:

Re: Project - Mega Dracula - Help / Updates

Post by KanedaFr » Tue Sep 01, 2015 11:02 pm

For joy handling, I suggest to use Joy_eventHandler

ex: https://bitbucket.org/SpritesMind/genre ... trols.c-72

A lot more useful since handler is only called on change and you already have the changed and current joy status

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Project - Mega Dracula - Help / Updates

Post by matteus » Wed Sep 02, 2015 9:34 am

To calculate when you can't go beyond a wall I use the following code:

I'm not sure how to deal with this one in C as it uses decimal places and the BASIC I ported it from rounds down rather than up!

Pseudo code

Code: Select all

if (((PositionInt - 1) / 20) == round(((PositionInt - 1) / 20))) { RT = 1; }
Position = 20
0.95 == 0

Position = 21
1 == 1

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Re: Project - Mega Dracula - Help / Updates

Post by djcouchycouch » Wed Sep 02, 2015 2:31 pm

It's not clear to me how you're representing your walls. Are you working with a tilemap for level collisions?

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Project - Mega Dracula - Help / Updates

Post by matteus » Wed Sep 02, 2015 3:28 pm

Sorry I'll explain in more detail it's a dungeon crawler!

I have a [22][17] array, rows are 20 spaces long with walls found at each end

19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00

So if I was in space 19 and wanted to go WEST, I'd be moving to position + 1 and that is where this code kicks in to check!

A = (19+1)/20
B = Round((19+1)/20)

Which means A == B (1 == 1) meaning I can't move

If we did the same with place 18

A = (18+1)/20
B = RoundDown(18+1)/20

A == B (0.95 == 0) meaning I can move
Last edited by matteus on Wed Sep 02, 2015 4:49 pm, edited 3 times in total.

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Re: Project - Mega Dracula - Help / Updates

Post by tryphon » Wed Sep 02, 2015 4:04 pm

Why don't you just test if A == 0 or A == 20 ?

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Project - Mega Dracula - Help / Updates

Post by matteus » Wed Sep 02, 2015 4:15 pm

Because when you go up a row the maths changes :)

ROW 1: 39 38 37 36 35 34 33 32 31 20 29 28 27 26 25 24 23 22 21 20
ROW 0 : 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Re: Project - Mega Dracula - Help / Updates

Post by tryphon » Wed Sep 02, 2015 5:07 pm

Fast answer : modulo. I'll elaborate later.

Edit: So, what you want to know is :
does A equal to 0, 20, 40, 60, etc. ? , i.e. is A a multiple of 20 ?

The modulo of A and 20 (denoted A % 20 in Python, and IIRC in C too) is the remainder in the (euclidean, or integer) division of A by 20.
For example, 68 / 20 = 3, and the remainder is 68 - 20*3 = 8, so 68 % 20 = 8.

To state that A is a multiple of 20 is the same as stating that A % 20 = 0.

So your test should be :

Code: Select all

if (A % 20 == 0) || ((A + 1) % 20 == 0)
Or even better (because you compute only one modulo) :

Code: Select all

B = A % 20;
if ((B == 0) || (B == 19))
That said, computing a modulo is like computing a division : it's slow. Except in case the right term is a power of 2. In this case, the modulo is given by the right-most bits. For example, computing modulo 2^5 = 32 is the same as keeping the 5 right-mosts bits, so A % 32 is the same as A & 0x1F.

So you should make your rows 32 bytes long (by padding) and your test should be :

Code: Select all

B = A & 0x1F;
if ('B == 0) || (B == 19))

Post Reply