Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

18.12.2011, 15:32

Inlinefunktionserweiterung zerstört Funktion vom Ccde

Ich bin gerade dabei mal ein kleines Spiel von Grund auf mit der SDL zu erstellen, dabei habe ich jetzt bei einem kleinen Test feststellen müssen, dass mein Code zwar in der Debug-Version funktioniert, bei der Release jedoch Anzeigefehler passieren. Entweder es erscheint gar keine Anzeige (Wenn ich die Ausgabe der Positionen nicht auskommentiere) oder die Oberste Reihe Blöcke wird nicht angezeigt. (Siehe anhängende Bilder)

Nach einigem Probieren habe ich herausgefunden, dass die Inlinefunktionserweiterung schuld an dem ganzen Schlamassel ist, sobald die eingeschaltet ist, passieren die Fehler.

Hier mal der Render-Kern, irgend wo hier scheint es Probleme zu geben:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
EMG_Error CSurface::blitSurface(SDL_Surface * src, sPosition pos){
    
    SDL_Rect src_pos, dst_pos;
    dst_pos.x = static_cast<Sint16> ( static_cast<float> (m_pScreen->w) * pos.x);
    dst_pos.y = static_cast<Sint16> ( static_cast<float> (m_pScreen->h) * pos.y);

    src_pos.x = 0;
    src_pos.y = 0;

    //std::cout << "Renderpos x:" << static_cast<Sint16> ( m_pScreen->w * pos.x) << " y:" << static_cast<Sint16> ( m_pScreen->h * pos.y) << std::endl;

    if (SDL_BlitSurface(src, &src_pos, m_pScreen, &dst_pos) == 0){
        return E_OK;
    }else{
        return E_SDLERROR;
    }
}


Technischen Infos:
VS 2010 Prof
SDL 1.2.14 mit SDL_gfx-2.0.23

Hat jemand eine Idee, ob es sich hierbei um einen Bug im MS-Compiler handelt, oder ob mein Code "fehlerhaft" ist.
»ChrisvA« hat folgende Bilder angehängt:
  • Korrekt.JPG
  • fehler.JPG

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

18.12.2011, 18:23

Wenn es im Debugmodus aber nicht im Releasemodus funktioniert, ist es meist ein Zeichen dafür, dass Variablen nicht korrekt initialisiert wurden, denn diese werden im Debugmodus meist auf 0 gesetzt, was aber im Releasemodus nicht der Fall ist. Allerdings sehe ich an dem Abschnitt nichts was dafür sprechen würde.
Sieht übrigens verdächtig nach atomic bomberman aus.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

3

19.12.2011, 07:53

Also das Variablen nicht initialisiert sind, kann ich mir fast nicht vorstellen, da ja alle anderen Grafik auch gerendert werden, obwohl die in der selben Schleife erstellt werden.
Außerdem geht es ja auch in der Releaseversion, nur eben nicht wenn ich die Inlinefunktionserweiterung aktiviert habe.

Der Tipp mit dem Bomberman stimmt übrigens.

Was aber in der Tat ein wenig verwunderlich ist, ist dass es gerade nur die Steine erwischt, die pos.y = 0.0f haben.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

4

19.12.2011, 08:54

Zeige mal die Renderschleife. Es könnte natürlich auch ein Compilerbug sein. Aber dass ausgerechnet Du auf einen neuen Bug im Compiler stoßen solltest, und noch dazu in einem Teil, der von Millionen von Leuten intensiv genutzt wird (Inlining), ist statistisch doch recht unwahrscheinlich. Wahrscheinlicher ist, dass Du einen Bug im Code hat. Und bei Debug<->Release-Unterschieden sind es nunmal meist die uninitialisierten Variablen.

Nebenbei: Du kannst auch für Release-Builds einfache Debug-Info anschalten und damit grundlegend durch den Code steppen. Es ist aber schwer, in diesem Modus auseinander zu halten, was wirklich Bug ist und was der Debugger Dir nur wegen Optimierungen nicht mehr anzeigen kann.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

5

19.12.2011, 22:20

Das ganze ist im Prinzip meine Renderschleife. Hier aber mal der komplette Weg der Steine:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
void CGame::addBreakableStones(){

    //Zufalsgenerator init
    time_t timer;
    
    time (&timer);

    srand(static_cast<unsigned int> (timer));
    

    CGOBreakableStone* pBStone;

    int numFieldCols = (m_GameParams.numStonesX * 2) + 1;
    int numFieldRows = (m_GameParams.numStonesY * 2) + 1;

    // Abstand zwischen 2 Reihen
    float dxCols = 1.0f / static_cast<float>(numFieldCols);
    float dyRows = 1.0f / static_cast<float>(numFieldRows);

    // Steinreihen setzen
    for(int i = 0; i < numFieldCols; ++i){

        for (int j = 0; j < numFieldRows; ++j){

            float xpos = i * dxCols;
            float ypos = static_cast<float> (j) * dyRows;

            assert((xpos >= 0.0) && (xpos <=  m_framework.getSurface()->getW()));
            assert((ypos >= 0.0) && (ypos <= m_framework.getSurface()->getH()));

            // Zufall vergleichen, FELDMITTE!! pruefen, ob schon besetzt
            if ( ((rand() % 100) < m_GameParams.percentBreakableStones )&&
                !checkOccupied( (xpos + (dxCols / 2.0f)), (ypos + (dyRows / 2.0f) ))){
                //std::cout << "Unbesetzt: i=" << i << " j=" << j  << " xpos:" << xpos << " ypos:" << ypos << std::endl;

                pBStone = new CGOBreakableStone(m_framework.getSurface());

                pBStone->setPos(xpos , ypos);
        
                pBStone->setSize(dxCols, dyRows);

                m_lpObjects.push_back(pBStone);

            }

        }
    }
    
}

void CGame::render(){

    // Bildschirm uebermalen
    //m_framework.getSurface()->clear();

    std::deque<CGameObject*>::iterator it;

    it = m_lpObjects.begin();

    // Komplette Spielobjekliste durchgehen und alles rendern
    while (it != m_lpObjects.end()){
        (*it)->render();
        ++it;
    }

}

void CGOStone::render(){
    //std::cout << "Renderpos x:" << m_dimensionRect.pos.x << " y:" << m_dimensionRect.pos.y << std::endl;
    m_pSurface->showTexture(m_pStoneTexture, m_dimensionRect.pos);
}

EMG_Error CSurface::showTexture(CTexture* texture, sPosition pos){
    return blitSurface(texture->getSurface(), pos);
}

EMG_Error CSurface::blitSurface(SDL_Surface * src, sPosition pos){
    
    SDL_Rect src_pos, dst_pos;
    dst_pos.x = static_cast<Sint16> ( static_cast<float> (m_pScreen->w) * pos.x);
    dst_pos.y = static_cast<Sint16> ( static_cast<float> (m_pScreen->h) * pos.y);

    src_pos.x = 0;
    src_pos.y = 0;

    //std::cout << "Renderpos x:" << static_cast<Sint16> ( m_pScreen->w * pos.x) << " y:" << static_cast<Sint16> ( m_pScreen->h * pos.y) << std::endl;

    if (SDL_BlitSurface(src, &src_pos, m_pScreen, &dst_pos) == 0){
        return E_OK;
    }else{
        return E_SDLERROR;
    }
}


Noch kurz zu meinen Klassen Vererbungen:
CGameObject -> CGOStone -> CBreakableStone

Positionen sind bis zur letzten als Float gespeichert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
// Allg. Position, gemessen von der linken oberen Ecke
/*
    ___________________________
    |(0.0, 0.0)             |
    |                       |
    |                       |
    |               (1.0, 1.0)|
    __________________________
*/

Werbeanzeige