]> Shamusworld >> Repos - apple2/commitdiff
Set eol-style to native to keep things sane.
authorShamus Hammons <jlhamm@acm.org>
Tue, 29 May 2007 05:00:36 +0000 (05:00 +0000)
committerShamus Hammons <jlhamm@acm.org>
Tue, 29 May 2007 05:00:36 +0000 (05:00 +0000)
16 files changed:
Makefile
apple2.cfg
src/apple2.cpp
src/ay8910.cpp
src/gui/button.cpp
src/gui/button.h
src/gui/draggablewindow.cpp
src/gui/element.cpp
src/gui/element.h
src/gui/gui.cpp
src/gui/gui.h
src/gui/guimisc.cpp
src/gui/guimisc.h
src/gui/textedit.cpp
src/gui/window.cpp
src/v65c02.cpp

index e94b4a61eed517abc5adf25ffeeacdeda8a231fc..24e7642c3d6ecce7f946850ebb308515ad60a40a 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -54,9 +54,9 @@ TARGET     = apple2
 #              -ffast-math -fomit-frame-pointer `sdl-config --cflags` -fprofile-arcs -ftest-coverage
 # No optimization for profiling with gprof...
 CFLAGS   = -MMD -Wall -Wno-switch -D$(SYSTYPE) \
-               -ffast-math `sdl-config --cflags` -pg -g
+               -ffast-math `sdl-config --cflags` -pg
 CPPFLAGS = -MMD -Wall -Wno-switch -Wno-non-virtual-dtor -D$(SYSTYPE) \
-               -ffast-math `sdl-config --cflags` -pg -g
+               -ffast-math `sdl-config --cflags` -pg
 #              -fomit-frame-pointer `sdl-config --cflags` -g
 #              -fomit-frame-pointer `sdl-config --cflags` -DLOG_UNMAPPED_MEMORY_ACCESSES
 
@@ -73,7 +73,6 @@ INCS = -I. -I./src -I/usr/local/include -I/usr/include
 OBJS = \
        obj/button.o          \
        obj/draggablewindow.o \
-       obj/draggablewindow2.o \
        obj/element.o         \
        obj/gui.o             \
        obj/guimisc.o         \
index ece7b9ce5bb89ebb796a6a12c3e126ee8d16eeba..197823747a18a0f634765c4a8585e32657aafd69 100755 (executable)
@@ -39,7 +39,7 @@ autoSaveState = 1
 # Yes, keys???
 #floppyImage1 = ./disks/MidnightMagic_etc.dsk
 # ???
-#floppyImage1 = ./disks/battle_chess_1.dsk
+floppyImage1 = ./disks/battle_chess_1.dsk
 # Yes 
 #floppyImage1 = ./disks/MoebiusI-1.dsk
 # Yes, but crashes on the attract mode
@@ -54,8 +54,8 @@ autoSaveState = 1
 #floppyImage1 = ./disks/ultima_ii-1.dsk
 #floppyImage2 = ./disks/ultima_ii-2.dsk
 # Yes, autoloads!
-floppyImage1 = ./disks/u2prog-patched.dsk
-floppyImage2 = ./disks/u2player-jlh.dsk
+#floppyImage1 = ./disks/u2prog-patched.dsk
+#floppyImage2 = ./disks/u2player-jlh.dsk
 
 
 # OpenGL options: 1 - use OpenGL rendering, 0 - use old style rendering
index dbdb619287e5d4de84e1b13fc405616c8bbeadb1..7621a2e679edfefe1fb8393a5f59ebacf3b23678 100755 (executable)
@@ -51,7 +51,7 @@
 
 #include "gui/gui.h"
 #include "gui/window.h"
-#include "gui/draggablewindow2.h"
+#include "gui/draggablewindow.h"
 #include "gui/textedit.h"
 
 using namespace std;
@@ -98,7 +98,7 @@ static void BlinkTimer(void);
 
 Element * TestWindow(void)
 {
-       Element * win = new DraggableWindow2(10, 10, 128, 128);
+       Element * win = new DraggableWindow(10, 10, 128, 128);
 //     ((DraggableWindow *)win)->AddElement(new TextEdit(4, 16, 92, 0, "u2prog.dsk", win));
 
        return win;
@@ -316,28 +316,28 @@ if (addr >= 0xC080 && addr <= 0xC08F)
 A-9 (Mockingboard)
 APPENDIX F Assembly Language Program Listings
 
-                       1       *PRIMARY ROUTINES
-                       2       *FOR SLOT 4
-                       3       *
-                       4                       ORG     $9000
-                       5       *                               ;ADDRESSES
-                                                                               FOR FIRST
-                                                                               6522
-                       6       ORB             EQU     $C400           ;PORT B
-                       7       ORA             EQU     $C401           ;PORT A
-                       8       DDRB            EQU     $C402           ;DATA DIRECTION
-                                                                               REGISTER (A)
-                       9       DDRA            EQU     $C403           ;DATA DIRECTION
-                                                                               REGISTER (B)
-                       10      *                                       ;ADDRESSES
-                                                                               FOR SECOND
-                                                                               6522
-                       11      ORB2            EQU     $C480           ;PORT B
-                       12      ORA2            EQU     $C481           ;PORT A
-                       13      DDRB2   EQU     $C482           ;DATA DIRECTION
-                                                                               REGISTER (B)
-                       14      DDRA2   EQU     $C483           ;DATA DIRECTION
-                                                                               REGISTER (A)
+1      *PRIMARY ROUTINES
+2      *FOR SLOT 4
+3      *
+4                      ORG     $9000
+5      *                               ;ADDRESSES
+                                       FOR FIRST
+                                       6522
+6      ORB             EQU     $C400           ;PORT B
+7      ORA             EQU     $C401           ;PORT A
+8      DDRB            EQU     $C402           ;DATA DIRECTION
+                                                       REGISTER (A)
+9      DDRA            EQU     $C403           ;DATA DIRECTION
+                                                       REGISTER (B)
+10     *                                       ;ADDRESSES
+                                                       FOR SECOND
+                                                       6522
+11     ORB2            EQU     $C480           ;PORT B
+12     ORA2            EQU     $C481           ;PORT A
+13     DDRB2   EQU     $C482           ;DATA DIRECTION
+                                                       REGISTER (B)
+14     DDRA2   EQU     $C483           ;DATA DIRECTION
+                                                       REGISTER (A)
 */
 void WrMem(uint16 addr, uint8 b)
 {
index 4f8da2feef95c092a3119ef402b5ac22aba0d2ae..56c03d121cb5d481c432fec46d96a6ee8ed4bba6 100755 (executable)
 //    freely available as well.
 // 
 
-// JLH: Commented out MAME specific crap
+// JLH: Removed MAME specific crap
 
 #include <string.h>                                                            // for memset()
 #include "ay8910.h"
 
-#define MAX_OUTPUT 0x7FFF
+///////////////////////////////////////////////////////////
+// typedefs & dummy funcs to allow MAME code to compile:
+//
+//typedef UINT8 (*mem_read_handler)(UINT32);
+//typedef void (*mem_write_handler)(UINT32, UINT8);
+//
+//static void logerror(char* psz, ...)
+//{
+//}
+//
+//static unsigned short activecpu_get_pc()
+//{
+//     return 0;
+//}
+//
+//
+///////////////////////////////////////////////////////////
+
+#define MAX_OUTPUT 0x7fff
 
 // See AY8910_set_clock() for definition of STEP
 #define STEP 0x8000
 
+//This is not used at all...
+//static int num = 0, ym_num = 0;
+
 struct AY8910
 {
        int Channel;
@@ -83,70 +104,60 @@ struct AY8910
 static struct AY8910 AYPSG[MAX_8910];          /* array of PSG's */
 
 
+
 void _AYWriteReg(int n, int r, int v)
 {
        struct AY8910 *PSG = &AYPSG[n];
        int old;
 
+
        PSG->Regs[r] = v;
 
-       /* A note about the period of tones, noise and envelope: for speed reasons, *
-        * we count down from the period to 0, but careful studies of the chip      * 
-        * output prove that it instead counts up from 0 until the counter becomes  * 
-        * greater or equal to the period. This is an important difference when the * 
-        * program is rapidly changing the period to modulate the sound.            * 
-        * To compensate for the difference, when the period is changed we adjust   * 
-        * our internal counter.                                                    * 
-        * Also, note that period = 0 is the same as period = 1. This is mentioned  * 
-        * in the YM2203 data sheets. However, this does NOT apply to the Envelope  * 
-        * period. In that case, period = 0 is half as period = 1.                  */
-       switch (r)
+       /* A note about the period of tones, noise and envelope: for speed reasons,*/
+       /* we count down from the period to 0, but careful studies of the chip     */
+       /* output prove that it instead counts up from 0 until the counter becomes */
+       /* greater or equal to the period. This is an important difference when the*/
+       /* program is rapidly changing the period to modulate the sound.           */
+       /* To compensate for the difference, when the period is changed we adjust  */
+       /* our internal counter.                                                   */
+       /* Also, note that period = 0 is the same as period = 1. This is mentioned */
+       /* in the YM2203 data sheets. However, this does NOT apply to the Envelope */
+       /* period. In that case, period = 0 is half as period = 1. */
+       switch( r )
        {
        case AY_AFINE:
        case AY_ACOARSE:
-               PSG->Regs[AY_ACOARSE] &= 0x0F;
+               PSG->Regs[AY_ACOARSE] &= 0x0f;
                old = PSG->PeriodA;
                PSG->PeriodA = (PSG->Regs[AY_AFINE] + 256 * PSG->Regs[AY_ACOARSE]) * PSG->UpdateStep;
-
                if (PSG->PeriodA == 0) PSG->PeriodA = PSG->UpdateStep;
-
                PSG->CountA += PSG->PeriodA - old;
-
                if (PSG->CountA <= 0) PSG->CountA = 1;
                break;
        case AY_BFINE:
        case AY_BCOARSE:
-               PSG->Regs[AY_BCOARSE] &= 0x0F;
+               PSG->Regs[AY_BCOARSE] &= 0x0f;
                old = PSG->PeriodB;
                PSG->PeriodB = (PSG->Regs[AY_BFINE] + 256 * PSG->Regs[AY_BCOARSE]) * PSG->UpdateStep;
-
                if (PSG->PeriodB == 0) PSG->PeriodB = PSG->UpdateStep;
-
                PSG->CountB += PSG->PeriodB - old;
-
                if (PSG->CountB <= 0) PSG->CountB = 1;
                break;
        case AY_CFINE:
        case AY_CCOARSE:
-               PSG->Regs[AY_CCOARSE] &= 0x0F;
+               PSG->Regs[AY_CCOARSE] &= 0x0f;
                old = PSG->PeriodC;
                PSG->PeriodC = (PSG->Regs[AY_CFINE] + 256 * PSG->Regs[AY_CCOARSE]) * PSG->UpdateStep;
-
                if (PSG->PeriodC == 0) PSG->PeriodC = PSG->UpdateStep;
-
                PSG->CountC += PSG->PeriodC - old;
-
                if (PSG->CountC <= 0) PSG->CountC = 1;
                break;
        case AY_NOISEPER:
-               PSG->Regs[AY_NOISEPER] &= 0x1F;
+               PSG->Regs[AY_NOISEPER] &= 0x1f;
                old = PSG->PeriodN;
                PSG->PeriodN = PSG->Regs[AY_NOISEPER] * PSG->UpdateStep;
-
                if (PSG->PeriodN == 0) PSG->PeriodN = PSG->UpdateStep;
-
                PSG->CountN += PSG->PeriodN - old;
-
                if (PSG->CountN <= 0) PSG->CountN = 1;
                break;
        case AY_ENABLE:
@@ -169,17 +180,17 @@ void _AYWriteReg(int n, int r, int v)
                PSG->lastEnable = PSG->Regs[AY_ENABLE];
                break;
        case AY_AVOL:
-               PSG->Regs[AY_AVOL] &= 0x1F;
+               PSG->Regs[AY_AVOL] &= 0x1f;
                PSG->EnvelopeA = PSG->Regs[AY_AVOL] & 0x10;
                PSG->VolA = PSG->EnvelopeA ? PSG->VolE : PSG->VolTable[PSG->Regs[AY_AVOL] ? PSG->Regs[AY_AVOL]*2+1 : 0];
                break;
        case AY_BVOL:
-               PSG->Regs[AY_BVOL] &= 0x1F;
+               PSG->Regs[AY_BVOL] &= 0x1f;
                PSG->EnvelopeB = PSG->Regs[AY_BVOL] & 0x10;
                PSG->VolB = PSG->EnvelopeB ? PSG->VolE : PSG->VolTable[PSG->Regs[AY_BVOL] ? PSG->Regs[AY_BVOL]*2+1 : 0];
                break;
        case AY_CVOL:
-               PSG->Regs[AY_CVOL] &= 0x1F;
+               PSG->Regs[AY_CVOL] &= 0x1f;
                PSG->EnvelopeC = PSG->Regs[AY_CVOL] & 0x10;
                PSG->VolC = PSG->EnvelopeC ? PSG->VolE : PSG->VolTable[PSG->Regs[AY_CVOL] ? PSG->Regs[AY_CVOL]*2+1 : 0];
                break;
@@ -187,11 +198,8 @@ void _AYWriteReg(int n, int r, int v)
        case AY_ECOARSE:
                old = PSG->PeriodE;
                PSG->PeriodE = ((PSG->Regs[AY_EFINE] + 256 * PSG->Regs[AY_ECOARSE])) * PSG->UpdateStep;
-
                if (PSG->PeriodE == 0) PSG->PeriodE = PSG->UpdateStep / 2;
-
                PSG->CountE += PSG->PeriodE - old;
-
                if (PSG->CountE <= 0) PSG->CountE = 1;
                break;
        case AY_ESHAPE:
@@ -221,9 +229,8 @@ void _AYWriteReg(int n, int r, int v)
                has twice the steps, happening twice as fast. Since the end result is
                just a smoother curve, we always use the YM2149 behaviour.
                */
-               PSG->Regs[AY_ESHAPE] &= 0x0F;
-               PSG->Attack = (PSG->Regs[AY_ESHAPE] & 0x04) ? 0x1F : 0x00;
-
+               PSG->Regs[AY_ESHAPE] &= 0x0f;
+               PSG->Attack = (PSG->Regs[AY_ESHAPE] & 0x04) ? 0x1f : 0x00;
                if ((PSG->Regs[AY_ESHAPE] & 0x08) == 0)
                {
                        /* if Continue = 0, map the shape to the equivalent one which has Continue = 1 */
@@ -235,12 +242,10 @@ void _AYWriteReg(int n, int r, int v)
                        PSG->Hold = PSG->Regs[AY_ESHAPE] & 0x01;
                        PSG->Alternate = PSG->Regs[AY_ESHAPE] & 0x02;
                }
-
                PSG->CountE = PSG->PeriodE;
-               PSG->CountEnv = 0x1F;
+               PSG->CountEnv = 0x1f;
                PSG->Holding = 0;
                PSG->VolE = PSG->VolTable[PSG->CountEnv ^ PSG->Attack];
-
                if (PSG->EnvelopeA) PSG->VolA = PSG->VolE;
                if (PSG->EnvelopeB) PSG->VolB = PSG->VolE;
                if (PSG->EnvelopeC) PSG->VolC = PSG->VolE;
@@ -279,74 +284,76 @@ void _AYWriteReg(int n, int r, int v)
 // NB. This should be called at twice the 6522 IRQ rate or (eg) 60Hz if no IRQ.
 void AY8910Update(int chip, int16 ** buffer, int length)       // [TC: Removed static]
 {
-       struct AY8910 * PSG = &AYPSG[chip];
-       INT16 * buf1, * buf2, * buf3;
+       struct AY8910 *PSG = &AYPSG[chip];
+       INT16 *buf1,*buf2,*buf3;
        int outn;
 
        buf1 = buffer[0];
        buf2 = buffer[1];
        buf3 = buffer[2];
 
-       /* The 8910 has three outputs, each output is the mix of one of the three    *
-        * tone generators and of the (single) noise generator. The two are mixed    *
-        * BEFORE going into the DAC. The formula to mix each channel is:            *
-        * (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable).                        *
-        * Note that this means that if both tone and noise are disabled, the output *
-        * is 1, not 0, and can be modulated changing the volume.                    *
-        *                                                                           *
-        * If the channels are disabled, set their output to 1, and increase the     *
-        * counter, if necessary, so they will not be inverted during this update.   *
-        * Setting the output to 1 is necessary because a disabled channel is locked *
-        * into the ON state (see above); and it has no effect if the volume is 0.   *
-        * If the volume is 0, increase the counter, but don't touch the output.     */
+
+       /* The 8910 has three outputs, each output is the mix of one of the three */
+       /* tone generators and of the (single) noise generator. The two are mixed */
+       /* BEFORE going into the DAC. The formula to mix each channel is: */
+       /* (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable). */
+       /* Note that this means that if both tone and noise are disabled, the output */
+       /* is 1, not 0, and can be modulated changing the volume. */
+
+
+       /* If the channels are disabled, set their output to 1, and increase the */
+       /* counter, if necessary, so they will not be inverted during this update. */
+       /* Setting the output to 1 is necessary because a disabled channel is locked */
+       /* into the ON state (see above); and it has no effect if the volume is 0. */
+       /* If the volume is 0, increase the counter, but don't touch the output. */
        if (PSG->Regs[AY_ENABLE] & 0x01)
        {
-               if (PSG->CountA <= length * STEP) PSG->CountA += length * STEP;
+               if (PSG->CountA <= length*STEP) PSG->CountA += length*STEP;
                PSG->OutputA = 1;
        }
        else if (PSG->Regs[AY_AVOL] == 0)
        {
-               /* note that I do count += length, NOT count = length + 1. You might think *
-                * it's the same since the volume is 0, but doing the latter could cause   *
-                * interferencies when the program is rapidly modulating the volume.       */
-               if (PSG->CountA <= length * STEP) PSG->CountA += length * STEP;
+               /* note that I do count += length, NOT count = length + 1. You might think */
+               /* it's the same since the volume is 0, but doing the latter could cause */
+               /* interferencies when the program is rapidly modulating the volume. */
+               if (PSG->CountA <= length*STEP) PSG->CountA += length*STEP;
        }
-
        if (PSG->Regs[AY_ENABLE] & 0x02)
        {
-               if (PSG->CountB <= length * STEP) PSG->CountB += length * STEP;
+               if (PSG->CountB <= length*STEP) PSG->CountB += length*STEP;
                PSG->OutputB = 1;
        }
        else if (PSG->Regs[AY_BVOL] == 0)
        {
-               if (PSG->CountB <= length * STEP) PSG->CountB += length * STEP;
+               if (PSG->CountB <= length*STEP) PSG->CountB += length*STEP;
        }
-
        if (PSG->Regs[AY_ENABLE] & 0x04)
        {
-               if (PSG->CountC <= length * STEP) PSG->CountC += length * STEP;
+               if (PSG->CountC <= length*STEP) PSG->CountC += length*STEP;
                PSG->OutputC = 1;
        }
        else if (PSG->Regs[AY_CVOL] == 0)
        {
-               if (PSG->CountC <= length * STEP) PSG->CountC += length * STEP;
+               if (PSG->CountC <= length*STEP) PSG->CountC += length*STEP;
        }
 
-       /* for the noise channel we must not touch OutputN - it's also not necessary *
-        * since we use outn.                                                        */
+       /* for the noise channel we must not touch OutputN - it's also not necessary */
+       /* since we use outn. */
        if ((PSG->Regs[AY_ENABLE] & 0x38) == 0x38)      /* all off */
-               if (PSG->CountN <= length * STEP) PSG->CountN += length * STEP;
+               if (PSG->CountN <= length*STEP) PSG->CountN += length*STEP;
 
        outn = (PSG->OutputN | PSG->Regs[AY_ENABLE]);
 
+
        /* buffering loop */
        while (length)
        {
-               int vola, volb, volc;
+               int vola,volb,volc;
                int left;
 
-               /* vola, volb and volc keep track of how long each square wave stays *
-                * in the 1 position during the sample period.                       */
+
+               /* vola, volb and volc keep track of how long each square wave stays */
+               /* in the 1 position during the sample period. */
                vola = volb = volc = 0;
 
                left = STEP;
@@ -354,38 +361,34 @@ void AY8910Update(int chip, int16 ** buffer, int length)  // [TC: Removed static]
                {
                        int nextevent;
 
+
                        if (PSG->CountN < left) nextevent = PSG->CountN;
                        else nextevent = left;
 
                        if (outn & 0x08)
                        {
                                if (PSG->OutputA) vola += PSG->CountA;
-
                                PSG->CountA -= nextevent;
-                               /* PeriodA is the half period of the square wave. Here, in each    *
-                                * loop I add PeriodA twice, so that at the end of the loop the    *
-                                * square wave is in the same status (0 or 1) it was at the start. *
-                                * vola is also incremented by PeriodA, since the wave has been 1  *
-                                * exactly half of the time, regardless of the initial position.   *
-                                * If we exit the loop in the middle, OutputA has to be inverted   *
-                                * and vola incremented only if the exit status of the square      *
-                                * wave is 1.                                                      */
+                               /* PeriodA is the half period of the square wave. Here, in each */
+                               /* loop I add PeriodA twice, so that at the end of the loop the */
+                               /* square wave is in the same status (0 or 1) it was at the start. */
+                               /* vola is also incremented by PeriodA, since the wave has been 1 */
+                               /* exactly half of the time, regardless of the initial position. */
+                               /* If we exit the loop in the middle, OutputA has to be inverted */
+                               /* and vola incremented only if the exit status of the square */
+                               /* wave is 1. */
                                while (PSG->CountA <= 0)
                                {
                                        PSG->CountA += PSG->PeriodA;
-
                                        if (PSG->CountA > 0)
                                        {
                                                PSG->OutputA ^= 1;
-
                                                if (PSG->OutputA) vola += PSG->PeriodA;
                                                break;
                                        }
-
                                        PSG->CountA += PSG->PeriodA;
                                        vola += PSG->PeriodA;
                                }
-
                                if (PSG->OutputA) vola -= PSG->CountA;
                        }
                        else
@@ -394,13 +397,11 @@ void AY8910Update(int chip, int16 ** buffer, int length)  // [TC: Removed static]
                                while (PSG->CountA <= 0)
                                {
                                        PSG->CountA += PSG->PeriodA;
-
                                        if (PSG->CountA > 0)
                                        {
                                                PSG->OutputA ^= 1;
                                                break;
                                        }
-
                                        PSG->CountA += PSG->PeriodA;
                                }
                        }
@@ -408,41 +409,32 @@ void AY8910Update(int chip, int16 ** buffer, int length)  // [TC: Removed static]
                        if (outn & 0x10)
                        {
                                if (PSG->OutputB) volb += PSG->CountB;
-
                                PSG->CountB -= nextevent;
-
                                while (PSG->CountB <= 0)
                                {
                                        PSG->CountB += PSG->PeriodB;
-
                                        if (PSG->CountB > 0)
                                        {
                                                PSG->OutputB ^= 1;
-
                                                if (PSG->OutputB) volb += PSG->PeriodB;
                                                break;
                                        }
-
                                        PSG->CountB += PSG->PeriodB;
                                        volb += PSG->PeriodB;
                                }
-
                                if (PSG->OutputB) volb -= PSG->CountB;
                        }
                        else
                        {
                                PSG->CountB -= nextevent;
-
                                while (PSG->CountB <= 0)
                                {
                                        PSG->CountB += PSG->PeriodB;
-
                                        if (PSG->CountB > 0)
                                        {
                                                PSG->OutputB ^= 1;
                                                break;
                                        }
-
                                        PSG->CountB += PSG->PeriodB;
                                }
                        }
@@ -450,90 +442,74 @@ void AY8910Update(int chip, int16 ** buffer, int length)  // [TC: Removed static]
                        if (outn & 0x20)
                        {
                                if (PSG->OutputC) volc += PSG->CountC;
-
                                PSG->CountC -= nextevent;
-
                                while (PSG->CountC <= 0)
                                {
                                        PSG->CountC += PSG->PeriodC;
-
                                        if (PSG->CountC > 0)
                                        {
                                                PSG->OutputC ^= 1;
-
                                                if (PSG->OutputC) volc += PSG->PeriodC;
                                                break;
                                        }
-
                                        PSG->CountC += PSG->PeriodC;
                                        volc += PSG->PeriodC;
                                }
-
                                if (PSG->OutputC) volc -= PSG->CountC;
                        }
                        else
                        {
                                PSG->CountC -= nextevent;
-
                                while (PSG->CountC <= 0)
                                {
                                        PSG->CountC += PSG->PeriodC;
-
                                        if (PSG->CountC > 0)
                                        {
                                                PSG->OutputC ^= 1;
                                                break;
                                        }
-
                                        PSG->CountC += PSG->PeriodC;
                                }
                        }
 
                        PSG->CountN -= nextevent;
-
                        if (PSG->CountN <= 0)
                        {
                                /* Is noise output going to change? */
-                               if ((PSG->RNG + 1) & 0x00002)   /* (bit0^bit1)? */
+                               if ((PSG->RNG + 1) & 2) /* (bit0^bit1)? */
                                {
                                        PSG->OutputN = ~PSG->OutputN;
                                        outn = (PSG->OutputN | PSG->Regs[AY_ENABLE]);
                                }
 
-                               /* The Random Number Generator of the 8910 is a 17-bit shift  *
-                                * register. The input to the shift register is bit0 XOR bit3 *
-                                * (bit0 is the output). This was verified on AY-3-8910 and   *
-                                * YM2149 chips.                                              *
-                                *                                                            *
-                                * The following is a fast way to compute bit17 = bit0^bit3.  *
-                                * Instead of doing all the logic operations, we only check   *
-                                * bit0, relying on the fact that after three shifts of the   *
-                                * register, what now is bit3 will become bit0, and will      *
-                                * invert, if necessary, bit14, which previously was bit17.   */
-                               if (PSG->RNG & 0x00001)
-                                       PSG->RNG ^= 0x24000; /* This version is called the "Galois configuration". */
+                               /* The Random Number Generator of the 8910 is a 17-bit shift */
+                               /* register. The input to the shift register is bit0 XOR bit3 */
+                               /* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */
 
+                               /* The following is a fast way to compute bit17 = bit0^bit3. */
+                               /* Instead of doing all the logic operations, we only check */
+                               /* bit0, relying on the fact that after three shifts of the */
+                               /* register, what now is bit3 will become bit0, and will */
+                               /* invert, if necessary, bit14, which previously was bit17. */
+                               if (PSG->RNG & 1) PSG->RNG ^= 0x24000; /* This version is called the "Galois configuration". */
                                PSG->RNG >>= 1;
                                PSG->CountN += PSG->PeriodN;
                        }
 
                        left -= nextevent;
-               }
-               while (left > 0);
+               } while (left > 0);
 
                /* update envelope */
                if (PSG->Holding == 0)
                {
                        PSG->CountE -= STEP;
-
                        if (PSG->CountE <= 0)
                        {
                                do
                                {
                                        PSG->CountEnv--;
                                        PSG->CountE += PSG->PeriodE;
-                               }
-                               while (PSG->CountE <= 0);
+                               } while (PSG->CountE <= 0);
 
                                /* check envelope current position */
                                if (PSG->CountEnv < 0)
@@ -541,19 +517,18 @@ void AY8910Update(int chip, int16 ** buffer, int length)  // [TC: Removed static]
                                        if (PSG->Hold)
                                        {
                                                if (PSG->Alternate)
-                                                       PSG->Attack ^= 0x1F;
-
+                                                       PSG->Attack ^= 0x1f;
                                                PSG->Holding = 1;
                                                PSG->CountEnv = 0;
                                        }
                                        else
                                        {
-                                               /* if CountEnv has looped an odd number of times (usually 1), *
-                                                * invert the output.                                         */
+                                               /* if CountEnv has looped an odd number of times (usually 1), */
+                                               /* invert the output. */
                                                if (PSG->Alternate && (PSG->CountEnv & 0x20))
-                                                       PSG->Attack ^= 0x1F;
+                                                       PSG->Attack ^= 0x1f;
 
-                                               PSG->CountEnv &= 0x1F;
+                                               PSG->CountEnv &= 0x1f;
                                        }
                                }
 
@@ -569,77 +544,90 @@ void AY8910Update(int chip, int16 ** buffer, int length)  // [TC: Removed static]
                *(buf1++) = (vola * PSG->VolA) / STEP;
                *(buf2++) = (volb * PSG->VolB) / STEP;
                *(buf3++) = (volc * PSG->VolC) / STEP;
-#else  // [Tom's code...]
+#else
                // Output PCM wave [-32768...32767] instead of MAME's voltage level [0...32767]
                // - This allows for better s/w mixing
 
-               if (PSG->VolA)
+               if(PSG->VolA)
                {
-                       if (vola)
+                       if(vola)
                                *(buf1++) = (vola * PSG->VolA) / STEP;
                        else
-                               *(buf1++) = -(int)PSG->VolA;
+                               *(buf1++) = - (int) PSG->VolA;
                }
                else
+               {
                        *(buf1++) = 0;
+               }
 
-               if (PSG->VolB)
+               //
+
+               if(PSG->VolB)
                {
-                       if (volb)
+                       if(volb)
                                *(buf2++) = (volb * PSG->VolB) / STEP;
                        else
-                               *(buf2++) = -(int)PSG->VolB;
+                               *(buf2++) = - (int) PSG->VolB;
                }
                else
+               {
                        *(buf2++) = 0;
+               }
 
-               if (PSG->VolC)
+               //
+
+               if(PSG->VolC)
                {
-                       if (volc)
+                       if(volc)
                                *(buf3++) = (volc * PSG->VolC) / STEP;
                        else
-                               *(buf3++) = -(int)PSG->VolC;
+                               *(buf3++) = - (int) PSG->VolC;
                }
                else
+               {
                        *(buf3++) = 0;
+               }
 #endif
+
                length--;
        }
 }
 
 
-static void AY8910_set_clock(int chip, int clock)
+static void AY8910_set_clock(int chip,int clock)
 {
-       struct AY8910 * PSG = &AYPSG[chip];
-
-       /* The step clock for the tone and noise generators is the chip clock    *
-        * divided by 8; for the envelope generator of the AY-3-8910, it is half *
-        * that much (clock/16), but the envelope of the YM2149 goes twice as    *
-        * fast, therefore again clock/8.                                        *
-        * Here we calculate the number of steps which happen during one sample  *
-        * at the given sample rate. No. of events = sample rate / (clock/8).    *
-        * STEP is a multiplier used to turn the fraction into a fixed point     *
-        * number.                                                               */
-       PSG->UpdateStep = (unsigned int)(((double)STEP * PSG->SampleRate * 8 + clock / 2) / clock);     // [TC: unsigned int cast]
+       struct AY8910 *PSG = &AYPSG[chip];
+
+       /* the step clock for the tone and noise generators is the chip clock    */
+       /* divided by 8; for the envelope generator of the AY-3-8910, it is half */
+       /* that much (clock/16), but the envelope of the YM2149 goes twice as    */
+       /* fast, therefore again clock/8.                                        */
+       /* Here we calculate the number of steps which happen during one sample  */
+       /* at the given sample rate. No. of events = sample rate / (clock/8).    */
+       /* STEP is a multiplier used to turn the fraction into a fixed point     */
+       /* number.                                                               */
+       PSG->UpdateStep = (unsigned int) (((double)STEP * PSG->SampleRate * 8 + clock/2) / clock);      // [TC: unsigned int cast]
 }
 
 
 static void build_mixer_table(int chip)
 {
-       struct AY8910 * PSG = &AYPSG[chip];
+       struct AY8910 *PSG = &AYPSG[chip];
+       int i;
+       double out;
 
-       /* calculate the volume->voltage conversion table                     */
+
+       /* calculate the volume->voltage conversion table */
        /* The AY-3-8910 has 16 levels, in a logarithmic scale (3dB per step) */
        /* The YM2149 still has 16 levels for the tone generators, but 32 for */
-       /* the envelope generator (1.5dB per step).                           */
-       double out = MAX_OUTPUT;
-
-       for(int i=31; i>0; i--)
+       /* the envelope generator (1.5dB per step). */
+       out = MAX_OUTPUT;
+       for (i = 31;i > 0;i--)
        {
-               PSG->VolTable[i] = (unsigned int)(out + 0.5);   /* round to nearest */  // [TC: unsigned int cast]
+               PSG->VolTable[i] = (unsigned int) (out + 0.5);  /* round to nearest */  // [TC: unsigned int cast]
+
                out /= 1.188502227;     /* = 10 ^ (1.5/20) = 1.5dB */
        }
-
        PSG->VolTable[0] = 0;
 }
 
@@ -647,48 +635,59 @@ static void build_mixer_table(int chip)
 void AY8910_reset(int chip)
 {
        int i;
-       struct AY8910 * PSG = &AYPSG[chip];
+       struct AY8910 *PSG = &AYPSG[chip];
 
        PSG->register_latch = 0;
        PSG->RNG = 1;
        PSG->OutputA = 0;
        PSG->OutputB = 0;
        PSG->OutputC = 0;
-       PSG->OutputN = 0xFF;
+       PSG->OutputN = 0xff;
        PSG->lastEnable = -1;   /* force a write */
-
-       for(i=0; i<AY_PORTA; i++)
-               _AYWriteReg(chip, i, 0);        /* AYWriteReg() uses the timer system; we cannot */
-                                                                       /* call it at this time because the timer system */
-                                                                       /* has not been initialized.                     */
+       for (i = 0;i < AY_PORTA;i++)
+               _AYWriteReg(chip,i,0);  /* AYWriteReg() uses the timer system; we cannot */
+                                                               /* call it at this time because the timer system */
+                                                               /* has not been initialized. */
 }
 
-// This stuff looks like Tom's code, so let's streamline and un-MSHungarianize this shit:
-// [DONE]
+//-------------------------------------
 
-void AY8910_InitAll(int clock, int sampleRate)
+void AY8910_InitAll(int nClock, int nSampleRate)
 {
-       for(int chip=0; chip<MAX_8910; chip++)
+       for(int nChip=0; nChip<MAX_8910; nChip++)
        {
-               struct AY8910 * PSG = &AYPSG[chip];
+               struct AY8910 *PSG = &AYPSG[nChip];
+
+               memset(PSG,0,sizeof(struct AY8910));
+               PSG->SampleRate = nSampleRate;
+
+//             PSG->PortAread = NULL;
+//             PSG->PortBread = NULL;
+//             PSG->PortAwrite = NULL;
+//             PSG->PortBwrite = NULL;
 
-               memset(PSG, 0, sizeof(struct AY8910));
-               PSG->SampleRate = sampleRate;
-               AY8910_set_clock(chip, clock);
-               build_mixer_table(chip);
+               AY8910_set_clock(nChip, nClock);
+
+               build_mixer_table(nChip);
        }
 }
 
-void AY8910_InitClock(int clock)
+//-------------------------------------
+
+void AY8910_InitClock(int nClock)
 {
-       for(int chip=0; chip<MAX_8910; chip++)
-               AY8910_set_clock(chip, clock);
+       for(int nChip=0; nChip<MAX_8910; nChip++)
+       {
+               AY8910_set_clock(nChip, nClock);
+       }
 }
 
-uint8 * AY8910_GetRegsPtr(uint16 chipNum)
+//-------------------------------------
+
+uint8 * AY8910_GetRegsPtr(uint16 nAyNum)
 {
-       if (chipNum >= MAX_8910)
+       if(nAyNum >= MAX_8910)
                return NULL;
 
-       return &AYPSG[chipNum].Regs[0];
+       return &AYPSG[nAyNum].Regs[0];
 }
index b5af684a92c9e1d0492116f514fc5568c1fc7bec..4c4119f7b9be6f0e41e53ef1dfcbb966103b6771 100755 (executable)
@@ -26,6 +26,8 @@
 #define MASK_A 0xFF000000
 #endif
 
+using namespace std;                                                           // For STL stuff
+
 //
 // Button class implementation
 //
@@ -33,7 +35,7 @@
 /*
 Some notes about this class:
 
-- Button colors are hardwired (for plain text buttons)
+- Button colors are hardwired
 */
 
 Button::Button(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*= 0*/,
@@ -76,7 +78,7 @@ Button::Button(uint32 x, uint32 y, SDL_Surface * bU, SDL_Surface * bH/*= NULL*/,
                extents.h = buttonUp->h;
 }
 
-Button::Button(uint32 x, uint32 y, uint32 w, uint32 h, std::string s, Element * parent/*= NULL*/):
+Button::Button(uint32 x, uint32 y, uint32 w, uint32 h, string s, Element * parent/*= NULL*/):
        Element(x, y, w, h, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, parent),
        activated(false), clicked(false), inside(false),
        buttonUp(NULL), buttonDown(NULL), buttonHover(NULL), surfacesAreLocal(true),
@@ -85,7 +87,7 @@ Button::Button(uint32 x, uint32 y, uint32 w, uint32 h, std::string s, Element *
        // Create the button surfaces here...
 }
 
-Button::Button(uint32 x, uint32 y, std::string s, Element * parent/*= NULL*/):
+Button::Button(uint32 x, uint32 y, string s, Element * parent/*= NULL*/):
        Element(x, y, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, parent),
        activated(false), clicked(false), inside(false),
        buttonUp(NULL), buttonDown(NULL), buttonHover(NULL), surfacesAreLocal(true),
@@ -168,6 +170,8 @@ void Button::Draw(void)
        if (buttonUp == NULL)
                return;                                                                 // Bail out if no surface was created...
 
+       SDL_Rect rect = GetScreenCoords();
+
        // Now, draw the appropriate button state!
 
        SDL_Surface * picToShow = buttonUp;
@@ -178,10 +182,6 @@ void Button::Draw(void)
        if (buttonDown != NULL && inside && clicked)
                picToShow = buttonDown;
 
-       SDL_Rect rect = GetScreenCoords();
-
-//Need to do coverage list blitting here, to avoid unnecessary drawing when doing mouseovers
-//Also, need to add suport in Gui()...
        SDL_BlitSurface(picToShow, NULL, screen, &rect);        // This handles alpha blending too! :-D
 
        needToRefreshScreen = true;
index 8009486f0bf6c0c75460f04de218542df32ba91a..fcf366bbc8ad205d2700bff0368d521738609d45 100755 (executable)
@@ -8,7 +8,6 @@
 #define __BUTTON_H__
 
 #include <string>
-//#include <list>
 #include "element.h"
 
 //Apparently this approach doesn't work for inheritance... D'oh!
index 45635bff2dc77f4e79a70800a2459159ee64caa8..860e35d4fc2e8bf5f21443d2601f123608065377 100755 (executable)
@@ -32,8 +32,9 @@
 #define MASK_A 0xFF000000
 #endif
 
+using namespace std;                                                           // For STL stuff
+
 #define BACKGROUND_IMG_TEST
-//#define USE_COVERAGE_LISTS
 
 //
 // DraggableWindow class implementation
@@ -141,16 +142,6 @@ void DraggableWindow::HandleMouseButton(uint32 x, uint32 y, bool mouseDown)
 
 void DraggableWindow::Draw(void)
 {
-#ifdef USE_COVERAGE_LISTS
-       // These are *always* top level and parentless, so no need to traverse up through
-       // the parent chain...
-       for(std::list<SDL_Rect>::iterator i=coverList.begin(); i!=coverList.end(); i++)
-               SDL_FillRect(screen, &(*i), bgColor);
-
-       // Handle the items this window contains...
-       for(uint32 i=0; i<list.size(); i++)
-               list[i]->Draw();
-#else
        // These are *always* top level and parentless, so no need to traverse up through
        // the parent chain...
 //Perhaps we can make these parentable, put the parent traversal in the base class?
@@ -176,7 +167,6 @@ void DraggableWindow::Draw(void)
        // Handle the items this window contains...
        for(uint32 i=0; i<list.size(); i++)
                list[i]->Draw();
-#endif
 
 //Prolly don't need this since the close button will do this for us...
        needToRefreshScreen = true;
index bbaff3cc757598c1e826b7c1387013b16667a1c0..dc73bb9fd33e6592b349eef82fac9add22b52c1a 100755 (executable)
@@ -15,7 +15,6 @@
 //
 
 #include "element.h"
-#include "guimisc.h"                                                           // Various support functions
 
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
 #define MASK_R 0xFF000000
@@ -47,7 +46,6 @@ Element::Element(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*=
        extents.y = y,
        extents.w = w,
        extents.h = h;
-       coverList.push_back(extents);
 }
 
 Element::Element(uint32 x, uint32 y, uint32 w, uint32 h,
@@ -59,7 +57,6 @@ Element::Element(uint32 x, uint32 y, uint32 w, uint32 h,
        extents.y = y,
        extents.w = w,
        extents.h = h;
-       coverList.push_back(extents);
 
        // This *should* allow us to store our colors in an endian safe way... :-/
        uint8 * c = (uint8 *)&fgColor;
@@ -84,7 +81,7 @@ bool Element::Inside(uint32 x, uint32 y)
                && y >= (uint32)extents.y && y < (uint32)(extents.y + extents.h) ? true : false);
 }
 
-//Badly named--!!! FIX !!! [DONE]
+//Badly named--!!! FIX !!!
 //SDL_Rect Element::GetParentCorner(void)
 SDL_Rect Element::GetScreenCoords(void)
 {
@@ -105,7 +102,7 @@ SDL_Rect Element::GetScreenCoords(void)
        return rect;
 }
 
-#if 1
+#if 0
 //May use this in the future...
 SDL_Rect Element::GetParentRect(void)
 {
@@ -127,11 +124,6 @@ SDL_Rect Element::GetParentRect(void)
 }
 #endif
 
-SDL_Rect Element::GetExtents(void)
-{
-       return extents;
-}
-
 void Element::CreateBackstore(void)
 {
        backstore = SDL_CreateRGBSurface(SDL_SWSURFACE, extents.w, extents.h, 32,
@@ -148,145 +140,6 @@ void Element::RestoreScreenFromBackstore(void)
        SDL_BlitSurface(backstore, NULL, screen, &r);
 }
 
-void Element::SaveScreenToBackstore(void)
-{
-       SDL_BlitSurface(screen, &extents, backstore, NULL);
-}
-
-void Element::ResetCoverageList(void)
-{
-       // Setup our coverage list with the entire window area
-       coverList.empty();
-       coverList.push_back(extents);
-}
-
-void Element::AdjustCoverageList(SDL_Rect r)
-{
-//Prolly should have a bool here to set whether or not to do this crap, since it
-//takes a little time...
-
-       // Here's where we do the coverage list voodoo... :-)
-
-/*
-Steps:
-  o Check for intersection. If no intersection, then no need to divide rects.
-  o Loop through current rects. If rect is completely inside passed in rect, remove from list.
-  o Loop through remaining rects. If rect intersects, decompose to four rects and
-    exclude degenerate rects, push rest into the coverage list.
-
-*/
-//     std::list<Element *>::reverse_iterator ri;
-//     std::list<SDL_Rect>::iterator i;
-
-       // Loop through rects and remove those completely covered by passed in rect.
-/*     for(i=coverList.begin(); i!=coverList.end(); i++)
-       {
-//             if (RectanglesIntersect(r, *i))
-               if (RectangleFirstInsideSecond(*i, r))
-               {
-//This is not right--do a while loop instead of a for loop?
-                       // Remove it from the list...
-                       std::list<SDL_Rect>::iterator next = coverList.erase(i);
-               }
-       }
-*/
-       // Loop through rects and remove those completely covered by passed in rect.
-       std::list<SDL_Rect>::iterator i = coverList.begin();
-
-       while (i != coverList.end())
-       {
-               if (RectangleFirstInsideSecond(*i, r))
-                       i = coverList.erase(i);                         // This will also advance i to the next item!
-               else
-                       i++;
-       }
-
-//This may not be needed if nothing follows the loop below...!
-//     if (coverList.empty())
-//             return;
-
-       // Check for intersection. If no intersection, then no need to divide rects.
-       i = coverList.begin();
-
-       while (i != coverList.end())
-       {
-               if (RectanglesIntersect(r, *i))
-               {
-                       // Do the decomposition here. There will always be at least *one* rectangle
-                       // generated by this algorithm, so we know we're OK in removing the original
-                       // from the list. The general pattern looks like this:
-                       //
-                       // +------+
-                       // |1     |
-                       // +-+--+-+
-                       // |2|//|3|  <- Rectangle "r" is in the center
-                       // +-+--+-+
-                       // |4     |
-                       // +------+
-                       //
-                       // Even if r extends beyond the bounds of the rectangle under consideration,
-                       // that's OK because we test to see that the rectangle isn't degenerate
-                       // before adding it to the list.
-
-//Should probably use a separate list here and splice it in when we're done here...
-//Or, could use push_front() to avoid the problem... Neat! Doesn't require a separate list!
-//But, we need to remove the currently referenced rect... Another while loop!
-
-//This approach won't work--if no rect1 then we're screwed! [FIXED]
-//Now *that* will work...
-                       SDL_Rect current = *i;
-                       uint32 bottomOfRect1 = current.y;
-//                     uint32 rightOfRect2 = current.x;
-//                     uint32 leftOfRect3 = current.x + current.w;
-                       uint32 topOfRect4 = current.y + current.h;
-
-                       // Rectangle #1 (top)
-                       if (r.y > current.y)                            // Simple rectangle degeneracy test...
-                       {
-                               bottomOfRect1 = r.y;
-                               SDL_Rect rect = current;
-                               rect.h = r.y - current.y;
-                               coverList.push_front(rect);
-                       }
-
-                       // Rectangle #4 (bottom)
-                       if (r.y + r.h < current.y + current.h)
-                       {
-                               topOfRect4 = r.y + r.h;
-                               SDL_Rect rect = current;
-                               rect.y = r.y + r.h;
-                               rect.h = (current.y + current.h) - (r.y + r.h);
-                               coverList.push_front(rect);
-                       }
-
-                       // Rectangle #2 (left side)
-                       if (r.x > current.x)
-                       {
-                               SDL_Rect rect = current;
-                               rect.w = r.x - current.x;
-                               rect.y = bottomOfRect1;
-                               rect.h = topOfRect4 - bottomOfRect1;
-                               coverList.push_front(rect);
-                       }
-
-                       // Rectangle #3 (right side)
-                       if (r.x + r.w < current.x + current.w)
-                       {
-                               SDL_Rect rect;
-                               rect.x = r.x + r.w;
-                               rect.w = (current.x + current.w) - (r.x + r.w);
-                               rect.y = bottomOfRect1;
-                               rect.h = topOfRect4 - bottomOfRect1;
-                               coverList.push_front(rect);
-                       }
-
-                       i = coverList.erase(i);                         // This will also advance i to the next item!
-               }
-               else
-                       i++;
-       }
-}
-
 //
 // Class methods
 //
index a090a968c2164b9f92f1f912268d171cc3210c41..a53d0011d7b85584792171eec856ee7068529291 100755 (executable)
@@ -13,7 +13,6 @@
 enum { WINDOW_CLOSE, MENU_ITEM_CHOSEN, SCREEN_REFRESH_NEEDED };
 
 #include <SDL.h>
-#include <list>
 #include "types.h"
 
 class Element
@@ -35,17 +34,12 @@ class Element
 //Badly named, though we may code something that does this...
 //             SDL_Rect GetParentCorner(void);
                SDL_Rect GetScreenCoords(void);
-               SDL_Rect GetExtents(void);
-#if 1
+#if 0
 //May use this in the future...
                SDL_Rect GetParentRect(void);
 #endif
                void CreateBackstore(void);
                void RestoreScreenFromBackstore(void);
-               void SaveScreenToBackstore(void);
-               void ResetCoverageList(void);
-//Need something to prevent this on Elements that don't have mouseover effects...
-               void AdjustCoverageList(SDL_Rect r);
                // Class methods...
                static void SetScreen(SDL_Surface *);
                static bool ScreenNeedsRefreshing(void);
@@ -58,7 +52,6 @@ class Element
                uint32 fgColor;
                uint32 bgColor;
                SDL_Surface * backstore;
-               std::list<SDL_Rect> coverList;
 
                // Class variables...
                static SDL_Surface * screen;
index 2841992fc2ba07e8ddf2ab7cff55d1ee9f996067..ef5ef97b507417337094fcdffee16fc375e3c262 100755 (executable)
 // ---  ----------  ------------------------------------------------------------
 // JLH  02/03/2006  Created this file
 // JLH  03/13/2006  Added functions to allow shutting down GUI externally
-// JLH  03/22/2006  Finalized basic multiple window support
 //
-// STILL TO DO:
+
+// STILL TO FIX:
 //
-// - Memory leak on quitting with a window active [DONE]
-// - Multiple window handling [DONE]
+// - Memory leak on quitting with a window active
+// - Multiple window handling
 //
 
 #include "gui.h"
 
 //#define DEBUG_MAIN_LOOP
 
-//#ifdef DEBUG_MAIN_LOOP
+#ifdef DEBUG_MAIN_LOOP
 #include "log.h"
-//#endif
+#endif
 
 
-GUI::GUI(SDL_Surface * mainSurface): menuItem(new MenuItems())
+GUI::GUI(SDL_Surface * mainSurface): mainMenu(new Menu()), menuItem(new MenuItems())
 {
-       windowList.push_back(new Menu());
        Element::SetScreen(mainSurface);
 }
 
 GUI::~GUI()
 {
-       // Clean up menuItem, if any
+       if (mainMenu)
+               delete mainMenu;
 
        if (menuItem)
                delete menuItem;
-
-       // Clean up the rest
-
-       for(std::list<Element *>::iterator i=windowList.begin(); i!=windowList.end(); i++)
-               if (*i)
-                       delete *i;
 }
 
 void GUI::AddMenuTitle(const char * title)
@@ -65,32 +59,25 @@ void GUI::AddMenuItem(const char * item, Element * (* a)(void)/*= NULL*/, SDLKey
 
 void GUI::CommitItemsToMenu(void)
 {
-//We could just do a simple check here to see if more than one item is in the list,
-//and if so fail. Make it so you build the menu first before allowing any other action. [DONE]
-
-//Right now, we just silently fail...
-       if (windowList.size() > 1)
-       {
-               WriteLog("GUI: Can't find menu--more than one item in windowList!\n");
-               return;
-       }
-
-       ((Menu *)(*windowList.begin()))->Add(*menuItem);
+       mainMenu->Add(*menuItem);
 }
 
+
 void GUI::Run(void)
 {
        exitGUI = false;
-       showMouse = true;
+
+       bool showMouse = true;
+       int mouseX = 0, mouseY = 0;
+       int oldMouseX = 0, oldMouseY = 0;
+       Element * mainWindow = NULL;
        SDL_Event event;
-       std::list<Element *>::iterator i;
 
        SDL_EnableKeyRepeat(150, 75);
-
-       // Initial update... [Now handled correctly in the constructor]
-       for(i=windowList.begin(); i!=windowList.end(); i++)
-               (*i)->Draw();
-
+       // Initial update...
+//Shouldn't we save the state of the GUI instead of doing things this way?
+//We have a memory leak whenever a mainWindow is active and we quit... !!! FIX !!!
+       mainMenu->Draw();
        RenderScreenBuffer();
 
        // Main loop
@@ -109,47 +96,35 @@ WriteLog(" -- SDL_USEREVENT\n");
 //Mebbe add another user event for screen refresh? Why not!
                                if (event.user.code == WINDOW_CLOSE)
                                {
-                                       for(i=windowList.begin(); i!=windowList.end(); i++)
-                                       {
-                                               if (*i == (Element *)event.user.data1)
-                                               {
-                                                       delete *i;
-                                                       windowList.erase(i);
-                                                       break;
-                                               }
-                                       }
+                                       delete mainWindow;
+                                       mainWindow = NULL;
                                }
                                else if (event.user.code == MENU_ITEM_CHOSEN)
                                {
                                        // Confused? Let me enlighten... What we're doing here is casting
-                                       // data1 as a pointer to a function which returns a Element pointer and
-                                       // which takes no parameters (the "(Element *(*)(void))" part), then
+                                       // data1 as a pointer to a function which returns a Window pointer and
+                                       // which takes no parameters (the "(Window *(*)(void))" part), then
                                        // derefencing it (the "*" in front of that) in order to call the
                                        // function that it points to. Clear as mud? Yeah, I hate function
                                        // pointers too, but what else are you gonna do?
-                                       Element * window = (*(Element *(*)(void))event.user.data1)();
-
-                                       if (window)
-                                               windowList.push_back(window);
+                                       mainWindow = (*(Element *(*)(void))event.user.data1)();
 
                                        while (SDL_PollEvent(&event));  // Flush the event queue...
-
                                        event.type = SDL_MOUSEMOTION;
                                        int mx, my;
                                        SDL_GetMouseState(&mx, &my);
                                        event.motion.x = mx, event.motion.y = my;
                                    SDL_PushEvent(&event);                      // & update mouse position...!
 
-                                       oldMouse.x = mouse.x, oldMouse.y = mouse.y;
-                                       mouse.x = mx, mouse.y = my;             // This prevents "mouse flash"...
+                                       oldMouseX = mouseX, oldMouseY = mouseY;
+                                       mouseX = mx, mouseY = my;               // This prevents "mouse flash"...
                                }
-//There's a *small* problem with the following approach--if a window and a bunch of
-//child widgets send this message, we'll get a bunch of unnecessary refresh events...
+//There's a *small* problem with this approach--if a window and a bunch of child
+//widgets send this message, we'll get a bunch of unnecessary refresh events...
 //This could be controlled by having the main window refresh itself intelligently...
 
 //What we could do instead is set a variable in Element and check it after the fact
 //to see whether or not a refresh is needed.
-//[This is what we do now.]
 
 //Dirty rectangle is also possible...
                                else if (event.user.code == SCREEN_REFRESH_NEEDED)
@@ -157,235 +132,58 @@ WriteLog(" -- SDL_USEREVENT\n");
                        }
                        else if (event.type == SDL_ACTIVEEVENT)
                        {
-//Need to do a screen refresh here...
                                if (event.active.state == SDL_APPMOUSEFOCUS)
                                        showMouse = (event.active.gain ? true : false);
-
-                               RenderScreenBuffer();
                        }
                        else if (event.type == SDL_KEYDOWN)
                        {
 #ifdef DEBUG_MAIN_LOOP
 WriteLog(" -- SDL_KEYDOWN\n");
 #endif
-                               if (event.key.keysym.sym == SDLK_F1)
+                               if (event.key.keysym.sym == SDLK_F5)
                                        exitGUI = true;
 
-//Not sure that this is the right way to handle this...
-//Probably should only give this to the top level window...
-//                             for(i=windowList.begin(); i!=windowList.end(); i++)
-//                                     (*i)->HandleKey(event.key.keysym.sym);
-                               windowList.back()->HandleKey(event.key.keysym.sym);
+                               if (mainWindow)
+                                       mainWindow->HandleKey(event.key.keysym.sym);
+                               else
+                                       mainMenu->HandleKey(event.key.keysym.sym);
                        }
                        else if (event.type == SDL_MOUSEMOTION)
                        {
 #ifdef DEBUG_MAIN_LOOP
 WriteLog(" -- SDL_MOUSEMOTION\n");
 #endif
-//This is for tracking a custom mouse cursor, which we're not doing--YET.
-                               oldMouse.x = mouse.x, oldMouse.y = mouse.y;
-                               mouse.x = event.motion.x, mouse.y = event.motion.y;
+                               oldMouseX = mouseX, oldMouseY = mouseY;
+                               mouseX = event.motion.x, mouseY = event.motion.y;
 
-//Not sure that this is the right way to handle this...
-//Right now, we should probably only do mouseover for the last item in the list...
-//And now we do!
-//Though, it seems to screw other things up. Maybe it IS better to pass it to all windows?
-//Or maybe to just the ones that aren't completely obscured?
-//Probably. Right now, a disk's close button that should be obscured by one sitting on
-//top of it gets redrawn. Not good.
-                               for(i=windowList.begin(); i!=windowList.end(); i++)
-                                       (*i)->HandleMouseMove(mouse.x, mouse.y);
-//                             windowList.back()->HandleMouseMove(mouse.x, mouse.y);
+                               if (mainWindow)
+                                       mainWindow->HandleMouseMove(mouseX, mouseY);
+                               else
+                                       mainMenu->HandleMouseMove(mouseX, mouseY);
                        }
                        else if (event.type == SDL_MOUSEBUTTONDOWN)
                        {
 #ifdef DEBUG_MAIN_LOOP
-WriteLog(" -- SDL_MOUSEBUTTONDOWN\n");
+WriteLog(" -- SDL_MOSEBUTTONDOWN\n");
 #endif
-//Not sure that this is the right way to handle this...
-// What we should do here is ensure that whatever has been clicked on gets moved to the
-// highest priority--in our current data schema that would be the end of the list... !!! FIX !!!
-//[DONE]
-
-/*
-
-We could do the following:
-
-- Go through list and find which window has been clicked on (if any). If more
-  than one is clicked on, take the one highest in the Z order (closer to the end
-  of the list).
-
-- If item is highest in Z order, pack click through to window and exit.
-
-- Otherwise, restore backing store on each window in reverse order.
-
-- Remove item clicked on from the list. Put removed item at the end of the list.
-
-- Go through list and pass click through to each window in the list. Also do a
-  blit to backing store and a Draw() for each window.
-
-Could also do a check (if not clicked on highest Z window) to see which windows
-it overlaps and just do restore/redraw for those that overlap. To wit:
-
-- Create new list containing only those windows that overlap the clicking on window.
-
-- Go through list and do a blit to backing store and a Draw() for each window.
-
-- Go through list and pass click through to each window in the list.
-
-*/
-
-#if 0
-#if 0
-                               for(i=windowList.begin(); i!=windowList.end(); i++)
-                                       (*i)->HandleMouseButton(event.button.x, event.button.y, true);
-#else
-// We use the 1st algorithm here, since it's simpler. If we need to, we can optimize
-// to the 2nd...
+                               uint32 mx = event.button.x, my = event.button.y;
 
-                               // Walk backward through the list and see if a window was hit.
-                               // This will automagically return us the window with the highest Z.
-
-                               std::list<Element *>::reverse_iterator ri;
-                               std::list<Element *>::iterator hit;// = windowList.end();
-
-                               for(ri=windowList.rbegin(); ri!=windowList.rend(); ri++)
-                               {
-                                       if ((*ri)->Inside(event.button.x, event.button.y))
-                                       {
-                                               // Here's a bit of STL weirdness: Converting from a reverse
-                                               // iterator to a regular iterator requires backing the iterator
-                                               // up a position after grabbing it's base() OR going forward
-                                               // one position with the reverse iterator before grabbing base().
-                                               // Ugly, but it get the job done...
-                                               hit = (++ri).base();
-                                               // Put it back where we found it, so the tests following this
-                                               // don't fail...
-                                               ri--;
-                                               break;
-                                       }
-                               }
-
-                               // If we hit the highest in the list, then pass the event through
-                               // to the window for handling. if we hit no windows, then pass the
-                               // event to all windows. Otherwise, we need to shuffle windows.
-
-//NOTE: We need to pass the click to all windows regardless of whether they're topmost or not...
-                               if (ri == windowList.rbegin())
-                               {
-                                       for(i=windowList.begin(); i!=windowList.end(); i++)
-                                               (*i)->HandleMouseButton(event.button.x, event.button.y, true);
-                               }
-                               else if (ri == windowList.rend())
-                               {
-                                       for(i=windowList.begin(); i!=windowList.end(); i++)
-                                               (*i)->HandleMouseButton(event.button.x, event.button.y, true);
-                               }
+                               if (mainWindow)
+                                       mainWindow->HandleMouseButton(mx, my, true);
                                else
-                               {
-// - Otherwise, restore backing store on each window in reverse order.
-                                       for(ri=windowList.rbegin(); ri!=windowList.rend(); ri++)
-                                               (*ri)->RestoreScreenFromBackstore();
-                                       // At this point, the screen has been restored...
-
-// - Remove item clicked on from the list. Put removed item at the end of the list.
-                                       windowList.push_back(*hit);
-                                       windowList.erase(hit);
-// - Go through list and pass click through to each window in the list. Also do a
-//  blit to backing store and a Draw() for each window.
-                                       for(i=windowList.begin(); i!= windowList.end(); i++)
-                                       {
-                                               // Grab bg into backstore
-                                               (*i)->SaveScreenToBackstore();
-                                               // Pass click
-                                               (*i)->HandleMouseButton(event.button.x, event.button.y, true);
-                                               // Draw?
-                                               (*i)->Draw();
-                                       }
-                               }
-#endif
-#endif
-/*
-A slightly different way to handle this would be to loop through all windows, compare
-all those above it to see if they obscure it; if so then subdivide it's update rectangle
-to eliminate drawing the parts that aren't shown. The beauty of this approach is that
-you don't have to care what order the windows are drawn in and you don't need to worry
-about the order of restoring the backing store.
-
-You *do* still need to determine the Z-order of the windows, in order to get the subdivisions
-correct, but that's not too terrible.
-
-Also, when doing a window drag, the coverage lists for all windows have to be regenerated.
-*/
-                               std::list<Element *>::reverse_iterator ri;
-                               bool movedWindow = false;
-
-                               for(ri=windowList.rbegin(); ri!=windowList.rend(); ri++)
-                               {
-                                       if ((*ri)->Inside(event.button.x, event.button.y))
-                                       {
-                                               // Remove item clicked on from the list & put removed item at the
-                                               // end of the list, thus putting the window at the top of the Z
-                                               // order. But IFF window is not already topmost!
-                                               if (ri != windowList.rbegin())
-                                               {
-                                                       windowList.push_back(*ri);
-                                                       // Here's a bit of STL weirdness: Converting from a reverse
-                                                       // iterator to a regular iterator requires backing the iterator
-                                                       // up a position after grabbing it's base() OR going forward
-                                                       // one position with the reverse iterator before grabbing base().
-                                                       // Ugly, but it get the job done...
-                                                       windowList.erase((++ri).base());
-                                                       movedWindow = true;
-                                               }
-
-                                               break;
-                                       }
-                               }
-
-//Small problem here: we should only pass the *hit* to the topmost window and pass
-//*misses* to everyone else... Otherwise, you can have overlapping draggable windows
-//and be able to drag both by clicking on a point that intersects both...
-//(though that may be an interesting way to handle things!)
-                               // Pass the click on to all windows
-                               for(i=windowList.begin(); i!=windowList.end(); i++)
-                                       (*i)->HandleMouseButton(event.button.x, event.button.y, true);
-
-//                             // & bail if nothing changed...
-                               if (movedWindow)
-//                                     return;
-{
-                               // Check for overlap/build coverage lists [O((n^2)/2) algorithm!]
-//One way to optimize this would be to only reset coverage lists from the point in
-//the Z order where the previous window was.
-                               for(i=windowList.begin(); i!=windowList.end(); i++)
-                               {
-                                       (*i)->ResetCoverageList();
-
-                                       // This looks odd, but it's just a consequence of iterator weirdness.
-                                       // Otherwise we could just stick a j+1 in the for loop below. :-P
-                                       std::list<Element *>::iterator j = i;
-                                       j++;
-
-                                       for(; j!=windowList.end(); j++)
-                                               (*i)->AdjustCoverageList((*j)->GetExtents());
-
-//                                     (*i)->HandleMouseButton(event.button.x, event.button.y, true);
-                                       (*i)->Draw();
-                               }
-}
+                                       mainMenu->HandleMouseButton(mx, my, true);
                        }
                        else if (event.type == SDL_MOUSEBUTTONUP)
                        {
 #ifdef DEBUG_MAIN_LOOP
 WriteLog(" -- SDL_MOUSEBUTTONUP\n");
 #endif
-//Not sure that this is the right way to handle this...
-                               for(i=windowList.begin(); i!=windowList.end(); i++)
-                                       (*i)->HandleMouseButton(event.button.x, event.button.y, false);
-//I think we should only do topmost here...
-//Or should we???
-//                             windowList.back()->HandleMouseButton(event.button.x, event.button.y, false);
+                               uint32 mx = event.button.x, my = event.button.y;
+
+                               if (mainWindow)
+                                       mainWindow->HandleMouseButton(mx, my, false);
+                               else
+                                       mainMenu->HandleMouseButton(mx, my, false);
                        }
 #ifdef DEBUG_MAIN_LOOP
 else
index 05ab391b399209755b9fd045b13997ea84be64c9..b67783ade503ca48e8c56c7ae932473f23371fea 100755 (executable)
@@ -8,7 +8,7 @@
 #define __GUI_H__
 
 #include <SDL.h>
-#include <list>
+#include <vector>
 
 class Menu;                                                                            // Now *this* should work, since we've got pointers...
 class MenuItems;
@@ -26,12 +26,10 @@ class GUI
                void Stop(void);
 
        private:
-//             Menu * mainMenu;
+               Menu * mainMenu;
                MenuItems * menuItem;
-               std::list<Element *> windowList;
+               std::vector<Element *> windowList;
                bool exitGUI;
-               bool showMouse;
-               SDL_Rect mouse, oldMouse;
 };
 
 #endif // __GUI_H__
index 53b333ddb16226151c81955bdf06761097f035d6..99a8e352aa4cc2a132e0fdc85d6215ac77cb5852 100755 (executable)
@@ -156,47 +156,6 @@ void DrawStringOpaque(SDL_Surface * screen, uint32 x, uint32 y, uint32 fg, uint3
        SDL_FreeSurface(chr);
 }
 
-bool RectanglesIntersect(SDL_Rect r1, SDL_Rect r2)
-{
-       // The strategy here is to see if any of the sides of the smaller rect
-       // fall within the larger.
-
-/*
-    +-----------------+ r1
-    |                 |
-    |   +------+ r2   |
-    |   |      |      |
-    |   |      |      |
-    |   +------+      |
-    |                 |
-    +-----------------+
-
-*/
-
-//This approach fails if r2 is inside of r1. !!! FIX !!! [DONE]
-       if (RectangleFirstInsideSecond(r2, r1))
-               return true;
-
-       if ((r1.x > r2.x && r1.x < (r2.x + r2.w))
-               || ((r1.x + r1.w) > r2.x && (r1.x + r1.w) < (r2.x + r2.w))
-               || (r1.y > r2.y && r1.y < (r2.y + r2.h))
-               || ((r1.y + r1.h) > r2.y && (r1.y + r1.h) < (r2.y + r2.h)))
-               return true;
-
-       return false;
-}
-
-bool RectangleFirstInsideSecond(SDL_Rect r1, SDL_Rect r2)
-{
-       if ((r1.x > r2.x             && (r1.x + r1.w) > r2.x)
-               && (r1.x < (r2.x + r2.w) && (r1.x + r1.w) < (r2.x + r2.w))
-               && (r1.y > r2.y          && (r1.y + r1.h) > r2.y)
-               && (r1.y < (r2.y + r2.h) && (r1.y + r1.h) < (r2.y + r2.h)))
-               return true;
-
-       return false;
-}
-
 
 //
 // Various GUI bitmaps
index 84da8741e217339eb56cfd2f2baf543d7f8d6fc9..6382cc9c49186a292a91dcb8364412d0f2166efa 100755 (executable)
@@ -48,9 +48,7 @@ uint32 GetFontHeight(void);
 void DrawStringTrans(SDL_Surface * screen, uint32 x, uint32 y, uint32 color, const char * text, ...);
 void DrawStringOpaque(SDL_Surface * screen, uint32 x, uint32 y, uint32 fg, uint32 bg, const char * text, ...);
 
-//Not sure these belong here, but there you go...
-bool RectanglesIntersect(SDL_Rect r1, SDL_Rect r2);
-bool RectangleFirstInsideSecond(SDL_Rect r1, SDL_Rect r2);
+void DrawStringOpaqueSmall(SDL_Surface * screen, uint32 x, uint32 y, uint32 fg, uint32 bg, const char * text, ...);
 
 // GUI bitmaps (exported)
 
index 96e45e71d5a4d32534f5ce5b3f8ffd203b89e2be..96be146397091dc5a2a7f3e85eedf4aacd983313 100755 (executable)
 #define MASK_A 0xFF000000
 #endif
 
+using namespace std;                                                           // For STL stuff
+
 //
 // Text edit class implementation
 //
 
 TextEdit::TextEdit(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*= 0*/,
-       std::string s/*= ""*/, Element * parent/*= NULL*/):
+       string s/*= ""*/, Element * parent/*= NULL*/):
        Element(x, y, w, h, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x40, 0x40, 0xFF, parent),
        activated(false), clicked(false), inside(false),
        img(NULL), text(s), caretPos(0), scrollPos(0),
@@ -225,7 +227,7 @@ void TextEdit::Notify(Element *)
 {
 }
 
-std::string TextEdit::GetText(void)
+string TextEdit::GetText(void)
 {
        return text;
 }
index 0f460eaa8f428411b109870bd2eed0803fff8ac4..75b6cc1f8286b3209e711c8682dbcff203c80dfa 100755 (executable)
 #include "guimisc.h"                                                           // Various support functions
 #include <algorithm>
 
-// Debug support...
-//#define DESTRUCTOR_TESTING
-
-// Rendering experiment...
-#define USE_COVERAGE_LISTS
-
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
 #define MASK_R 0xFF000000
 #define MASK_G 0x00FF0000
@@ -36,6 +30,8 @@
 #define MASK_A 0xFF000000
 #endif
 
+using namespace std;                                                           // For STL stuff
+
 //
 // Window class implementation
 //
@@ -63,9 +59,6 @@ Window::Window(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*= 0*
 
 Window::~Window()
 {
-#ifdef DESTRUCTOR_TESTING
-printf("Inside ~Window()...\n");
-#endif
        for(uint32 i=0; i<list.size(); i++)
                if (list[i])
                        delete list[i];
@@ -107,16 +100,6 @@ void Window::HandleMouseButton(uint32 x, uint32 y, bool mouseDown)
 
 void Window::Draw(void)
 {
-#ifdef USE_COVERAGE_LISTS
-       // These are *always* top level and parentless, so no need to traverse up through
-       // the parent chain...
-       for(std::list<SDL_Rect>::iterator i=coverList.begin(); i!=coverList.end(); i++)
-               SDL_FillRect(screen, &(*i), bgColor);
-
-       // Handle the items this window contains...
-       for(uint32 i=0; i<list.size(); i++)
-               list[i]->Draw();
-#else
        // These are *always* top level and parentless, so no need to traverse up through
        // the parent chain...
        SDL_FillRect(screen, &extents, bgColor);
@@ -124,7 +107,6 @@ void Window::Draw(void)
        // Handle the items this window contains...
        for(uint32 i=0; i<list.size(); i++)
                list[i]->Draw();
-#endif
 
 //Prolly don't need this since the close button will do this for us...
        needToRefreshScreen = true;
@@ -135,9 +117,7 @@ void Window::Notify(Element * e)
        if (e == closeButton)
        {
                SDL_Event event;
-               event.type = SDL_USEREVENT;
-               event.user.code = WINDOW_CLOSE;
-               event.user.data1 = (void *)this;
+               event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE;
                SDL_PushEvent(&event);
        }
 }
index a98c16f7b677dc3e9692384b491967c40bce6d8e..9c2383392ba7602984175003b9f9811171186f02 100755 (executable)
@@ -15,6 +15,7 @@
 //However, the Atari version *does* occassionally pick strength while the Apple
 //versions do not--which would seem to indicate a bug either in the RNG algorithm,
 //the 65C02 core, or the Apple hardware. Need to investigate all three!
+//[As it turns out, it was a problem with the Apple RNG written by Origin. Bad Origin!]
 
 #define __DEBUG__
 //#define __DEBUGMON__
@@ -917,10 +918,10 @@ static void OpDE(void)                                                    // DEC ABS, X
 Here's one problem: DEX is setting the N flag!
 
 D3EE: A2 09          LDX   #$09                [PC=D3F0, SP=01F7, CC=---B-I-C, A=01, X=09, Y=08]
-D3F0: 98             TYA               [PC=D3F1, SP=01F7, CC=N--B-I-C, A=08, X=09, Y=08]
-D3F1: 48             PHA               [PC=D3F2, SP=01F6, CC=N--B-I-C, A=08, X=09, Y=08]
+D3F0: 98             TYA                       [PC=D3F1, SP=01F7, CC=N--B-I-C, A=08, X=09, Y=08]
+D3F1: 48             PHA                       [PC=D3F2, SP=01F6, CC=N--B-I-C, A=08, X=09, Y=08]
 D3F2: B5 93          LDA   $93,X               [PC=D3F4, SP=01F6, CC=---B-IZC, A=00, X=09, Y=08]
-D3F4: CA             DEX               [PC=D3F5, SP=01F6, CC=N--B-I-C, A=00, X=08, Y=08]
+D3F4: CA             DEX                       [PC=D3F5, SP=01F6, CC=N--B-I-C, A=00, X=08, Y=08]
 D3F5: 10 FA          BPL   $D3F1               [PC=D3F7, SP=01F6, CC=N--B-I-C, A=00, X=08, Y=08]
 D3F7: 20 84 E4       JSR   $E484               [PC=E484, SP=01F4, CC=N--B-I-C, A=00, X=08, Y=08]
 
@@ -1130,6 +1131,7 @@ JSR       Absolute        JSR Abs         20      3       6
 //This is not jumping to the correct address... !!! FIX !!! [DONE]
 static void Op20(void)                                                 // JSR
 {
+// The whole ret - 1 probably stems from a fetch/push/fetch/push sequence...
        uint16 addr = RdMemW(regs.pc);
        regs.pc++;                                                                      // Since it pushes return address - 1...
        regs.WrMem(0x0100 + regs.sp--, regs.pc >> 8);