Absturz beim Ändern der Werte in 2D Feld



  • Ich habe mal wieder ein Problem... 😞
    Das Gesamte Prog ist zwar Winapi, ich hab aber hier in einer Funktion, die ANSI ist - oder es zumindest halbwegs sein sollte.

    Ich habe einen Typ T_KACHEL

    typedef unsigned char T_KACHEL[2500];
    struct S_ARCHEAD
    {
      int  SizeOfKachel;
      int  XKCount, YKCount;
      char WaterMark;
    };
    

    Bitte später nicht dran stören, dass die Größe festgelegt ist. Ich werd's irgendwann noch ändern..

    So, nun habe ich einen Pointer erstellt.

    T_KACHEL *Felddaten
    

    Dieses wird initialisiert mit einer dieser beiden Funktionen:

    ´
    T_KACHEL *NewTerrain  (S_ARCHEAD *H)
    {
      T_KACHEL *T;
    
      T=(T_KACHEL*) malloc ( H->SizeOfKachel * H->XKCount * H->YKCount);
      return (T_KACHEL*) memset (T, H->WaterMark, H->SizeOfKachel * H->XKCount * H->YKCount);
    }
    
    int       SaveTerrain (char *Dateiname, T_KACHEL *T, S_ARCHEAD *H)
    {
      FILE *F;
    
      F = fopen (Dateiname, "wb");
         if (F == NULL) return -1;
         fwrite(H, sizeof(S_ARCHEAD),1,F);
         fwrite(T, H->SizeOfKachel,  H->XKCount * H->YKCount, F);
      fclose(F);
      return 0;
    }
    
    T_KACHEL *LoadTerrain (char *Dateiname, S_ARCHEAD *Header)
    {
      FILE *F;
      T_KACHEL *T;
      S_ARCHEAD H;
      F = fopen (Dateiname, "rb");
         if (F == NULL) return NULL;
         fread(&H, sizeof(S_ARCHEAD), 1, F);
         T = NewTerrain(&H);
         fread(T, H.SizeOfKachel, H.XKCount * H.YKCount, F);
         memcpy (Header, &H, sizeof (S_ARCHEAD));
      fclose(F);
    
      return T;
    }
    

    Also entweder neue Datei oder eine laden..
    Der Knackpunkt ist nun diese Funktion, wenn ich den Wert eines einzelnen Feldes ändern will.. XPosA und YPosA geben jeweils vor dem Komma die Kachel an (das Kachelfeld ist virtuel 2-Dimensional) und hinter dem Komma steht die Koordinate auf der einzelnen Kachel. Die Berechnung ist eigentlich auch in Ordnung, aber eben beim Ändern des Wertes in K geht irgendwas schief :(.

    PSize ist eine Pinselgröße. Val ist der Wert um den geändert werden soll und Tool ist dann später das Werkzeug.

    void FillKachel(T_KACHEL *K, S_ARCHEAD S, float XPosA, float YPosA, 
                    int PSize, int Val, int Tool)
    {
     int Xa, Xb, Xc, 
         Ya, Yb, Yc;
     int Kachel, Koord;
     float XPos = XPosA; 
     float YPos = YPosA;
    
        XPos *= S.SizeOfKachel; 
        YPos *= S.SizeOfKachel;
    
        Xa = (int)(XPos - PSize); 
        Xb = (int)(XPos + PSize); // Eckpunkte errechnen
        Ya = (int)(YPos - PSize); 
        Yb = (int)(YPos + PSize); // Eckpunkte errechnen
    
        if (Xa < 0) Xa = 0;     
        if (Xb > S.XKCount * S.SizeOfKachel) Xb = S.XKCount * S.SizeOfKachel; 
        if (Ya < 0) Ya = 0;     
        if (Yb > S.YKCount * S.SizeOfKachel) Yb = S.YKCount * S.SizeOfKachel; 
                                                         // evtl. normalisieren
    
        for (Yc = Ya; Yc <= Yb; Yc++)
            for (Xc = Xa; Xc <= Xb; Xc++)
            {
               Kachel = (Yc/50) * S.XKCount +  (Xc/50);   // Kachel errechnen
               Koord  = (Yc%50) * S.SizeOfKachel + (Xc%50);  // Koordinate auf Kachel
    //           switch (Typ)
    //           {
    //             case 1:  // Berg 
                  if ( (K[Kachel][Koord]+Val ) <= 255)
                        K[Kachel][Koord]+=Val; 
                  else      
                        K[Kachel][Koord]= 255; 
    //              break;      
    /*             case 2:  // Ebene
    
                  if ( K[Kachel][Koord]> WBorder)
                        if ( (K[Kachel][Koord]-Val) >= WBorder )
                           K[Kachel][Koord]-=Val;
                        else    
                           K[Kachel][Koord]=WBorder;
                  else      
                        if ( (K[Kachel][Koord]+Val) <= WBorder )
                           K[Kachel][Koord]+=Val;
                        else    
                           K[Kachel][Koord]=WBorder;
                  break;      
                 case 3: // Wasser 
                  if ( (K[Kachel][Koord]- (Val/10) ) >= 0)
                        K[Kachel][Koord]-=(Val/10); 
                  else      
                        K[Kachel][Koord]= 0; 
                  break;      
               }   
    */        }  
    }
    

    initialisieren kann man zum Testen mal mit den Werten

    S_ARCHEAD H;
    T_KACHEL *Felddaten;
     H.SizeOfKachel = 50; // Seitenlänge 50
     H.XKCount = 5;       // Kachelzahl X
     H.YKCount = 5;       // Kachelzahl Y
     H.WaterMark = 5;     // Wasserlevel
    
    Felddaten = NewTerrain ( &H);
    
    FillKachel (Felddaten, H, 1.23, 2.34, 30, 10, 1);
    

    [ Dieser Beitrag wurde am 26.11.2002 um 21:57 Uhr von DocJunioR editiert. ]


Anmelden zum Antworten