# Das nächste Problem: Funktion tut anscheinend rein gar nichts...

• Hi(gh)!

Im Moment klappt mit Programmieren wirklich rein gar nichts... werde ich dement? Oder liegt es an der ausgesucht scheißigen Umgebung (lärmiges Unterschicht-Wohnklo ohne Klimaanlage in lärmigem Unterschicht-Viertel, fast ununterbrochenes Kindergeschrei, Bassgewummer, Auspuffgebrüll und ständiger Martinshorn-Terror)?

Konkret:

Die Funktion c64fill():

``````bool c64fill(vector<vector<pixel> >& img, vector<vector<pixel> >& c64img, string md, int fcolor)
{
unsigned short leftcols, upperrows, rightcols, lowerrows, fullw, fullh;
unsigned short h = img.size();
unsigned short w = img[0].size();
int a, b;
pixel p;

cout << "F" << uuml << "llfunktion wird aufgerufen!" << endl;

cout << "Gew" << auml << "hlte F" << uuml << "llfarbe: " << palette[fcolor].red << " " << palette[fcolor].green << palette[fcolor].blue << endl;

cout << "Breite des Originalbildes: " << w << endl;
cout << "H" << ouml << "he des Originalbildes: " << h << endl;

if (md == "blocks")
{
fullw = 40;
fullh = 25;
}
if (md == "multicolor")
{
fullw = 160;
fullh = 200;
}

// cout << "fullw = " << fullw << "\tfullh = " << fullh << endl;

c64img.resize(fullh);
// c64img[0].resize(fullw);

if (w < fullw)
{
leftcols = (fullw-w)/2;
rightcols = fullw-w-leftcols;
}
else
{
leftcols = 0;
rightcols = 0;
}

if (h < fullh)
{
upperrows = (fullh-h)/2;
lowerrows = fullh-h-upperrows;
}
else
{
upperrows = 0;
lowerrows = 0;
}

if ( h == fullh && w == fullw)
return false;

// cout << "leftcols = " << leftcols << "\trightcols = " << rightcols << endl;

if (rightcols > 0)
{
a=0;
while (a<fullh)
{
b=0;
while (b<fullw)
{
if (b < leftcols || b > w+leftcols-1)
{
p.set_red((unsigned char)palette[fcolor].red);
p.set_green((unsigned char)palette[fcolor].green);
p.set_blue((unsigned char)palette[fcolor].blue);

c64img[a].push_back(p);
}
else
{
p.set_red((unsigned char)img[a].at(b-leftcols).get_red());
p.set_green((unsigned char)img[a].at(b-leftcols).get_green());
p.set_blue((unsigned char)img[a].at(b-leftcols).get_blue());

c64img[a].push_back(p);

// cout << "b - leftcols = " << b-leftcols << endl;
}
b++;
}
a++;
}
}

if (lowerrows > 0)
{
a=0;
while (a<fullh)
{
b=0;
while (b<fullw)
{
if (a < upperrows || a > h+upperrows-1)
{
p.set_red((unsigned char)palette[fcolor].red);
p.set_green((unsigned char)palette[fcolor].green);
p.set_blue((unsigned char)palette[fcolor].blue);

c64img[a].push_back(p);
}
else
{
p.set_red((unsigned char)img[a-upperrows].at(b).get_red());
p.set_green((unsigned char)img[a-upperrows].at(b).get_green());
p.set_blue((unsigned char)img[a-upperrows].at(b).get_blue());

c64img[a].push_back(p);
}
b++;
}
a++;
}

}
return true;
}
``````

soll sowohl im "blocks"-Modus (40 x 25 Pixel) als auch im Multicolor-Modus (160 x 200 Pixel) bei im Original nicht bildschirmfüllenden Bildern fehlende Zeilen oder Spalten mit einer frei aus der C 64-Palette wählbaren Füllfarbe auffüllen. palette ist ein globaler Vektor aus rgb-Strukturen (struct rgb ist in meiner Klassendatei definiert) und wurde schon beim vorangegangenen Aufruf der Funktion c64() mit den entsprechenden Farbwerten belegt.

Bis gestern funktionierte diese Funktion noch - mittlerweile lässt sie die Bilder unverändert, d. h. es werden keine Spalten oder Zeilen aufgefüllt. Ich bin drauf und dran, die Programmiererei mit C++ endgültig dranzugeben, ich kann es ja anscheinend schlichtweg nicht! Schon gar nicht, wenn ich dauernd durch irgendwelchen Alltagsschlamassel (wie das halt eben normal ist in der Unterschicht) abgelenkt werde... Alltag und Programmieren, das beißt sich!

Bis bald im Khyberspace!

• ​Es klappt und klappt und klappt und klappt und klappt nicht... jeder Versuch, Fehler zu korrigieren, produziert nur neue Fehler. Ich will nicht mehr, ich bin kurz davor, alles zu vernichten, was mit yip zu tun hat... dann gibt es eben keine Retro-Videos im C64-Look!

ICH KANN KEIN C++! ICH BIN ZU DUMM DAZU!!!

• Wenn du nichts an der Funktion nichts geändert hast (und sie bis gestern noch funktionierte), dann liegt der Fehler nicht im gezeigten Code.

• Oder liegt es an der ausgesucht scheißigen Umgebung (lärmiges Unterschicht-Wohnklo ohne Klimaanlage in lärmigem Unterschicht-Viertel, fast ununterbrochenes Kindergeschrei, Bassgewummer, Auspuffgebrüll und ständiger Martinshorn-Terror)?

Wahrscheinlich

• Schon in der Ausgabe greifst du offenbar auf irgendwelche Globalen Variablen zurück, die wir nicht kennen.

Am einfachsten für uns ist es, wenn du uns ein kompilierbares minimal Beispiel lieferst, mit dem wir das Problem reproduzieren können. Ich weiß, dass kann viel Aufwand sein, aber häufig fällt man dabei selbst über das Problem.

P.S. Wenn es ein Hobby/Lernprojekt ist, könnte es tatsächlich Sinnvoll sein, nochmal mit einer klaren objektorientierten Kapselung neu anzufangen.

• jeder Versuch, Fehler zu korrigieren, produziert nur neue Fehler.

Dann überleg dir das Prinzip der Funktion bevor du codest - am Schreibtisch (oder im Bett oder auf dem Klo oder ...).

ICH KANN KEIN C++

Das hat mit C++ nichts zu tun.

`cout << "F" << uuml << "llfunktion wird aufgerufen!"`

Wenn du dich mit solchen Kleinigjeiten, wie richtige Umlaute für eine Debugausgabe aufhälts, verrennst du dich auch woanders.
ob da ein ue oder ü steht ist Pillepalle.

Und wenn, es unbedingt sein muss, dann konfiguriere den Compiler richtig.

• Schon in der Ausgabe greifst du offenbar auf irgendwelche Globalen Variablen zurück, die wir nicht kennen.

Am einfachsten für uns ist es, wenn du uns ein kompilierbares minimal Beispiel lieferst, mit dem wir das Problem reproduzieren können. Ich weiß, dass kann viel Aufwand sein, aber häufig fällt man dabei selbst über das Problem.

P.S. Wenn es ein Hobby/Lernprojekt ist, könnte es tatsächlich Sinnvoll sein, nochmal mit einer klaren objektorientierten Kapselung neu anzufangen.

Hier ist der aktuelle Stand, mit KIassendefinition, Sprach-Konfigurationsdatei und zwei Beispielbildern für den blocks- und den multicolor-Modus:
http://www.rock-o-data.de/yip_20180715.tar.gz

Ich bin mit meinem Latein am Ende...

• Die Idee hinter einem minimal Beispiel ist eigentlich nicht, einfach alles zu nehmen, sondern den Code soweit zu reduzieren, dass man wenige Zeilen in einen Compiler jagen kann und den Fehler sieht.

Aber wenn ich die Woche Zeit habe, schau ich mal rein, ich kann aber nix versprechen, da ich recht viel zu tun habe.

• jeder Versuch, Fehler zu korrigieren, produziert nur neue Fehler.

Dann überleg dir das Prinzip der Funktion bevor du codest - am Schreibtisch (oder im Bett oder auf dem Klo oder ...).

ICH KANN KEIN C++

Das hat mit C++ nichts zu tun.

`cout << "F" << uuml << "llfunktion wird aufgerufen!"`

Wenn du dich mit solchen Kleinigjeiten, wie richtige Umlaute für eine Debugausgabe aufhälts, verrennst du dich auch woanders.
ob da ein ue oder ü steht ist Pillepalle.

Und wenn, es unbedingt sein muss, dann konfiguriere den Compiler richtig.

Wahrscheinlich liegt es bei mir auch daran, dass ich einfach NULL ROUTINE im Programmieren habe - ich beschäftige mich nur alle paar Monate mal sporadisch mit einem Programm! Kein Wunder, dass ich 20 Jahre nach meiner ersten Begegnung mit C++ immer noch ein absoluter Anfänger bin - Programmieren, das ist eine Berufung, die man tagtäglich leben muss! Und dazu fehlt es bei mir an Disziplin... oder anders ausgedrückt: ich will immer auf zehn Hochzeiten gleichzeitig tanzen, will in allem gut, wenn nicht gar super sein, ob das jetzt Fahrradfernreisen, Amateurastronomie, Synthesizermusik oder eben C++ ist! Leider sind dafür meine Tage, ist mein ganzes Leben zu kurz...

• Was wünscht Du Dir, was man Dir sagen soll?

• @lemon03 sagte in Das nächste Problem: Funktion tut anscheinend rein gar nichts...:

Was wünscht Du Dir, was man Dir sagen soll?

Ich würde gerne verbindlich erfahren, ob ich mich in den schätzungsweise 30 Jahren, die mir noch bleiben, auf Fahrradfernreisen, Amateurastronomie, Synthesizermusik oder C++ konzentrieren soll - alles gleichzeitig schaffe ich nicht! Ich will endlich so etwas wie einen Platz im Leben finden, nachdem bis jetzt alles nur konfuses Chaos war...

• Amateurastronomie würde ich schätzen. Bis Du da die Grundlagen drinne hast, kannst Du lesen, lesen, lesen bis der Arzt kommt Und musst niemand was beweisen, weil jeder besser gewesen ist. Weißt schon, man steht auf Schultern von Riesen. Eine gute Grundlage fürs Alterseisen.

Aber ist leider unverbindlich.

• Um da Du scheinbar Interesse an Naturwissenschaften hast, will ich für Dich eine kleine Reihe vorstellen.

Von Aristoteles zur Stringtheorie

Prolog und Nebra • Aristoteles ⯈ Stringtheorie (1) | Josef M. Gaßner

• @lemon03 sagte in Das nächste Problem: Funktion tut anscheinend rein gar nichts...:

Amateurastronomie würde ich schätzen. Bis Du da die Grundlagen drinne hast, kannst Du lesen, lesen, lesen bis der Arzt kommt Und musst niemand was beweisen, weil jeder besser gewesen ist. Weißt schon, man steht auf Schultern von Riesen. Eine gute Grundlage fürs Alterseisen.

Aber ist leider unverbindlich.

Amateurastronomie hat leider den Nachteil, dass es ein sehr teures Hobby ist, erst recht, wenn man auch noch durchs Teleskop fotografieren will... mit der Ausrüstung, die ich mir gerade so leisten kann (4,5-Zoll-Reflektor auf wackeliger EQ-2-Montierung, gebrauchte Canon PowerShot S40 für die RAW-Fotos, dazu eine Digiklemme für die Kamera) ist hier in der Großstadt außer Mondfotos kaum etwas möglich...

Mitunter wünsche ich mir geradezu, dass mir durch äußeren Zwang (Diktatur, Krieg, allgemeiner zivilisatorischer Zusammenbruch) ein bestimmter Lebensweg auferlegt wird, dem ich mich dann nicht mehr entziehen kann - all die Milliarden Optionen, die man hierzulande heutzutage hat (und bei näherer Betrachtung dann eben doch nicht hat, weil materielle Mittel und/oder Persönlichkeitsstruktur nicht dazu passen), treiben mich in die Verzweiflung!

• Amateurastronomie hat leider den Nachteil, dass es ein sehr teures Hobby ist, erst recht, wenn man auch noch durchs Teleskop fotografieren will...

Naja, am Anfang steht immer noch Information sammeln, sonst weißt Du gar nicht, wie Du Deine wertvolle Ausrüstung ausrichten sollst. Und das ist so gut wie kostenlos.

Aber mal unter uns Schnaps-Psychologen. Solange Du kein ernsthaftes Interesse für eine Sache entdeckst, wirst Du immer vor Dich her wurschteln. Du musst Dich mal aufraffen und was in die Hand nehmen. Klar, das Leben kann Kacke sein. Kenne ich. Aber das sagst Du seit dreißig Jahren, scheinbar ohne Erfolg. Das zu ändern geht nicht von heute auf morgen. Du musst Dich bewegen oder wirst sterben. Entscheide Dich für etwas. Nicht für alles, sondern für etwas.

• @yadgar sagte in [Das nächste Problem: Funktion tut anscheinend rein gar nichts.

Mitunter wünsche ich mir geradezu, dass mir durch äußeren Zwang (Diktatur, Krieg, allgemeiner zivilisatorischer Zusammenbruch) ein bestimmter Lebensweg auferlegt wird, dem ich mich dann nicht mehr entziehen kann - all die Milliarden Optionen, die man hierzulande heutzutage hat (und bei näherer Betrachtung dann eben doch nicht hat, weil materielle Mittel und/oder Persönlichkeitsstruktur nicht dazu passen), treiben mich in die Verzweiflung!

Das hätteste gerne, was? Wegen Deinem Unvermögen sollen alle bluten? Tschuldigung, aber das setzt Deine Person in eine Wichtigkeit, die Du im selben Atemzug negierst.

Das ist doch alles ein Joke hier auf den ich reingefallen bin!?

• ``````#include <iostream>
#include <cmath>
#include <vector>
#include <cassert>
#include <algorithm>

using namespace std;

class pixel
{
public:
pixel() : r{}, g{}, b{} {}
pixel(short red, short green, short blue) : r{ red }, g{ green }, b{ blue } {}
void set_red(short red) { r = red; }
void set_green(short green) { g = green; }
void set_blue(short blue) { b = blue; }
short get_red() { return r; }
short get_green() { return g; }
short get_blue() { return b; }
void invert() { r = 255 - r; g = 255 - g; b = 255 - b; }
void rgb2grey() { r = g = b = static_cast<short>(round(getvalue())); }
void rgb2grey(float, float, float);
float getvalue() { return r * 0.299f + g * 0.587f + b * 0.114f; }
private:
short r;
short g;
short b;
};

void pixel::rgb2grey(float redw, float greenw, float bluew)
{
float sumw = redw + greenw + bluew;
float red = r * (redw / sumw);
float green = g * (greenw / sumw);
float blue = b * (bluew / sumw);
float sum = red + green + blue;
r = g = b = static_cast<short>(round(sum));
}

std::vector<pixel> palette;

bool c64fill(vector<vector<pixel>> const & img, vector<vector<pixel>> & c64img, string const & md, std::size_t fcolor)
{
assert(fcolor < palette.size());

if (md != "blocks" && md != "multicolor")
return false;

std::size_t target_width{ md == "blocks" ? 40u : 160u };
std::size_t target_height{ md == "blocks" ? 25u : 200u };

std::copy(img.begin(), img.end(), c64img.begin());

c64img.resize(target_height);
for (auto & col : c64img)
col.resize(target_width);

auto ori_width{ img[0].size() };
auto ori_height{ img.size() };

for (std::size_t y{ 0 }; y < ori_height; ++y)
std::fill(c64img[y].begin() + ori_width, c64img[y].end(), palette[fcolor]);

for (std::size_t y{ ori_height }; y < target_height; ++y)
std::fill(c64img[y].begin(), c64img[y].end(), palette[fcolor]);

return true;
}
``````

• @yadgar Hey, ich habe mir deinen Code mal angeschaut.
Bei meinen kleinen Versuchen, ist zumindest irgendwas passiert. Um da genauer was zu sagen, musst du mal ein Beispiel Aufruf angeben, mit dem man deinen Fehler reproduzieren kann.

Du hast irgendwo geschrieben, dass du vor 20 Jahren deine ersten Erfahrungen mit C++ gemacht hast, aber nicht wirklich dran geblieben bist.
Wenn C++ die Sprache deine Wahl ist, rate ich dir dringend zu einem aktuellen Anfänger-Lehrbuch. Einfach mal auf Null stellen und vo Grund auf ordentlich anfancgen. Es gab hier mal irgendwo eine Liste, dazu. Ein gerne empfohlenes ist der "C++ Primer".
Außerdem möchte ich dir dringend raten, dir was zum Thema Softwaredesign anzulesen. Dein Code ist für dritte so kaum bis nicht les - oder wartbar. Alleine deine main() hat 1425 Zeilen Code und ist eine reine Kaskade aus ifdef und ifs.
Deine Gesamte Algorithmik ist in freien Funktionen die auf Vektoren von Vektoren arbeiten (die meistens Image heißt). Was spricht zum Beispiel gegen eine Image Klasse, in die man sowas wunderbar kapseln könnte.
Du solltest dein Code auch dringend auf mehr Dateien aufteilen. Für jede Klasse eine Header und eine Source Datei ist ein guter Richtwert.

Wenn man eine Software Multilingual haben möchte, gibt es bessere Wege als alle Strings doppelt im Source Code aufzunehmen. "Internationalization" ist das Stichwort. GUI Frameworks wie QT und wxWidgets bieten da fertige Funktionalitäten für an, ansonsten möchte ich dich da z.B. auf GNU gettext verweisen.
Aber mein Tipp wäre, erstmal alles einsprachig zu halten und erstmal um den Rest kümmern.

• @yadgar Ach, das Originalbild soll zentriert im neuen und von der Füllfarbe umrandet sein?

``````std::vector<pixel> palette;

bool c64fill(vector<vector<pixel>> const & img, vector<vector<pixel>> & c64img, string const & md, std::size_t fcolor)
{
assert(fcolor < palette.size());

if (md != "blocks" && md != "multicolor")
return false;

std::size_t target_width{ md == "blocks" ? 40u : 160u };
std::size_t target_height{ md == "blocks" ? 25u : 200u };

c64img.resize(target_height);
for (auto & col : c64img)
col.resize(target_width);

auto ori_width{ img[0].size() };
auto ori_height{ img.size() };

auto x_ori_start{ (target_width - ori_width) / 2 };
auto y_ori_start{ (target_height - ori_height) / 2 };

for (std::size_t y{}; y < y_ori_start; ++y)
std::fill(c64img[y].begin(), c64img[y].end(), palette[fcolor]);

for (std::size_t y{ y_ori_start }; y < y_ori_start + ori_height; ++y) {
std::fill(c64img[y].begin(), c64img[y].begin() + x_ori_start, palette[fcolor]);
std::copy(img[y - y_ori_start].begin(), img[y - y_ori_start].end(), c64img[y].begin() + x_ori_start);
std::fill(c64img[y].begin() + x_ori_start + ori_width, c64img[y].end(), palette[fcolor]);
}

for (std::size_t y{ y_ori_start + ori_height }; y < target_height; ++y)
std::fill(c64img[y].begin(), c64img[y].end(), palette[fcolor]);

return true;
}
``````

• ich beschäftige mich nur alle paar Monate mal sporadisch mit einem Programm!

ach so. Naja. Bis nächsten Monat dann ...