![]() |
C Gauge: Der Zeiger des VSI will nicht!!!
Hallo!
Ich bekomm es einfach nicht hin, dass der Zeiger (MAKE_NEEDLE) mir die Vertikalgeschwindigkeit anzeigt! Was ist da los?:mad: :lol: Compilen funktioniert, Hintergrund ist auch zu sehen. Aber diese blöde Nadel... Vielleicht hat einer von euch eine Antwort drauf! Viele Grüße, Hari:cool: |
Hallo!
Hab den Fehler schon gefunden! Ich hatte die plist Verlinkung vergessen!
MAKE_STATIC( vsi_background, VSI_BACKGROUND, &vsi_plist1, NULL, IMAGE_USE_ERASE, 0, {0, 0} ) ----- So bleibt nur noch zu fragen: Was heißt das folgende!!?? Der Anfang ist ja logisch, dass "val" von der Token abhängig ist. Aber was heißt das /=1.30048 Was heißt dieses "/="? FLOAT64 val=pelement->source_var.var_value.n /= 1.30048; Und noch was: Wenn ich ein EFIS mache, so dass der Schirm dunkel werden soll, so mache ich das am besten über ein MAKE_ICON, welches sich über das Gauge legt, oder? Gar so einfach wie bei XML gehts nämlich glaub ich nicht, wo man einfach ein PHP-Code:
Vieole Grüße, Harri:cool: |
FLOAT64 val=pelement->source_var.var_value.n/=1.30048; ist eine Verkürzung von:
FLOAT64 val=0; pelement->source_var.var_value.n=pelement->source_var.var_value.n/1.30048; val=pelement->source_var.var_value.n; an der Stelle hätte es auch wohl FLOAT64 val=pelement->source_var.var_value.n/1.30048; getan. Die Umrechnug ist notwendig da VERTICAL_SPEED m/sec*256 ist. Mit der fs2k2gauges.h gibt es einige Umrechnungsmacros, die das ganze etwas übersichtlicher gestalten könen. Abgesehen davon ist ein VSI häufig mit einer nichtlinearen Skala versehen, so dass sich NONLINEARITY tables empfehlen. In die kann man dann schon die Umrechnung stecken, und den Callback weglassen. Es gibt in C nicht ein so einfaches <Visible> tag, aber dafür das eine oder andere image flag für diesen Zweck (HIDE_IMAGE()/SHOW_IMAGE() HIDE_IMAGE_TREE()/SHOW_IMAGE_TREE usw.). Im sdgauxx.zip Tutorial ist das eine oder andere Beispiel. Arne Bartels |
Falls es "nur" um Nichtsichbarkeit im Fehlerfall geht, dafür sind die FAILURE_RECORDs zuständig. Dann muss man nicht mit den image_flags rumhampeln. Die sind eher was für mode selectors und dergleichen.
Arne Bartels |
Hallo!
Ich hab es jetzt über ein Icon gelöst. Allerdings gibts da noch ein bisschen Probleme:
Ich habe es zwar schon mal hinbeommen, das Gauge mitsamt dem Icon zu kompilieren, allerdings crashte dann der FS immer. Warum muss außerdem im Icon, wie auch in den anderen Makros, immer eine Token Variable angegeben werden, obwohl die Informationen eh aus dem Callback stammen! Siehe beim Icon: MASTER_BATTERY, efis_cb, Einerseits bekommt das Makro Infos aus der Token(Batterie-Token), aber auch aus dem Callback. Wieso das also? Beim Icon bedeutet als Bitmapzahl 1, dass 2 bmp vorhanden sind? Viele Grüße, Harri:cool: MODULE_VAR zustand = {MASTER_BATTERY}; . . . MAKE_ICON( efis_mas, EFIS_OFF, NULL, NULL, IMAGE_USE_ERASE | IMAGE_USE_TRANSPARENCY, 0, 0, 0, MASTER_BATTERY, efis_cb, ICON_SWITCH_TYPE_SET_CUR_ICON, 1, 0, 0 ) . . . FLOAT64 FSAPI efis_cb(PELEMENT_ICON pelement) { lookup_var(&zustand); FLOAT64 ausgabe = zustand.var_value.n; return ausgabe; } Compiler Meldung: "C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(102) : error C2143: syntax error : missing ';' before 'type' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(104) : error C2065: 'ausgabe' : undeclared identifier " |
Wenn ich mich recht erinnere, dann muss eine Variablendeklaration IMMER vor allen Rechnungen stehen (zumindestens in C, u.U. in C++ nicht unbedingt). Also
FLOAT64 FSAPI efis_cb(PELEMENT_ICON pelement) { FLOAT64 ausgabe = 0; lookup_var(&zustand); ausgabe = zustand.var_value.n; return ausgabe; } In diesem Fall tut es aber auch: FLOAT64 FSAPI efis_cb(PELEMENT_ICON pelement) { FLOAT64 ausgabe = pelement->source_var.var_value.n; return ausgabe; } oder FLOAT64 FSAPI efis_cb(PELEMENT_ICON pelement) { return pelement->source_var.var_value.n; } in dem Fall kann man auch den Callback ganz weglassen und im MAKE_ICON "NULL" anstelle von "efis_cb" verwenden. Vielleicht nicht ganz deutlich gemacht, es ist durchaus erlaubt im MAKE_ICON keine Variable (bzw. MODULE_VAR_NONE) zu setzen und dafür eine callback-Funktion zu verwenden, oder eben eine Variable im MAKE_ICON und dann NULL als callback (also keinen) wie oben, oder eine Kombination aus Variable und Callback. Arne Bartels |
Hallo!
Jetzt habe ich da ein bisschen ein eigenartiges Problem, wo ich echt nicht weiß wo anfangen!
Code siehe dazu nächsten Beitrag! Als Abschluß wollte ich noch einen String auf das Gauge draufsetzen, wo dann obenstehen soll TCAS OFF. (Zu Testzwecken wird jetzt vorerst nur mal TEST ausgegeben) Natürlich will ich eine solche Meldung nicht ganz vorne am Gauge picken haben, sondern eher hinten in der plist Reihe. Das Problem ist jetzt nur, dass alle Makros, die überhalb des String Makros stehen(also eine kleinere plist Nummer haben), nicht angezeigt werden. Somit müsste es an erster Stelle stehen, damit alle Makros funktionieren! Dass kommt für mich aber nicht in Frage, alleine schon weil ich mit dem Make_Icon alles ausblenden will, sobald die Batterie aus ist. Ich möchte Make_String als vorletztes Element im Gauge haben(also vor dem Hintergeund). Wenn man bedenkt, wie wenig Code-Zeilen man in XML für das gleiche Gauge bräuchte bräuchte...:rolleyes: :D Am beigefügten Bild habe ich den String als zweites Element "eingereiht", es funktioniert also alles bis auf das darüberstehende Make_Icon. Eigentlich müsste der EFIS Schirm schwarz sein, da die Batterie aus ist! Funktioniert aber aus den oben genannten Gründen nicht! Gibts eigentlich in C eine ähnlich praktische Variable wie (A:master general panel on, bool)??? Meiner Meinung nach eine der wichtigsten Variablen für EFIS überhaupt... Viele Grüße, Harri:cool: |
vsi_gauge.c
Hier also der code: Mit Kommentaren ausgerüstet; manchmal in deutsch, manchmal in englisch, wie's mich gerade gefreut hat!
//vsi_gauge.c //by Harald Scheidl (c)2003 char vsi_gauge_name[] = GAUGE_NAME; extern PELEMENT_HEADER vsi_list; extern MOUSERECT vsi_mouse_rect[]; GAUGE_CALLBACK vsi_update; GAUGE_HEADER_FS700(GAUGE_W, vsi_gauge_name, &vsi_list, vsi_mouse_rect, vsi_update, 0,0,0 ); MOUSE_BEGIN( vsi_mouse_rect, 0, 0, 0 ) MOUSE_END #include <stdio.h> #include "font.h" //definiert die daten zur schrift #define GAUGE_MAX_FPM 6000 #define GAUGE_MIN_FPM -6000 //--------------------------------------------------------------- //updates NEEDLE_UPDATE_CALLBACK vsi_set_cb; NEEDLE_UPDATE_CALLBACK vsi_needle_src_cb; STRING_UPDATE_CALLBACK vsi_string_cb; //--------------------------------------------------------------- //Icon macro for showing EFIS/not showing EFIS MAKE_ICON( efis_black, EFIS_OFF, NULL, NULL, IMAGE_USE_ERASE | IMAGE_USE_TRANSPARENCY, 0, 0,0, MASTER_BATTERY, NULL, ICON_SWITCH_TYPE_SET_CUR_ICON, 2, 0, 0 ) PELEMENT_HEADER vsi_plist1[] = { &efis_black.header, NULL }; //--------------------------------------------------------------- MAKE_STRING( vsi_string, NULL, &vsi_plist1, IMAGE_USE_ERASE | IMAGE_USE_BRIGHT | IMAGE_USE_TRANSPARENCY, 0, 50, 35, 60, 20, 4, MODULE_VAR_NONE, MODULE_VAR_NONE, MODULE_VAR_NONE, RGB(255,128,0), RGB(0,0,0), RGB(92,92,92), GAUGE_FONT_DEFAULT, GAUGE_WEIGHT_DEFAULT, GAUGE_CHARSET, 0, DT_CENTER | DT_VCENTER | DT_SINGLELINE, NULL, vsi_string_cb ) PELEMENT_HEADER vsi_plist2[] = { &vsi_string.header, NULL }; //--------------------------------------------------------------- FLOAT64 FSAPI vsi_string_cb(PELEMENT_STRING pelement ) { FLOAT64 val=pelement->source_var[0].var_value.n; sprintf(pelement->string, "%s", "TEST"); return val; } //Nonlinearity Table for the needle of the VSI NONLINEARITY vsi_needle_nl[] = { {{112, 64}, -6000, 0}, {{104, 85}, -4000, 0}, {{75, 105}, -2000, 0}, {{35, 105 }, -1000, 0}, {{8, 58}, 0, 0}, {{35, 11}, 1000, 0}, {{75, 12}, 2000, 0}, {{104, 31}, 4000, 0}, {{112, 51}, 6000, 0}, }; //--------------------------------------------------------------- //VSI Autopilot Setting MAKE_NEEDLE( vsi_setting, VSI_SET, &vsi_plist2, NULL, IMAGE_USE_ERASE | IMAGE_USE_TRANSPARENCY, 0, 60, 59, 0, 5, AUTOPILOT_VERTICAL_HOLD_VAR, vsi_set_cb, vsi_needle_nl, 0 ) PELEMENT_HEADER vsi_plist3[] = { &vsi_setting.header, NULL }; //--------------------------------------------------------------- FLOAT64 FSAPI vsi_set_cb ( PELEMENT_NEEDLE pelement ) { FLOAT64 val=pelement->source_var.var_value.n; if ( val > GAUGE_MAX_FPM ) val = GAUGE_MAX_FPM; if ( val < GAUGE_MIN_FPM ) val = GAUGE_MIN_FPM; return val; } //--------------------------------------------------------------- //VSI display MAKE_NEEDLE( vsi_needle, VSI_NEEDLE, &vsi_plist3, NULL, IMAGE_USE_ERASE | IMAGE_USE_TRANSPARENCY, 0, 60, 59, 0, 5, VERTICAL_SPEED, vsi_needle_src_cb, vsi_needle_nl, 0 ) PELEMENT_HEADER vsi_plist4[] = { &vsi_needle.header, NULL }; FLOAT64 FSAPI vsi_needle_src_cb ( PELEMENT_NEEDLE pelement ) { FLOAT64 val=pelement->source_var.var_value.n /= 1.30048; if ( val > GAUGE_MAX_FPM ) val = GAUGE_MAX_FPM; if ( val < GAUGE_MIN_FPM ) val = GAUGE_MIN_FPM; return val; } //---------------------------------------------------------------- MAKE_STATIC( vsi_background, VSI_BACKGROUND, &vsi_plist4, NULL, IMAGE_USE_ERASE, 0, {0, 0} ) PELEMENT_HEADER vsi_list = &vsi_background.header; //--------------------------------------------------------------- void FSAPI vsi_update (PGAUGEHDR pgauge, int service_id, UINT32 extra_data) { switch(service_id) { /* "install_routine()" */ case PANEL_SERVICE_PRE_INSTALL: break; /* "initialize_routine()" */ case PANEL_SERVICE_PRE_INITIALIZE: break; /* "update_routine()" */ case PANEL_SERVICE_PRE_UPDATE: /* "draw_routine()" */ case PANEL_SERVICE_PRE_DRAW: break; /* "kill_routine()" */ case PANEL_SERVICE_PRE_KILL: break; } } ///////////////////////////////////////////////////////////////////////////// #undef GAUGE_NAME #undef GAUGEHDR_VAR_NAME #undef GAUGE_W |
MAKE_STRINGs haben eine leicht andere Reihenfolge in den ersten Parametern (eigentlich nicht, die Resource id fehlt halt).
Du müsstest den zweiten und dritten Parameter tauschen, z.B. ... MAKE_STRING( vsi_string, &vsi_plist1, NULL, IMAGE_USE_ERASE | IMAGE_USE_BRIGHT | IMAGE_USE_TRANSPARENCY, 0, 50, 35, 60, 20, 4, MODULE_VAR_NONE, MODULE_VAR_NONE, MODULE_VAR_NONE, RGB(255,128,0), RGB(0,0,0), RGB(92,92,92), GAUGE_FONT_DEFAULT, GAUGE_WEIGHT_DEFAULT, GAUGE_CHARSET, 0, DT_CENTER | DT_VCENTER | DT_SINGLELINE, NULL, vsi_string_cb ) ... Ansonsten sieht ja alles gut aus. Ob man noch weiter optimiert ist Geschmackssache: falls Du dir Arbeit ersparen willst, lass den gauge callback weg und ändere die nonlinearity table zu: NONLINEARITY vsi_needle_nl[] = { {{112, 64}, -8000, 0}, {{112, 64}, -6000, 0}, {{104, 85}, -4000, 0}, {{75, 105}, -2000, 0}, {{35, 105 }, -1000, 0}, {{8, 58}, 0, 0}, {{35, 11}, 1000, 0}, {{75, 12}, 2000, 0}, {{104, 31}, 4000, 0}, {{112, 51}, 6000, 0}, {{112, 51}, 8000, 0} }; dann brauchst Du auch keine min-max Abfrage im needle callback mehr. Welche Zahlen (-8000,8000) da drin stehen ist wurscht, solange die ersten und die letzten beiden Einträge die selben Koordianten haben, und values außerhalb des Bereichs. Ist man nämlich außerhalb der Tabelle wird mit den Randwerten weiter interpoliert, geben die einen Differenzwinkel von 0 (gleiche Koordinaten) hat man da einen effektiven Stop eingebaut. Arne Bartels |
Hallo!
Danke Arne, der String funktioniert jetzt.
Ich habe nur mal versuchmäßig probiert, statt des normalen Textes die VS in Zahlen auszugeben. Die Berechnung habe ich dazu von der Needle herauskopiert. da ich nur ganze Zahlen haben will, lass ich mir eine int ausgeben (%d). Irgendetwas passt da aber nicht ganz. Ich hab bei einigen anderen String Gauges Source Codes gesehen, dass da im Callback drinnen steht val =! val. Das hab ich auch mal dazugetan, hat aber auch nichts genutzt. Die Zeile ergibt für mich genausoviel Sinn wie wenn ich hinschreiben würde 1 nicht gleich 1...:rolleyes: FLOAT64 FSAPI vsi_string_cb( PELEMENT_STRING pelement ) { FLOAT64 val=pelement->source_var[0].var_value.n /= 1.30048; sprintf(pelement->string, "%d", (FLOAT64)val); return val; } Ist /= eigentlich irgendeine besondere Abkürzung? Du hast sie zwar oben schon beschrieben, aber was heißt es, wenn die beiden Rechenzeichen da so dastehen??? Viele Grüße, Harri:cool: |
Also "%d" funktioniert nur bei Integer Zahlen, nicht bei floats, die als integer dargestellt werden sollen.
Eine Möglichkeit ist, vorher auf einen anderen Variablentyp umwandeln ("casten") wie Du auch schon gmacht hast, (FLOAT64)val wandelt val (vom Typ FLOAT64) in einen FLOAT64-Wert um, also überflüssig hier. Im Gegensatz dazu wandelt (SINT32) oder (int) eine Zahl in eine Integerzahl um und rundet ab, z.B.: sprintf(pelement->string, "%d", (SINT32)val); Alternativ kannst Du auch ein anderes Format verwenden, z.B.: sprintf(pelement->string, "%.0f", val); Hier wird eine Floatzahl ("%f") ohne Nachkommastelle (".0") in pelement->string geprinted, dabei wird gerundet. Die Formatstrings sind übrigens in C und XML sehr ähnlich !d! (XML) entspricht "%d" (C). Die val!=val bringt wie Du schon bemerkt hast, gar nichts. Ich weiß auch nicht wie das sich mal in die "üblichen" String-Callbacks geschlichen hat. Wie geasgt ist value/=bla eine Abkürzung für val=val/bla. Wie suich das mit einer doppelten Zuweisung in einer Zeile verhält habe ich nicht so im Kopf. So etwas vermeide ich immer, es geht ja auch in zwei Schritten. Ich gehe ziemlich stark davon aus, dass von rechts nach links abgearbeitet wird, aber sicher bin ich mir da nicht. Arne Bartels |
Hallo!
Mensch, bin ich blöd...:mad:
Ich hatte ja sicher ein paar Stunden herumgetan, bevor ich ins FXP gepostet habe. Dabei hatte ich auch schon eine deiner Rechnungen in der .c stehen gehabt. Und trotzdem hatts nicht funktioniert! Und weißt warum? Weil die Batch Datei das Gauge nicht ins Gauge Verzeichnis kopiert hat!!! Aber wie so oft hat da nicht das Programm, sondern der Benutzer schuld:D Trotzdem Danke für die Antworten, waren ja immerhin doch wieder mal ein paar Neuigkeiten für mich dabei! Achja, was könnte der Grund dafür sein, dass meine Batch Datei nicht funktioniert hat? del *.obj del *.lib del *.exp del *.res move *.gau C:\Programme\Microsoft Games\Fs2002\GAUGES Viele Grüße, Harri:cool: |
Vielleicht
move *.gau "C:\Programme\Microsoft Games\Fs2002\GAUGES" ? Wenn Du MS VC++ besitzt kann man auch direkt mit der IDE kompilieren, und nicht per makefile und Kommandozeile. Das Thema ist hier im Forum schon mal (oder öfter) durchgekaut worden. Arne Bartels |
Doch, doch, ich mache meine Gauges schon mit MS VS C++, ist ja immerhin sehr übersichtlich!
Aber im Release Ordner habe ich mir eine .bat erstellt, um nicht jedesmal die .gau ins Gauges Verzeichnis kopieren zu müssen. Viele Grüße, Harri:cool: |
Man kann nämlich gleich in das entsprechende Verzeichnis kompilieren, antstatt "Release\gaugename.gau" den vollständigen Pfad angeben.
Arne Bartels |
Hallo!
Der String, der die VS darstellt, ändert mit Überschreiten eines bestimmten VS-wertes die Farbe.(oder bessergesagt: Es wird ein anderer String verwendet, der eine andere Farbe besitzt!).
Dieser Grenzwert soll von außen her eingestellt werden können. Ich hab die beiden Werte farbe_max und farbe_min genannt. Wenn ich sie oben mit #define eingefügt habe, hat alles funktioniert. Das funktioniert alles perfekt. Aber der I/O funktioniert nicht:heul: Dabei hatte er in Turbo C++ immer so gut funktioniert. Später soll es dann so laufen, dass gecheckt wird, ob die Datei vorhanden ist und ob sie mit Inhalt gefüllt ist.(mit if(!file), wenns denn funktioniert. gibts dann außerdem noch eine Möglichkeit herauszufinden, ob die Datei leer ist? Vielleicht mit if(wert="")). Wenn die Datei leer ist, dann sollte sie mit dem Standardwert 3000 gefüllt werden. Wenn sie bereits gefüllt ist, dann wird der Wert herausgelesen und für die beiden Werte verwendet: Einmal positiv, das andere Mal negativ. mfg harri:cool: #include <stdio.h> #define datei "gauge.txt" FILE *pfile; char wert[4]; pfile=fopen("datei", "r"); fscanf("pfile","%s",wert); farbe_max=wert; farbe_min= - wert; fclose(pfile); //------------------------------------------------------ C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(36) : error C2040: 'pfile' : 'int ' differs in levels of indirection from 'struct _iobuf *' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(36) : error C2099: initializer is not a constant C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(38) : error C2143: syntax error : missing ')' before 'string' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(38) : error C2143: syntax error : missing '{' before 'string' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(38) : error C2059: syntax error : '<Unknown>' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(38) : error C2059: syntax error : ')' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(39) : warning C4047: 'initializing' : 'int ' differs in levels of indirection from 'char *' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(40) : error C2171: '-' : illegal on operands of type 'char [4]' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(40) : error C2099: initializer is not a constant C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(43) : warning C4273: 'fclose' : inconsistent dll linkage. dllexport assumed. |
Du kriegst den Hals wohl auch nicht voll<g>.
Das soll in Turbo C++ funktioniert haben? Da glaube ich nicht ganz dran, mit char[] und dann == geht nicht viel, besser die strcmp(),strlen() Funktionen verwenden. Das heißt in C++ können natürlich die (hinterhältigen) automatischen Konversionen auftauchen mit den versteckten Operatorübelagerungen die == und dergleichen auf char erlauben, aber da muss man dann CString nehmen, oder so. Zum Thema Farbe des Strings: Mit Code:
... Code:
return ... + pelement->fg_color Code:
... Code:
//lokal deklarieren und schon mal vorbesetzen Als letztes kann man natürlich nochmal auf deinen Code eingehen: Probier mal: Code:
#include <stdio.h> Arne Bartels |
Wieso ist eignetlich schon wieder das #include <stdio.h> verdunstet? Grr.
Arne Bartels |
Hallo!
Erst mal Danke für deine Antwort!
Zitat:
Der letzten Code, denn du gepostet hattest, funktioniert leider genauso wenig wie mein Code :( error C2040: 'pfile' : 'int ' differs in levels of indirection from 'struct _iobuf *' Ich habe echt eine Ahnung wie das zu bewerkstelligen ist. Denn das bisschen C, was wir bis jetzt gelernt haben, haben wir in Turbo C++ geschrieben, und da hats auch immer geklappt. Zitat:
Viele Grüße, Harri:cool: P.S.: Nach dem ich den File I/O geschafft habe, ist endgültig Schluß mit dem Gauge. Dann hab ich meinen Hals (vorerst) voll;) |
Hallo!
Ich habe mir zum Abschluss noch eine .exe im Turbo C++ gemacht, die die .txt Datei im Gauges Verzeichnis bearbeiten soll. Das Programm funktioniert sehr gut, wenn man die .txt Datei in C:\ erstellt. Wenn man allerdings einen darunterliegenden Ordner, wie z.B. "C:\\Programme\\Microsoft Games\\FS2002\\Gauges\vsi.txt" angibt, so funktioniert es leider nicht. Es wird weder eine .txt erstellt noch verändert!
Vielleicht fällt dir ja noch was ein zum File IO, vielleicht bekomm ich das Gauge ja dann heute noch fertig. Viele Grüße, Harri:cool: |
Du hast bei deinem letzten code geschrieben:
if(strlen(wert)) Da scheint durchs Forum wieder mal was verschwunden sein, oder!? if(strlen(wert) == 5) {} ...mit 5 müssten sich ja dann die 4 Zahlen darstellen lassen, oder? Viele Grüße, Harri:cool: |
das "if(strlen(wert))" entspricht "if(strlen(wert) != 0)". Das ergibt sich dadurch, dass in C/C++ 0 dem Wert false und alles andere true entspricht. Funktioniert also.
5 würden für 4 Zahlen (plus \0) ausreichen. << "C:\\Programme\\Microsoft Games\\FS2002\\Gauges\vsi.txt" >> Da fehlt noch ein Backslash vor "vsi.txt". Könnte es das sein? |
Hallo Hans!
Nein, den backslash hab ich sonst immer gehabt...hab ich nur jetzt im Forum vergessen. Kann es sein dass das Leerzeichen bei Microsoft Games Probleme bereitet???
Das Gauge selbst funktioniert aber auch noch nicht ganz einwandfrei: Leider erzeugt der code immer noch 5 Fehler und 2 Warnungen. Viele Grüße, Harri:cool: #include <stdio.h> #define datei "gauge.txt" FILE *pfile; char wert[4]; pfile=fopen(datei, "r"); //existiert Datei? if(pfile) { fscanf(pfile,"%s",wert); //steht was drin? if(strlen(wert)) { farbe_max=atoi(wert); farbe_min= - atoi(wert); } fclose(pfile); } |
Wie wäre es mit folgender Variante:
#include [stdio.h] // durch spitze Klammern ersetzen #define datei "gauge.txt" // Keine Pfadangabe = FS2002-Pfad!!! int farbe_max, farbe_min; FILE *f // Schreiben f = fopen(datei, "w"); if (f) { printf(f, "%d", farbe_max); fclose(f); // fclose() nur dann, wenn fopen() geklappt hat } // Lesen f = fopen(datei, "r"); if (f) { fscanf(f, "%d", &farbe_max); farbe_min = -farbe_max; fclose(f); // fclose() nur dann, wenn fopen() geklappt hat } Wenn Du trotzdem atoi() einsetzen willst, dann musst Du die stdlib.h noch mit includen. |
Hallo!
Danke für den Code, aber es ist immer noch der gleiche erste Error:
Da muss der Fehler doch irgendwo anders liegen, denn sowohl mein Code(der in Turbo C++ gut funktioniert), Arne's Code und dein Code fangen mit dem gleichen Error an...:rolleyes: error C2040: 'f' : 'int ' differs in levels of indirection from 'struct _iobuf *' mfg harri:cool: |
Könntest Du eventuell zu dem Error auch die Zeilennummern im Code angeben? Damit wir wissen zu welcher Zeile welcher Error gehört.
Arne Bartels |
Voila'
Von MSDN-zum error:
Compiler Error C2040 'operator' : 'identifier1' differs in levels of indirection from 'identifier2' An expression involving the specified operator had inconsistent levels of indirection. If both operands are of arithmetic type or if both are not (such as array or pointer), then they are used without change. If one operand is arithmetic, but the other is not, the arithmetic operator is converted to the type of the other operator. //------------------------------------------------------- C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(44) : error C2040: 'f' : 'int ' differs in levels of indirection from 'struct _iobuf *' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(44) : error C2099: initializer is not a constant C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(45) : error C2059: syntax error : 'if' C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(215) : warning C4554: '&' : check operator precedence for possible error; use parentheses to clarify precedence C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(221) : warning C4554: '&' : check operator precedence for possible error; use parentheses to clarify precedence C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(233) : warning C4554: '|' : check operator precedence for possible error; use parentheses to clarify precedence C:\Programme\Microsoft Visual Studio\MyProjects\vs3\subgauges\vsi_gauge.c(283) : warning C4554: '|' : check operator precedence for possible error; use parentheses to clarify precedence Error executing cl.exe. vs3.gau - 3 error(s), 4 warning(s) |
Ne ich meinte im Code dazu auch irgendwie die Zeilennummern anbringen, es reicht ja eine zu Beginn dann kann man weiterzählen.
Übrigens Hans' code funktioniert im Wesentlichen: Code:
#include <stdio.h> |
ich hab dir die zeile 34 angezeichnet!
direkt unter //schreiben #include <stdio.h> #define datei "gauge.txt" // Keine Pfadangabe = FS2002-Pfad!!! int farbe_max=3000, farbe_min=-3000; FILE *f; // Schreiben 34.)f = fopen(datei, "w"); if (f) { fprintf(f, "%d", farbe_max); fclose(f); // fclose() nur dann, wenn fopen() geklappt hat } // Lesen f = fopen(datei, "r"); if (f) { fscanf(f, "%d", &farbe_max); farbe_min = -farbe_max; fclose(f); // fclose() nur dann, wenn fopen() geklappt hat } |
Ist das #include oder #include <stdio.h> ?
Arne Bartels |
natürlich
PHP-Code:
harri |
Was benutzt Du? .c oder .cpp?
|
.c
An dem liegts ja nicht. Es hat ja alles funktioniert, bis ich jetzt mit dem File IO angefangen habe. Natürlich könnte ich es jetzt einfach rauslöschen und hätte dann ein Gauge das funktioniert. Aber wo wäre denn dann der Reiz des Gauges programmieren? mfg harri :cool: |
Probier bitte mal aus, direkt FILE *f = fopen(...); zu schreiben. Aber denk dran, dass in C *alle* Variablen-Deklarationen ganz oben in der Funktion sein müssen. Eine Deklaration mittendrin geht nur bei C++.
|
#define datei "gauge.txt" // Keine Pfadangabe = FS2002-Pfad!!!
int farbe_max=3000, farbe_min=-3000; FILE *f = fopen(datei, "r"); if(f){ fscanf(f, "%d", &farbe_max); farbe_min = -farbe_max; fclose(f); // fclose() nur dann, wenn fopen() geklappt hat } Ich hab deinen Code jetzt auf Einlesen reduziert. Aber immer noch regt der sich auf, "initializer is not a constant" bei der FILE *f Linie! Außerdem passt das if dem Compiler auch nicht ganz. Angäblich hat's da einen Syntax Error. Dieser Fehler hängt aber wahrscheinlich vom ersten Fehler ab, schätze ich mal... Deklariert und initialisiert(tolle Wörter:zzz: ) wird beim File IO doch eh richtig. Und gerade hab ich nochmal ausprobiert: Wenn ich das File IO weg"kommentatiere", und mir die farbe_max und farbe_min oben definiere, funktioniert das Gauge so wie es sein sollte. Aber wie schon oben gesagt:"Wo bleibt denn da der Reiz???:D" Viele Grüße, Harri:cool: |
Irgendwie ist das ja höchst seltsam. Bei mir läuft der Code sauber, keine Fehler. File I/O ist ja keine große Kunst. Irgendwie ist Dir die FILE Definition abhanden gekommen, würde ich fast vermuten. Du kannst mal testweise "FILE" durch "struct _iobuf" ersetzen.
Ist FILE irgendwie anders besetzt? Welche include holt der sich eigentlich (Rechtsklick auf FILE, "go to definition" o.ä. )? U.U. ist FILE ein FILEHANDLE, d.h. ein Integerwert. Arne Bartels |
No browse information available.
Do you want to rebuilt the project to get information...oder irgendwie so ähnlich. OK, hab's regebuiltet, und jetzt hat der in die stdio.h mir einen Eintrag gezeigt: typedef struct _iobuf FILE; #define _FILE_DEFINED #endif Ich hoffe nur, dass der zuerst auch schon da war und nicht jetzt irgendetwas da hineingeschrieben wurde durch MSVS. Compilen geht immer noch nicht! Das Ersetzen von FILE durch den einen Ausdruck da hat auch nichts geholfen. mfg harri:cool: |
Hallo!
So, hier noch die Kopie der subgauge.c Datei.
Ich muss jetzt aufhören, schließlich geht's morgen endlich ans Geldverdienen fürn Sommer! Viele Grüße, Harri:cool: |
Ich habe mal deinen Code (e_vsi.zip) genommen und in der Nähe von Zeile 36 den fraglichen Teil eingeworfen. Jede Menge Fehler und so ziemlich die beschriebenen. Der Punkt ist, dass Du Dein File IO Code innerhalb einer Funktion durchführen musst. Z.B. in der needle callback oder in der gauge callback.
Arne Bartels P.S. dein Upload und mein Beitrag haben sich überschnitten, ich schau mir das nachher an. |
So zum Beispiel.
#define datei "gauge.txt" // Keine Pfadangabe = FS2002-Pfad!!! int farbe_max=3000, farbe_min=-3000; global weit oben deklariert. Und das eigentliche Lesen in der gauge callback zu einem Zeitpunkt (service_id), der nur einmal aufgerufen wird, da sind einige möglich. Das sollte es gewesen sein, ich muss schließlich Morgen auch richtig arbeiten. Arne Bartels |
Alle Zeitangaben in WEZ +2. Es ist jetzt 12:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag