TUI programmieren [C]

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

TUI programmieren [C]

Beitrag von oDOSseus »

Hallo zusammen, ich bins wieder!

diesmal ein neues Thema. Da ich im Moment viel mit Graphik programmiere, kam mir in den Sinn, eine TUI zu programmieren (Textual User Interface).
Ich habe mir schon ne ASCII-Graphik-Library gebaut, die zwischen 80x50 und 80x25 mode hin-und-her schaltet, Attribute des Text verändern kann, den System-Cursor bewgegen kann und natürlich Reihen, Rechecke und Rahmen zeichnen kann. Also eigendlich alles was man braucht.

Nun meine Frage:
gibt es Tutorials zu TUIs? Ich würde gerne noch einen mouse-support einbauen und ich denke mir, es wäre einfach, wenn ich mir das an Beispielen abgucken kann. Wenn das schon jemand von euch vorher mal in C programmiert hat, wäre ich auch sehr an sourcecodes interessiert.
Was mich am meisten interessiert:
Wie kann ich eine Menüleiste mit Drop-Down-Menüs (wie in edit.com) bauen? Wenn ich das weiß, krieg ich den Rest auch hin.

vielen Dank im Voraus.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Hallo zusammen, ich bins wieder!

diesmal ein neues Thema. Da ich im Moment viel mit Graphik programmiere, kam mir in den Sinn, eine TUI zu programmieren (Textual User Interface).
Ich habe mir schon ne ASCII-Graphik-Library gebaut, die zwischen 80x50 und 80x25 mode hin-und-her schaltet, Attribute des Text verändern kann, den System-Cursor bewgegen kann und natürlich Reihen, Rechecke und Rahmen zeichnen kann. Also eigendlich alles was man braucht.

Nun meine Frage:
gibt es Tutorials zu TUIs? Ich würde gerne noch einen mouse-support einbauen und ich denke mir, es wäre einfach, wenn ich mir das an Beispielen abgucken kann. Wenn das schon jemand von euch vorher mal in C programmiert hat, wäre ich auch sehr an sourcecodes interessiert.
Was mich am meisten interessiert:
Wie kann ich eine Menüleiste mit Drop-Down-Menüs (wie in edit.com) bauen? Wenn ich das weiß, krieg ich den Rest auch hin.

vielen Dank im Voraus.
Ein Drop-Down-Menü könnte z.B. damit gebaut werden:

Code: Alles auswählen

AUF     DB "├───────────┤"             ; Klapp-Box-Ober-Teil
Auflen = ($-AUF)                       ; Anzahl der Spalten der Klapp-Box
ZELLE   DB "│           │"             ; Klapp-Box-Mittel-Teil
ZU      DB "└───────────┘"             ; Klapp-Box-Unter-Teil
;--------------------------------------
NEBO    DB "└───────────┐"             ; Neben-Klapp-Box-Ober-Teil
NEBU    DB "┌───────────┘"             ; Neben-Klapp-Box-Unter-Teil
Eine Mouseabfrage kann über einen Mousetreiber erfolgen und die benutzen gewöhnlich dazu Interrupt 33h. Damit werden Mouse über COM-Port und PS2 abgefragt.
Z.B benutzt die Cutemouse um eine PS2-Mouse abzufragen einen Mousehandler der über Interrupt 15h AX=0C207h die Daten bekommt.
Ich benutze die selber Methode um meine PS2-Mouse abzufragen die mit einem Adapter an einen der USB-Anschlüsse verbunden ist.
Im Bios meines Mainboards musste ich dafür USB-Legacy auf enable stellen. Mein modernes Mainboard besitzt weder einen PS2-Mouseanschluss noch Com-Ports.

Im Groben wird der PS2-Handler wie folgt initialisiert :

Code: Alles auswählen

checkPS2:
int 11h			; get equipment list
test    al, 3
jz  noPS2		; jump if PS/2-Mouse not indicated
mov	bh,3
mov     ax, 0C205h
int 15h		        ; initialize mouse, bh=datasize
jc noPS2
mov	bh,3
mov     ax, 0C203h
int 15h		        ; set mouse resolution bh
jc noPS2
mov     ax, cs
mov     es, ax
mov	bx, OFFSET PS2dummy
mov     ax, 0C207h
int 15h		        ; mouse, es:bx=ptr to handler
jc noPS2
xor     bx, bx
mov     es, bx		; mouse, es:bx=ptr to handler
mov     ax, 0C207h
int 15h
ret

noPS2:
stc
ret

PS2dummy:
retf
;---------------------------------------------------------
enablePS2:
call disablePS2
mov    ax, cs
mov    es, ax
mov    bx, OFFSET IRQhandler
mov    ax, 0C207h	; es:bx=ptr to handler
int 15h
mov	bh,1		; set mouse on
mov     ax, 0C200h
int 15h
ret
;-------------------------------
disablePS2:
xor	bx, bx		; set mouse off
mov	ax, 0C200h
int 15h
xor     bx, bx
mov     es, bx
mov     ax, 0C207h	; es:bx=ptr to handler
int 15h
ret
;---------------------------------------------------------------------------
IRQhandler:
		assume	ds:nothing,es:nothing
cld
push    ds
push    es
pusha
mov     ax, cs
mov     ds, ax
mov	bp,sp
mov	al,[bp+24+6]	; buttons
mov	bl,al
shl	al,3		; CF=Y sign bit
sbb	ch,ch		; signed extension 9->16 bit
cbw			; extend X sign bit
mov	al,[bp+24+4]	; AX=X movement
mov	cl,[bp+24+2]	; CX=Y movement
xchg	bx,ax
neg	cx              ; reverse Y movement
popa
pop	es
pop     ds
retf
Im Handler fehlen noch die Speicherstellen wo die ermittelten Daten abgelegt werden und es fehlt die Hauptroutine die daraus die Bewegung des Mouscoursors vornimmt und die Ereingniosse auslöst wenn eine Mousetaste gedrückt wird.

Dirk
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Dein Mouse-Handler sieht sehr interessant aus. Werde ich mir nochmal ganz genau angucken.
Aber einen Mouse-Handler schrob (sry. Meine grammatik ist von "die ärzte" geprägt xD) ich schonmal in C, jedoch für eine 320x200 VGA darstellung). War aber weniger ein Handler als vielmehr eine stetige Abfrage.
Er sah ungefähr so aus:

Code: Alles auswählen

word x;
word y;
word isPressed;

/* folgende Schleife endet, wenn die Maus in der unteren rechten bildschirm-Ecke angelangt ist */
while(x<319 || x<199){
  setPixel(x,y,COLOR_WHITE);
  /* Maus Bewegung abfragen */
  asm{
    MOV   AX, 0Bh
    INT   33h
    ADD   x, CX
    ADD   y, DX    
  }
  /* get Button */
  asm{
    MOV   AX, 0006h
    MOV   BX, 0000h
    INT   33h
    MOV   isPressed, BX    
  }
  if(isPressed){
    vPutS("Ist gedrueckt!!!");
  }
}
aber deiner sieht irgendwie intelligenter aus xD. Auch wenn meiner nur spielerei war und noch nicht umgebaut für text-mode

Naja und meine Frage bezog sich eigendlich grade auf diesen Handler. Wie mache ich es zum Beispiel am klügsten, abzufragen, ob er auf einen Menüpunkt oder vllt. auf einen etwaigen Button geklickt hat? Mir fallen dazu zwei Methoden ein, die beide nicht sehr klug aussehen:
a) Ich gehe jedes einzelnes Element durch und gucke ob der Klick drauf liegt
b) Ich melde jedes Element mit einer eigenen ID in einer Array an, die genau 80x25 (oder halt 80x50) bytes groß ist und wenn der klick auf so einer ID liegt, dann mach ich, was zu machen ist.

Was würdest du vorschlagen?
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: TUI programmieren [C]

Beitrag von DOSferatu »

Ich habe beides schon gemacht - und beides funktioniert.
Es kommt eben darauf an, wie die Oberfläche gestaltet ist. Wenn man nur wenige Elemente maximal hat (also ein paar hundert), machts dem Computer in der Regel nicht einmal etwas aus, da dauernd die Koordinaten zu testen...
Aber das mit den IDs im "Feld" hab ich auch schon gemacht. Bei dieser Variante sollte man sich nur überlegen, ob man dann auch sich überlappende Elemente ("Fenster") zuläßt und was man in diesem Fall tut (wie man die IDs speichert).
Ein Beispiel: In meinem IRC Client (auch Textmodes, aber mit 24 verschiedenen Auflösungen und modifizierter Farbpalette und Zeichensatz) lasse ich maximal 16 Fenster zu und lege ein virtelles Array of Word an, pro Zeichenposition ein Word. Und jedes der 16 Bits zeigt an, ob dort gerade das Fenster mit der entsprechenden Nummer ist (1) oder nicht (0). (Fenster "loggen" sich ein und aus, sortieren sich intern um, wenn man die Überlappung ändert - also ein Fenster "vorholt", etc...) Natürlich habe ich trotzdem noch eine "Element-Verwaltung" für die Fenster... Ich könnte da noch weiter ausholen, mit dem ganzen Kram, den ich sonst noch zu diesen Themen gemacht habe - aber das führt jetzt zu weit.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Dein Mouse-Handler sieht sehr interessant aus. Werde ich mir nochmal ganz genau angucken.
Aber einen Mouse-Handler schrob (sry. Meine grammatik ist von "die ärzte" geprägt xD) ich schonmal in C, jedoch für eine 320x200 VGA darstellung). War aber weniger ein Handler als vielmehr eine stetige Abfrage.
Er sah ungefähr so aus:

Code: Alles auswählen

word x;
word y;
word isPressed;

/* folgende Schleife endet, wenn die Maus in der unteren rechten bildschirm-Ecke angelangt ist */
while(x<319 || x<199){
  setPixel(x,y,COLOR_WHITE);
  /* Maus Bewegung abfragen */
  asm{
    MOV   AX, 0Bh
    INT   33h
    ADD   x, CX
    ADD   y, DX    
  }
  /* get Button */
  asm{
    MOV   AX, 0006h
    MOV   BX, 0000h
    INT   33h
    MOV   isPressed, BX    
  }
  if(isPressed){
    vPutS("Ist gedrueckt!!!");
  }
}
aber deiner sieht irgendwie intelligenter aus xD. Auch wenn meiner nur spielerei war und noch nicht umgebaut für text-mode

Naja und meine Frage bezog sich eigendlich grade auf diesen Handler. Wie mache ich es zum Beispiel am klügsten, abzufragen, ob er auf einen Menüpunkt oder vllt. auf einen etwaigen Button geklickt hat? Mir fallen dazu zwei Methoden ein, die beide nicht sehr klug aussehen:
a) Ich gehe jedes einzelnes Element durch und gucke ob der Klick drauf liegt
b) Ich melde jedes Element mit einer eigenen ID in einer Array an, die genau 80x25 (oder halt 80x50) bytes groß ist und wenn der klick auf so einer ID liegt, dann mach ich, was zu machen ist.

Was würdest du vorschlagen?
Ah prima, deine Routine nutzt einen Mousetreiber.

Ich habe die Randbereiche jedes Klickfeldes in eine Tabelle eingetragen. Dann überprüfe ich ob die aktuelle Mouseposition innerhalb des ersten Klickfeld sich befindet und erhöhe danach den Zeiger innerhalb der Tabelle um das nächte Klickfeld abzufragen und so weiter.
Eine ID benutze ich nicht, da die Nummer des Klickfeldes durch die Tabellenposition bestimmt wird.

Konstante ganz oben im Sourcecode (damit die genaue Position der Klickfelder schnell eingetragen werden kann beim Ermitteln der genauen Position):

Code: Alles auswählen

    Ber1Xmin     =   
    Ber1Xmax     = 
    Ber1Ymin     =  
    Ber1Ymax     = 

    Ber2Xmin     = 
    Ber2Xmax     =
    Ber2Ymin     = 
    Ber2Ymax     =
Tabelle im Datenbereich (ich verwende hier Datenwords weil ich den Videomode 800x600x32 benutze):

Code: Alles auswählen

MBEGR   DW Ber1Xmin, Ber1Xmax, Ber1Ymin, Ber1Ymax ; Tabelle der Mouse-Bereiche
	     DW Ber2Xmin, Ber2Xmax, Ber2Ymin, Ber2Ymax
Die Positionsabfrage:

Code: Alles auswählen

	  mov      si, OFFSET MBEGR  ; Zeiger auf Tabelle
TAIN:  cmp      cx, [si]        ; Mouse-Bereichs-Abfrage
	  jb  TAIR2
	  cmp      cx, [si+2]
	  ja  TAIR2
	  cmp      dx, [si+4]
	  jb  TAIR2
	  cmp      dx, [si+6]
	  ja  TAIR2
	  sub      si, OFFSET MBEGR    ; Tabellen-Nummer bestimmen
	  shr      si, 3               ; geteilt durch 8 Byte je Klickfeld-Bereich(Tabelle)

          ......
.... Abfrage ob geklickt wurde....
          ......

TAIR2:  lea      si, [si+8]         ; auf nächsten Tabellen-Eintrag erhöhen(macht das selbe wie "add si, 8" nur schneller)
	     cmp      si, OFFSET MBGend  ;  letzter Tabellen-Eintrag?
	     jb  TAIN                    ; sonst weiter mit dem nächsten Tabelleintrag abfragen
Wenn der Mouszeiger über ein Klickfeld bewegt wird, dann wird dieses Feld bei mir färblich hervorgehoben, um zu zeigen das man dort klicken kann. Wenn nur einige Klickfelder sehr dicht zusammen liegen, dann braucht man ggf. eine gesonderte Abfrage um das letzte Klickfeld abzuleuchten, für den Fall das wenn der Mousezeiger erst in das eine Klickfeld und dann unmittelbar in das nächste Klickfeld bewegt wird, ohne das er ausserhalb eines Klickfeldes bewegt wird.

Ich schalte den Mousezeiger selber nicht an und benutze einen eigenen Mousezeiger mit beliebigen Ausmassen (im Truecolor-Videomode). So muss ich vor dem Plazieren des Mouszeigers den Hintergrund retten und wenn die Mouse bewegt wird, dann wird der vorherige Bereich restauriert.

Hier noch mal ein PS2-Mousehandler der die Positionen+Mouseklick im Datenbereich rettet:

Code: Alles auswählen

PS2IRQ:   push    ds
          pusha
          mov     ax, DATEN
          mov     ds, ax
          mov     bp, sp
          mov     bx, [bp+22+6]   ; status byte(buttons,Sign,Overflow)
          mov     cx, [bp+22+4]   ; X movement
          mov     dx, [bp+22+2]   ; Y movement
          mov     ax, [XACK]
          test    bx, 10h         ; Sign X  Mouse goes right
          jz short MOGOR
          neg     cl
          sub     ax, cx
          cmp     ax, [BHMIN]     ; (Hmin) Mouse-Zeiger zu weit links ?
          jb  short IY0
;          test   bx, 40h          ; Overflow X
;          jz  short IY0
IX1:      jmp short IX2           ; X schreiben
;---------
MOGOR:    add     ax, cx
          cmp     ax, [BHMAX]     ; (Hmax) Mouse-Zeiger zu weit rechts ?
          ja  short IY0
;          test   bx, 40h          ; Overflow X
;          jz  short IY0
IX2:      mov     [XACK], ax
;---------------------------------
IY0:      mov     ax, [YACK]
          test    bx, 20h         ; Sign Y Mouse goes down
          jnz short MOGOU
          sub     ax, dx
          cmp     ax, [BVMIN]     ; (Vmin) Mouse-Zeiger zu hoch ?
          jb  short IIZ
;          test    bx, 80h         ; Overflow Y
;          jz  short IIZ
IY1:      jmp short IY2           ; Y schreiben
;---------
MOGOU:    neg     dl
          add     ax, dx
          cmp     ax, [BVMAX]     ; (Vmax)  Mouse-Zeiger zu tief ?
          ja  short IIZ
;          test     bx, 80h        ; Overflow Y
;          jz  short IIZ
IY2:      mov     [YACK], ax
;---------------------------------
IIZ:      and     bx, 3           ; only buttons, remove Sign + Overflow
          mov     [TACK], bx
;---------
          popa
          pop     ds
PS2TEST:  retf
Und hier der Anfang und das Ende der Routine die den Mousezeiger setzt:

Code: Alles auswählen

GETMPOS:  cli
          xor      ecx, ecx
          xor      edx, edx
          mov      cx, [XACK]          ; cx = X-Positon   holen
          mov      dx, [YACK]          ; dx = Y-Position  holen
          mov      bx, [TACK]          ; bx = Mouse-Taste holen
	  lea      ecx, [ecx*4]             ; ecx * 4 (für 32Bit true-color-Position)
	  lea      edx, [edx*4]
	  mov      [RETCLIC], bx
	  cmp      ecx, DWORD PTR[MX]
	  jnz short MSOI
	  cmp      edx, DWORD PTR[MY]
	  jz  NOMOUT                   ; wenn dieselbe Pos., dann nicht setzen
         .....
...Mousezeiger wird gesetzt.....
         .....
	  mov      bx, [RETCLIC]
 	  mov      ecx, DWORD PTR[MX]
	  mov      edx, DWORD PTR[MY]
NOMOUT:   sti
	  ret
Dirk
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Alles sehr hilfreich =)

Ich habe mich nun dazu entschieden es in C folgendermaßen zu machen:
ich mache einen globalen Pointer. In diesem Pointer werden die Adressen aller Elemente eingetragen.
Ein Element kann alles sein: Button, Label, Text-feld etc.
jedes Element hat mehrere Variablen:
  • Sichbarkeit (ja oder nein)
    Position
    Ausmaße
    Aufschrift
    Attribut (das heißt Vorder- und Hintergrundfarben)
    Typ (Button, Label, etc.)
    eine ID, mit der es zu erkennen ist (der Sinn wird später erklärt)
    Einen Zeiger auf eine Funktion, die aufgerufen wird, sobald auf das element geklickt wird
Mit der ID verhält es sich ähnlich wie mit einem Handler. Man kann so jedes bestimme Element in dem "Elementen-Zeiger" ganz genau erkennen und verarbeiten. Sonst müsste man ja immer das ganze Struct ( die ansammlung an Variablen) mitgeben.

dann gibt es eine Hauptfunktion draw() oder ähnliches die alle elemente durchgeht. Jedes das Sichtbar ist, wird gezeichnet. alle anderen nicht.

Um zu erkennen wo geklickt wurde, werden ebenfalls alle sichtbaren elemente durchgeguckt.

Klingt das intelligent?
Ich habe sowas noch nie gemacht.
elianda
DOS-Übermensch
Beiträge: 1150
Registriert: Mi 31. Jan 2007, 19:04
Wohnort: Halle
Kontaktdaten:

Re: TUI programmieren [C]

Beitrag von elianda »

Es fehlt noch die Elementpriorität bzw. der 'Tiefenwert'. Wenn du mehrere überlappende Elemente hast, willst du ja wissen welchen ganz vorne ist.
Entsprechend kannst Du bei der Entscheidung auf welchen Element die Maus gerade ist, diese Elemente durchlaufen und dann wechselwirkt die Maus nur mit dem vordersten.
Zum zeichnen musst Du die ja eh sortieren...

Du kannst dir noch überlegen ob Du das nochmals pro Fenster machst oder global. Vermutlich wäre aber pro Fenster schneller, da man dann recht einfach Fenster inkl. aller beinhaltenden Elemente nach vorne / hinten holen kann.
Diverse Retro-Computer vorhanden.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Oh ja!
Den Tiefenwert habe ich vergessen.
...Und schon ist er drin xD


Nur die frage ist, wie mach ich das?
Soll ich vor jedem Zeichnen die Liste sortieren, oder beim Einfügen von jedem neuen Element, verändern von Elementen und löschen von Elementen?

Ich nehme an, es wäre am klügsten, die Liste vor dem Zeichnen zu sortieren.
Aber wie sortier ich diese Liste? ich google mal, und melde mich erneut, wenn es nicht klappt.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Sooo
ich habs versucht.

aber Turbo C wirft mir ganze Hochhäuser in den Weg.
ich habe ne funktion "sortElementsByDepth" geschrieben.
Diese benutzt qSort.
Aber wenn ich sie aufrufe, werden nicht die elemente sortiert, sondern der Quelltext von TUI.ASM (eine automatisch erstellte Datei von Turbo C) ausgegeben.
Kompiliere ich mit open Watcom, dann klappts, aber die elemente werden auch nicht vernünftig kompiliert xD.
Hast du schonmal versucht ne Array zu sortieren, die zeiger auf Structs enthält?
Und wie kann ich Turbo Cs fehler beheben?
---------EDIT----------
habe Fehler behoben, indem ich für 80186 kompiliere statt für 8086.
Sort-Frage bleibt
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Sooo
ich habs versucht.

aber Turbo C wirft mir ganze Hochhäuser in den Weg.
ich habe ne funktion "sortElementsByDepth" geschrieben.
Diese benutzt qSort.
Aber wenn ich sie aufrufe, werden nicht die elemente sortiert, sondern der Quelltext von TUI.ASM (eine automatisch erstellte Datei von Turbo C) ausgegeben.
Kompiliere ich mit open Watcom, dann klappts, aber die elemente werden auch nicht vernünftig kompiliert xD.
Hast du schonmal versucht ne Array zu sortieren, die zeiger auf Structs enthält?
Und wie kann ich Turbo Cs fehler beheben?
---------EDIT----------
habe Fehler behoben, indem ich für 80186 kompiliere statt für 8086.
Sort-Frage bleibt
Das hört sich ja krass an.

Ich habe es noch nicht wirklich verstanden, wofür soll überaupt sortiert werden und geht es nicht auch ohne Sortierung?

Dirk
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Ich sortiere die Liste, damit das Element mit der größten Tiefe auch ganz oben ist. so werden sie passend über einander gemalt.
Aber wie soll ich das machen
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Ich sortiere die Liste, damit das Element mit der größten Tiefe auch ganz oben ist. so werden sie passend über einander gemalt.
Aber wie soll ich das machen
Auch so im Falle das die sich überlappen, soll das vordere Element auch zu aller letzt gemalt werden damit es vorne ist usw..
Das würde auch ohne Sortieren gehen, wenn jedes Element ein Flag dafür hat das die Reihenfolge bestimmt. Dann schaut man alle Flags durch und sucht den untersten und malt das Element, dann den nächsten suchen und malen usw..
255 Elemente sind schnell durchsucht, so das ein Umsortieren nicht unbedingt nötig ist.

Sonst habe ich hier noch ein Quicksort in Assembler, aber das ist nicht von mir sondern von Jan Bruns wahrscheionlich aus der Newsgroup "de.comp.lang.assembler", ich poste hier mal seinen Beitrag:

Code: Alles auswählen

Hallo,

weil mich folgender quicksort doch viel länger als erwartet beschäftigt hat:

ESI : Adresse des ersten (signed int32) Element der Liste
EDI : Adresse del letzten Elements
Sortierung erfolgt aufsteigend
Diese qsort-Variante läuft auch mit vorstortierten Listen schnell.


@start:         mov ecx,edi
                shr ecx,1
                mov eax,esi
                shr eax,1
                add ecx,eax
                and ecx,$FFFFFFFC
                mov ecx,dword ptr[ecx]
                push edi
                push esi
                sub esi,4
                add edi,4
@loop:          add esi,4
                cmp dword ptr[ESI],ecx
                jl @loop
@loop2:         sub edi,4
                cmp ecx,dword ptr[EDI]
                jl @loop2
                cmp edi,esi
                jc @skip
                mov eax, dword ptr[esi]
                mov ebx, dword ptr[edi]
                mov dword ptr[edi],eax
                mov dword ptr[esi],ebx
                jmp @loop
@skip:          pop eax
                cmp edi,eax
                jbe @m1
                push esi
                mov esi,eax
                call @start
                pop esi
@m1:            pop edi
                cmp edi,esi
                jnbe @start



Gruss

Jan Bruns
Dirk
Zuletzt geändert von freecrac am Mi 18. Aug 2010, 14:15, insgesamt 1-mal geändert.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Deinen Ansatz mit dem durchsuchen, welches am weitesten unten ist, und dieses dann malen, werde ich mir merken und ihn verwenden.

Doch ich halte es für intelligenter die Liste zu sortieren, denn genau das tut deine methode ja auch. Sie sortiert, merkt sich das Ergebnis aber nicht. Und sie sortiert bei jedem Zeichnen, auch wenn die Tiefe gar nicht verändert wurde. Somit wäre es ja fixer, nur zu bestimmten momenten zu sortieren.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

HAbs doch so gemacht wie du meintest. Klappt super.
Ich melde mich bei neueun problemen.

Kurzer Zwischenstand:
Alles klappt gut.
Habe schon erste Buttons gebaut und ihnen funktionen mitgegeben die auch ausgelöst wurden.
Melde mich wieder
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:HAbs doch so gemacht wie du meintest. Klappt super.
Ich melde mich bei neueun problemen.

Kurzer Zwischenstand:
Alles klappt gut.
Habe schon erste Buttons gebaut und ihnen funktionen mitgegeben die auch ausgelöst wurden.
Melde mich wieder
Prima.

Dirk
Antworten