Switch tab-indented files to 4-space indent

This commit is contained in:
Wolfgang Thaller
2019-08-18 13:21:00 +02:00
parent 9cb90cb3b0
commit e5185d23c3
133 changed files with 7879 additions and 7866 deletions
+17 -17
View File
@@ -1,19 +1,19 @@
# Copyright 2015 Wolfgang Thaller.
# Copyright 2015 Wolfgang Thaller.
#
# This file is part of Retro68.
# This file is part of Retro68.
#
# Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>.
# To use this example as a standalone project using CMake:
# mkdir build
@@ -22,16 +22,16 @@
# make
add_application(Dialog
dialog.c
dialog.r
)
dialog.c
dialog.r
)
# Enable -ffunction-sections and -gc-sections to make the app as small as possible
# On 68K, also enable --mac-single to build it as a single-segment app (so that this code path doesn't rot)
set_target_properties(Dialog PROPERTIES COMPILE_OPTIONS -ffunction-sections)
if(CMAKE_SYSTEM_NAME MATCHES Retro68)
set_target_properties(Dialog PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-single")
set_target_properties(Dialog PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-single")
else()
set_target_properties(Dialog PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
set_target_properties(Dialog PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
endif()
+9 -9
View File
@@ -22,10 +22,10 @@
#include <Fonts.h>
#ifndef TARGET_API_MAC_CARBON
/* NOTE: this is checking whether the Dialogs.h we use *knows* about Carbon,
not whether we are actually compiling for Cabon.
If Dialogs.h is older, we add a define to be able to use the new name
for NewUserItemUPP, which used to be NewUserItemProc. */
/* NOTE: this is checking whether the Dialogs.h we use *knows* about Carbon,
not whether we are actually compiling for Cabon.
If Dialogs.h is older, we add a define to be able to use the new name
for NewUserItemUPP, which used to be NewUserItemProc. */
#define NewUserItemUPP NewUserItemProc
#endif
@@ -33,7 +33,7 @@
pascal void ButtonFrameProc(DialogRef dlg, DialogItemIndex itemNo)
{
DialogItemType type;
Handle itemH;
Handle itemH;
Rect box;
GetDialogItem(dlg, 1, &type, &itemH, &box);
@@ -49,8 +49,8 @@ int main()
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(NULL);
TEInit();
InitDialogs(NULL);
#endif
DialogPtr dlg = GetNewDialog(128,0,(WindowPtr)-1);
InitCursor();
@@ -61,7 +61,7 @@ int main()
Rect box;
GetDialogItem(dlg, 2, &type, &itemH, &box);
SetDialogItem(dlg, 2, type, (Handle) NewUserItemUPP(&ButtonFrameProc), &box);
SetDialogItem(dlg, 2, type, (Handle) NewUserItemUPP(&ButtonFrameProc), &box);
ControlHandle cb, radio1, radio2;
GetDialogItem(dlg, 5, &type, &itemH, &box);
@@ -89,5 +89,5 @@ int main()
} while(item != 1);
FlushEvents(everyEvent, -1);
return 0;
return 0;
}
+7 -7
View File
@@ -5,17 +5,17 @@
# make
add_application(HelloWorld
hello.c
CONSOLE
hello.c
CONSOLE
)
# make the result as small as possible
# by removing unused code (gc-sections)
# and by removing macsbug function names on 68K
# (don't do this when debugging...)
# by removing unused code (gc-sections)
# and by removing macsbug function names on 68K
# (don't do this when debugging...)
set_target_properties(HelloWorld PROPERTIES COMPILE_OPTIONS -ffunction-sections)
if(CMAKE_SYSTEM_NAME MATCHES Retro68)
set_target_properties(HelloWorld PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-strip-macsbug")
set_target_properties(HelloWorld PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-strip-macsbug")
else()
set_target_properties(HelloWorld PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
set_target_properties(HelloWorld PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
endif()
+16 -16
View File
@@ -1,28 +1,28 @@
/*
Copyright 2014 Wolfgang Thaller.
Copyright 2014 Wolfgang Thaller.
This file is part of Retro68.
This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello, world.\n");
printf("\n(Press Return)\n");
getchar();
return 0;
printf("Hello, world.\n");
printf("\n(Press Return)\n");
getchar();
return 0;
}
+1 -1
View File
@@ -2,4 +2,4 @@ set(CMAKE_C_FLAGS "-Wno-multichar")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-gc-sections")
add_application(Launcher
FILES Launcher.c CONSOLE)
FILES Launcher.c CONSOLE)
+113 -113
View File
@@ -1,20 +1,20 @@
/*
Copyright 2014 Wolfgang Thaller.
Copyright 2014 Wolfgang Thaller.
This file is part of Retro68.
This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
@@ -28,124 +28,124 @@
void Explain()
{
printf("*********************************************************\n");
printf("This program is intended to make developing software\n");
printf("using Retro68K and Mini vMac a little more convenient.\n");
printf("\n");
printf("If you insert a disk that contains a single application\n");
printf("(= drag a disk image created by Retro68K to this window),\n");
printf("the application will be automatically launched and the\n");
printf("disk image unmounted again afterwards.\n");
printf("\n");
printf("It just saves a few repetitive clicks.\n");
printf("*********************************************************\n");
printf("*********************************************************\n");
printf("This program is intended to make developing software\n");
printf("using Retro68K and Mini vMac a little more convenient.\n");
printf("\n");
printf("If you insert a disk that contains a single application\n");
printf("(= drag a disk image created by Retro68K to this window),\n");
printf("the application will be automatically launched and the\n");
printf("disk image unmounted again afterwards.\n");
printf("\n");
printf("It just saves a few repetitive clicks.\n");
printf("*********************************************************\n");
}
void EjectOldDisk()
{
Handle h = GetResource('LNCH', 128);
if(h)
{
short refNum = **(short**)h;
printf("Ejecting disk (refNum = %d)\n", (int)refNum);
Handle h = GetResource('LNCH', 128);
if(h)
{
short refNum = **(short**)h;
printf("Ejecting disk (refNum = %d)\n", (int)refNum);
Eject(NULL, refNum);
UnmountVol(NULL, refNum);
RemoveResource(h);
}
Eject(NULL, refNum);
UnmountVol(NULL, refNum);
RemoveResource(h);
}
}
int main()
{
Explain();
EjectOldDisk();
printf("Insert a disk or hit any key to abort.\n");
Explain();
EjectOldDisk();
printf("Insert a disk or hit any key to abort.\n");
FlushEvents(everyEvent, 0);
FlushEvents(everyEvent, 0);
for(;;)
{
EventRecord e;
GetNextEvent(everyEvent, &e);
for(;;)
{
EventRecord e;
GetNextEvent(everyEvent, &e);
switch(e.what)
{
case keyDown:
return 0;
break;
switch(e.what)
{
case keyDown:
return 0;
break;
case diskEvt:
{
short refNum = LoWord(e.message);
short err = HiWord(e.message);
printf("Disk Inserted (refNum = %d, error = %d)\n", refNum, err);
if(err == 0)
{
{
Handle h = NewHandle(2);
**(short**)h = refNum;
AddResource(h, 'LNCH', 128, "");
}
SetVol(NULL, refNum);
case diskEvt:
{
short refNum = LoWord(e.message);
short err = HiWord(e.message);
printf("Disk Inserted (refNum = %d, error = %d)\n", refNum, err);
if(err == 0)
{
{
Handle h = NewHandle(2);
**(short**)h = refNum;
AddResource(h, 'LNCH', 128, "");
}
SetVol(NULL, refNum);
CInfoPBRec cpb;
unsigned char name[257];
int i, nApps = 0;
unsigned char bestName[257];
for(i = 1;; i++)
{
memset(&cpb, 0, sizeof(cpb));
cpb.dirInfo.ioVRefNum = refNum;
cpb.dirInfo.ioFDirIndex = i;
cpb.dirInfo.ioNamePtr = name;
err = PBGetCatInfoSync(&cpb);
CInfoPBRec cpb;
unsigned char name[257];
int i, nApps = 0;
unsigned char bestName[257];
for(i = 1;; i++)
{
memset(&cpb, 0, sizeof(cpb));
cpb.dirInfo.ioVRefNum = refNum;
cpb.dirInfo.ioFDirIndex = i;
cpb.dirInfo.ioNamePtr = name;
err = PBGetCatInfoSync(&cpb);
if(err != noErr)
break;
if(err != noErr)
break;
name[name[0]+1] = 0;
if(cpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
{
printf("Application: %s\n", &name[1]);
memcpy(bestName, name, sizeof(bestName));
++nApps;
}
}
name[name[0]+1] = 0;
if(cpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
{
printf("Application: %s\n", &name[1]);
memcpy(bestName, name, sizeof(bestName));
++nApps;
}
}
if(nApps == 0)
{
printf("No applications found on disk.\n");
EjectOldDisk();
}
else if(nApps > 1)
{
printf("Multiple applications found on disk.\n");
EjectOldDisk();
}
else
{
LaunchParamBlockRec lpb;
memset(&lpb, 0, sizeof(lpb));
if(nApps == 0)
{
printf("No applications found on disk.\n");
EjectOldDisk();
}
else if(nApps > 1)
{
printf("Multiple applications found on disk.\n");
EjectOldDisk();
}
else
{
LaunchParamBlockRec lpb;
memset(&lpb, 0, sizeof(lpb));
lpb.reserved1 = (unsigned long) bestName;
lpb.reserved2 = 0;
lpb.launchBlockID = extendedBlock;
lpb.launchEPBLength = 6;
lpb.launchFileFlags = 0;
lpb.launchControlFlags = 0xC000;
lpb.reserved1 = (unsigned long) bestName;
lpb.reserved2 = 0;
lpb.launchBlockID = extendedBlock;
lpb.launchEPBLength = 6;
lpb.launchFileFlags = 0;
lpb.launchControlFlags = 0xC000;
printf("Launching...\n");
err = LaunchApplication(&lpb);
printf("Still here after launch (err = %d). Press Enter to exit.\n", (int)err);
getchar();
return 0;
}
}
else
Eject(NULL, refNum);
}
break;
}
}
return 0;
printf("Launching...\n");
err = LaunchApplication(&lpb);
printf("Still here after launch (err = %d). Press Enter to exit.\n", (int)err);
getchar();
return 0;
}
}
else
Eject(NULL, refNum);
}
break;
}
}
return 0;
}
+13 -13
View File
@@ -1,20 +1,20 @@
/*
Copyright 2018 Wolfgang Thaller.
Copyright 2018 Wolfgang Thaller.
This file is part of Retro68.
This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -173,7 +173,7 @@ void *__dso_handle = &__dso_handle;
void _start()
{
RETRO68_RELOCATE();
RETRO68_RELOCATE();
if(setjmp(exit_buf))
;
+29 -29
View File
@@ -1,19 +1,19 @@
# Copyright 2014 Wolfgang Thaller.
# Copyright 2014 Wolfgang Thaller.
#
# This file is part of Retro68.
# This file is part of Retro68.
#
# Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>.
# To use this example as a standalone project using CMake:
# mkdir build
@@ -22,27 +22,27 @@
# make
if(APPLE)
add_executable(Raytracer MACOSX_BUNDLE
raytracer.c
)
add_executable(Raytracer2 MACOSX_BUNDLE
raytracer2.cc
fixed.h
fixed.cc
)
add_executable(Raytracer MACOSX_BUNDLE
raytracer.c
)
add_executable(Raytracer2 MACOSX_BUNDLE
raytracer2.cc
fixed.h
fixed.cc
)
target_link_libraries(Raytracer "-framework Carbon")
target_link_libraries(Raytracer2 "-framework Carbon")
target_link_libraries(Raytracer "-framework Carbon")
target_link_libraries(Raytracer2 "-framework Carbon")
else()
add_application(Raytracer
raytracer.c
)
add_application(Raytracer
raytracer.c
)
target_link_libraries(Raytracer "-lm")
add_application(Raytracer2
raytracer2.cc
fixed.h
fixed.cc
add_application(Raytracer2
raytracer2.cc
fixed.h
fixed.cc
)
add_application(FixedBenchmark CONSOLE
+20 -20
View File
@@ -23,26 +23,26 @@ long fixed::nMul = 0, fixed::nIMul = 0, fixed::nDiv = 0, fixed::nSqrt = 0;
fixed sqrt(fixed f)
{
COUNT_OP(fixed::nSqrt);
COUNT_OP(fixed::nSqrt);
const int FRACBITS = 16; /* Must be even! */
const int ITERS = 15 + (FRACBITS >> 1);
unsigned long root, remHi, remLo, testDiv, count;
root = 0; /* Clear root */
remHi = 0; /* Clear high part of partial remainder */
remLo = f.val; /* Get argument into low part of partial remainder */
count = ITERS; /* Load loop counter */
do {
remHi = (remHi << 2) | (remLo >> 30); remLo <<= 2; /* get 2 bits of arg */
root <<= 1; /* Get ready for the next bit in the root */
testDiv = (root << 1) + 1; /* Test radical */
if (remHi >= testDiv) {
remHi -= testDiv;
root += 1;
}
} while (count-- != 0);
const int FRACBITS = 16; /* Must be even! */
const int ITERS = 15 + (FRACBITS >> 1);
unsigned long root, remHi, remLo, testDiv, count;
root = 0; /* Clear root */
remHi = 0; /* Clear high part of partial remainder */
remLo = f.val; /* Get argument into low part of partial remainder */
count = ITERS; /* Load loop counter */
do {
remHi = (remHi << 2) | (remLo >> 30); remLo <<= 2; /* get 2 bits of arg */
root <<= 1; /* Get ready for the next bit in the root */
testDiv = (root << 1) + 1; /* Test radical */
if (remHi >= testDiv) {
remHi -= testDiv;
root += 1;
}
} while (count-- != 0);
return fixed(root, fixed::raw());
return fixed(root, fixed::raw());
}
+67 -67
View File
@@ -24,30 +24,30 @@
inline std::int32_t muls(std::int16_t x, std::int16_t y)
{
return (std::int32_t)x*y;
return (std::int32_t)x*y;
}
inline std::uint32_t mulu(std::uint16_t x, std::uint16_t y)
{
#if TARGET_CPU_M68K
std::uint32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
return res;
std::uint32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
return res;
#else
return (std::uint32_t)x * y;
return (std::uint32_t)x * y;
#endif
}
inline std::int32_t mulsu(std::int16_t x, std::uint16_t y)
{
#if TARGET_CPU_M68K
std::int32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
if(x < 0)
res -= ((std::uint32_t)y) << 16;
return res;
std::int32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
if(x < 0)
res -= ((std::uint32_t)y) << 16;
return res;
#else
return (std::int32_t)x * (std::uint32_t)y;
return (std::int32_t)x * (std::uint32_t)y;
#endif
}
@@ -55,71 +55,71 @@ inline std::int32_t mulsu(std::int16_t x, std::uint16_t y)
class fixed
{
std::int32_t val;
std::int32_t val;
public:
class raw {};
fixed(std::int32_t val, raw r) : val(val) {}
fixed() : val(0) {}
fixed(int x) : val((long)x << 16) {}
fixed(float f) : val(f * 65536) {}
//operator int() { return val >> 16; }
fixed operator+(fixed o) const { return fixed(val + o.val, raw()); }
fixed operator-(fixed o) const { return fixed(val - o.val, raw()); }
fixed operator*(fixed o) const {
COUNT_OP(nMul);
//return fixed((static_cast<long long>(val) * o.val) >> 16, raw());
int16_t a = val >> 16;
int16_t c = o.val >> 16;
class raw {};
fixed(std::int32_t val, raw r) : val(val) {}
fixed() : val(0) {}
fixed(int x) : val((long)x << 16) {}
fixed(float f) : val(f * 65536) {}
//operator int() { return val >> 16; }
fixed operator+(fixed o) const { return fixed(val + o.val, raw()); }
fixed operator-(fixed o) const { return fixed(val - o.val, raw()); }
fixed operator*(fixed o) const {
COUNT_OP(nMul);
//return fixed((static_cast<long long>(val) * o.val) >> 16, raw());
int16_t a = val >> 16;
int16_t c = o.val >> 16;
uint16_t b = val;
uint16_t d = o.val;
uint16_t b = val;
uint16_t d = o.val;
return fixed(((a*c) << 16)
+ mulsu(a,d) + mulsu(c,b)
+ (mulu(b,d) >> 16),raw());
}
fixed operator/(fixed o) const { COUNT_OP(nDiv); return fixed((static_cast<long long>(val) << 16) / o.val, raw()); }
fixed operator-() const { return fixed(-val, raw()); }
fixed& operator+=(fixed o) { val += o.val; return *this; }
fixed& operator-=(fixed o) { val -= o.val; return *this; }
fixed& operator*=(fixed o) { return (*this = *this * o); }
bool operator== (fixed o) const { return val == o.val; }
bool operator!= (fixed o) const { return val != o.val; }
bool operator> (fixed o) const { return val > o.val; }
bool operator< (fixed o) const { return val < o.val; }
bool operator>= (fixed o) const { return val >= o.val; }
bool operator<= (fixed o) const { return val <= o.val; }
friend fixed sqrt(fixed f);
friend fixed floor(fixed f);
friend fixed operator*(fixed f, int x);
friend fixed operator*(int x, fixed f);
friend int floor_to_int(fixed f);
static long nMul;
static long nIMul;
static long nDiv;
static long nSqrt;
return fixed(((a*c) << 16)
+ mulsu(a,d) + mulsu(c,b)
+ (mulu(b,d) >> 16),raw());
}
fixed operator/(fixed o) const { COUNT_OP(nDiv); return fixed((static_cast<long long>(val) << 16) / o.val, raw()); }
fixed operator-() const { return fixed(-val, raw()); }
fixed& operator+=(fixed o) { val += o.val; return *this; }
fixed& operator-=(fixed o) { val -= o.val; return *this; }
fixed& operator*=(fixed o) { return (*this = *this * o); }
bool operator== (fixed o) const { return val == o.val; }
bool operator!= (fixed o) const { return val != o.val; }
bool operator> (fixed o) const { return val > o.val; }
bool operator< (fixed o) const { return val < o.val; }
bool operator>= (fixed o) const { return val >= o.val; }
bool operator<= (fixed o) const { return val <= o.val; }
friend fixed sqrt(fixed f);
friend fixed floor(fixed f);
friend fixed operator*(fixed f, int x);
friend fixed operator*(int x, fixed f);
friend int floor_to_int(fixed f);
static long nMul;
static long nIMul;
static long nDiv;
static long nSqrt;
};
/*fixed operator*(fixed f, int x) { return fixed(f.val * x, fixed::raw()); }
fixed operator*(int x, fixed f) { return fixed(f.val * x, fixed::raw()); }*/
inline fixed operator*(fixed f, int c)
{
std::int16_t a = f.val >> 16;
std::int16_t a = f.val >> 16;
std::uint16_t b = f.val;
std::uint16_t b = f.val;
COUNT_OP(fixed::nIMul);
return fixed(((a*c) << 16)
+ mulsu(c,b),fixed::raw());
COUNT_OP(fixed::nIMul);
return fixed(((a*c) << 16)
+ mulsu(c,b),fixed::raw());
}
inline fixed operator*(int x, fixed f) { return f*x; }
@@ -132,12 +132,12 @@ fixed sqrt(fixed f);
inline fixed floor(fixed f)
{
return fixed(f.val & 0xFFFF0000L, fixed::raw());
return fixed(f.val & 0xFFFF0000L, fixed::raw());
}
inline int floor_to_int(fixed f)
{
return f.val >> 16;
return f.val >> 16;
}
#endif // FIXED_H
+73 -73
View File
@@ -1,20 +1,20 @@
/*
Copyright 2014 Wolfgang Thaller.
Copyright 2014 Wolfgang Thaller.
This file is part of Retro68.
This file is part of Retro68.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Retro68 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
@@ -31,81 +31,81 @@ using std::sqrt;
class timer
{
long t;
long t;
public:
timer() : t(TickCount()) {}
float elapsed() { return (TickCount() - t) / 60.15f; }
timer() : t(TickCount()) {}
float elapsed() { return (TickCount() - t) / 60.15f; }
};
template<class number>
void runTests(std::string type, std::vector<number>& numbers)
{
std::cout << "***********************************\n";
std::cout << "Running tests on type " << type << ":\n";
std::cout << "***********************************\n";
std::cout << "***********************************\n";
std::cout << "Running tests on type " << type << ":\n";
std::cout << "***********************************\n";
int n = numbers.size();
std::vector<number> outputs(n);
int n = numbers.size();
std::vector<number> outputs(n);
std::cout << "Testing Multiplication..." << std::flush;
{
timer t;
for(int i = 0; i < n; i++)
{
outputs[i] = numbers[i] * numbers[n - i - 1];
}
std::cout << 1000 * t.elapsed() / n << "ms\n";
}
std::cout << "Testing Multiplication..." << std::flush;
{
timer t;
for(int i = 0; i < n; i++)
{
outputs[i] = numbers[i] * numbers[n - i - 1];
}
std::cout << 1000 * t.elapsed() / n << "ms\n";
}
std::cout << "Testing Division..." << std::flush;
{
timer t;
for(int i = 0; i < n; i++)
{
outputs[i] = numbers[i] / numbers[n - i - 1];
}
std::cout << 1000 * t.elapsed() / n << "ms\n";
}
std::cout << "Testing Division..." << std::flush;
{
timer t;
for(int i = 0; i < n; i++)
{
outputs[i] = numbers[i] / numbers[n - i - 1];
}
std::cout << 1000 * t.elapsed() / n << "ms\n";
}
std::cout << "Testing Square Root..." << std::flush;
{
timer t;
for(int i = 0; i < n; i++)
{
outputs[i] = sqrt(numbers[i]);
}
std::cout << 1000 * t.elapsed() / n << "ms\n";
}
std::cout << std::endl;
std::cout << "Testing Square Root..." << std::flush;
{
timer t;
for(int i = 0; i < n; i++)
{
outputs[i] = sqrt(numbers[i]);
}
std::cout << 1000 * t.elapsed() / n << "ms\n";
}
std::cout << std::endl;
}
int main(int argc, char** argv)
{
std::cout << "Hello, world.\n";
std::cout << "Generating numbers..." << std::flush;
const size_t n = 1000;
std::vector<fixed> numbers(n);
std::vector<float> floats(n);
std::vector<double> doubles(n);
std::cout << "Hello, world.\n";
std::cout << "Generating numbers..." << std::flush;
const size_t n = 1000;
std::vector<fixed> numbers(n);
std::vector<float> floats(n);
std::vector<double> doubles(n);
for(size_t i = 0; i < numbers.size(); i++)
{
numbers[i] = fixed(std::rand(), fixed::raw());
floats[i] = float(std::rand()) / RAND_MAX;
doubles[i] = double(std::rand()) / RAND_MAX;
}
std::vector<fixed> outputs(n);
std::cout << "done.\n\n";
runTests("float", floats);
runTests("double", doubles);
runTests("fixed", numbers);
for(size_t i = 0; i < numbers.size(); i++)
{
numbers[i] = fixed(std::rand(), fixed::raw());
floats[i] = float(std::rand()) / RAND_MAX;
doubles[i] = double(std::rand()) / RAND_MAX;
}
std::vector<fixed> outputs(n);
std::cout << "done.\n\n";
runTests("float", floats);
runTests("double", doubles);
runTests("fixed", numbers);
std::cout << "Press Enter to Exit ;-)\n";
std::cin.get();
return 0;
std::cout << "Press Enter to Exit ;-)\n";
std::cin.get();
return 0;
}
+203 -203
View File
@@ -1,5 +1,5 @@
/*
Copyright 2014 Wolfgang Thaller.
Copyright 2014 Wolfgang Thaller.
This file is part of Retro68.
@@ -44,30 +44,30 @@
pascal /* <- pascal calling convention, for no reason in particular except to test the comppiler */
bool hitSphere(float x0, float y0, float z0, float dx, float dy, float dz, float *t)
{
const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f;
float x0c = x0 - xc;
float y0c = y0 - yc;
float z0c = z0 - zc;
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
float a = dx*dx + dy*dy + dz*dz;
float b = 2*(x0c*dx + y0c*dy + z0c*dz);
float c = x0c*x0c + y0c*y0c + z0c*z0c -r*r;
float D = b*b - 4 * a * c;
if(D >= 0)
{
*t = (-b - sqrtf(D)) / (2*a);
return *t >= 0;
}
return false;
const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f;
float x0c = x0 - xc;
float y0c = y0 - yc;
float z0c = z0 - zc;
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
float a = dx*dx + dy*dy + dz*dz;
float b = 2*(x0c*dx + y0c*dy + z0c*dz);
float c = x0c*x0c + y0c*y0c + z0c*z0c -r*r;
float D = b*b - 4 * a * c;
if(D >= 0)
{
*t = (-b - sqrtf(D)) / (2*a);
return *t >= 0;
}
return false;
}
const float lx = -2, ly = 4, lz = 3;
float lenl;
@@ -75,210 +75,210 @@ float lxn, lyn, lzn;
float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz)
{
{
const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f;
float x0c = x0 - xc;
float y0c = y0 - yc;
float z0c = z0 - zc;
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
float a = dx*dx + dy*dy + dz*dz;
float b = 2*(x0c*dx + y0c*dy + z0c*dz);
float c = x0c*x0c + y0c*y0c + z0c*z0c -r*r;
float D = b*b - 4 * a * c;
if(D >= 0)
{
float t = (-b - sqrtf(D)) / (2*a);
if(t > 0)
{
float x = x0 + dx * t;
float y = y0 + dy * t;
float z = z0 + dz * t;
float dx2 = x - xc;
float dy2 = y - yc;
float dz2 = z - zc;
float l = dx2 * dx + dy2 * dy + dz2 * dz;
l *= 2;
float reflected;
if(n)
reflected = ray(n-1, x,y,z, dx - l*dx2, dy - l*dy2, dz - l*dz2);
else
reflected = 0.0f;
float lambert = dx2 * lxn + dy2 * lyn + dz2 * lzn;
if(lambert < 0.0f)
lambert = 0.0f;
return 0.2f + 0.4f * lambert + 0.4f * reflected;
}
}
}
{
const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f;
float x0c = x0 - xc;
float y0c = y0 - yc;
float z0c = z0 - zc;
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
float a = dx*dx + dy*dy + dz*dz;
float b = 2*(x0c*dx + y0c*dy + z0c*dz);
float c = x0c*x0c + y0c*y0c + z0c*z0c -r*r;
float D = b*b - 4 * a * c;
if(D >= 0)
{
float t = (-b - sqrtf(D)) / (2*a);
if(t > 0)
{
float x = x0 + dx * t;
float y = y0 + dy * t;
float z = z0 + dz * t;
float dx2 = x - xc;
float dy2 = y - yc;
float dz2 = z - zc;
float l = dx2 * dx + dy2 * dy + dz2 * dz;
l *= 2;
float reflected;
if(n)
reflected = ray(n-1, x,y,z, dx - l*dx2, dy - l*dy2, dz - l*dz2);
else
reflected = 0.0f;
float lambert = dx2 * lxn + dy2 * lyn + dz2 * lzn;
if(lambert < 0.0f)
lambert = 0.0f;
return 0.2f + 0.4f * lambert + 0.4f * reflected;
}
}
}
if(dy < 0)
{
float t = (-1.5f - y0) / dy;
float x = x0 + dx * t;
float z = z0 + dz * t;
float color;
if( ((int)( floorf(x) )
+ (int)( floorf(z) )) % 2 )
color = 0.8f;
else
color = 0.1f;
float ts;
if(hitSphere(x,-1.5f,z, lxn, lyn, lzn, &ts))
color *= 0.2f;
float v = color + 0.5f * ray(n-1, x,-1.5f,z,dx,-dy,dz);
if(v > 1.0f)
return 1.0f;
else
return v;
}
float v = dy * 0.3f;
if(v < 0.0f)
return 0.0f;
else
return v;
if(dy < 0)
{
float t = (-1.5f - y0) / dy;
float x = x0 + dx * t;
float z = z0 + dz * t;
float color;
if( ((int)( floorf(x) )
+ (int)( floorf(z) )) % 2 )
color = 0.8f;
else
color = 0.1f;
float ts;
if(hitSphere(x,-1.5f,z, lxn, lyn, lzn, &ts))
color *= 0.2f;
float v = color + 0.5f * ray(n-1, x,-1.5f,z,dx,-dy,dz);
if(v > 1.0f)
return 1.0f;
else
return v;
}
float v = dy * 0.3f;
if(v < 0.0f)
return 0.0f;
else
return v;
}
int main()
{
WindowPtr win;
WindowPtr win;
#if !TARGET_API_MAC_CARBON
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
Rect r = qd.screenBits.bounds;
Rect r = qd.screenBits.bounds;
#else
BitMap bm;
GetQDGlobalsScreenBits(&bm);
Rect r = bm.bounds;
BitMap bm;
GetQDGlobalsScreenBits(&bm);
Rect r = bm.bounds;
#endif
SetRect(&r, r.left + 5, r.top + 45, r.right - 5, r.bottom -5);
win = NewWindow(NULL, &r, "\pRaytracer (C Version)", true, 0, (WindowPtr)-1, false, 0);
win = NewWindow(NULL, &r, "\pRaytracer (C Version)", true, 0, (WindowPtr)-1, false, 0);
#if !TARGET_API_MAC_CARBON
SetPort(win);
r = win->portRect;
#if !TARGET_API_MAC_CARBON
SetPort(win);
r = win->portRect;
#else
SetPortWindowPort(win);
GetPortBounds(GetWindowPort(win), &r);
SetPortWindowPort(win);
GetPortBounds(GetWindowPort(win), &r);
#endif
EraseRect(&r);
float accum = 0.0f;
short cx = r.right /2;
short cy = r.bottom / 2;
int x,y;
float accum = 0.0f;
short cx = r.right /2;
short cy = r.bottom / 2;
int x,y;
lenl = 1.0f / sqrtf(lx*lx + ly*ly + lz*lz);
lxn = lx*lenl, lyn = ly*lenl, lzn = lz*lenl;
lenl = 1.0f / sqrtf(lx*lx + ly*ly + lz*lz);
lxn = lx*lenl, lyn = ly*lenl, lzn = lz*lenl;
long startTime = TickCount();
float *accumV = (float*)NewPtrClear(sizeof(float) * r.right);
for(y = 0; y < r.bottom; y++)
{
for(x = 0; x < r.right; x++)
{
float pixel;
// cam = (0,0,0)
// ray = t * (x-r.right/2, - (y-r.bottom/2), -1)
// plane: y = -2
float dx = x - cx;
float dy = - (y - cy);
float dz = -cx;
float n1 = 1.0f / sqrtf(dx*dx + dy*dy + dz*dz);
pixel = ray(1,0,0,0,n1*dx,n1*dy,n1*dz);
long startTime = TickCount();
float *accumV = (float*)NewPtrClear(sizeof(float) * r.right);
for(y = 0; y < r.bottom; y++)
{
for(x = 0; x < r.right; x++)
{
float pixel;
// cam = (0,0,0)
// ray = t * (x-r.right/2, - (y-r.bottom/2), -1)
// plane: y = -2
float dx = x - cx;
float dy = - (y - cy);
float dz = -cx;
float n1 = 1.0f / sqrtf(dx*dx + dy*dy + dz*dz);
pixel = ray(1,0,0,0,n1*dx,n1*dy,n1*dz);
#if 0
accum += pixel;
if(accum >= 0.5f)
accum -= 1.0f;
else
{
MoveTo(x,y);
Line(0,0);
}
accum += pixel;
if(accum >= 0.5f)
accum -= 1.0f;
else
{
MoveTo(x,y);
Line(0,0);
}
#elif 0
accum += pixel;
accum += accumV[x];
if(accum >= 0.5f)
accum -= 1.0f;
else
{
MoveTo(x,y);
Line(0,0);
}
accumV[x] = accum = accum / 2;
#elif 0
//if(pixel < Random() / 32767.0)
if(pixel < (float)std::rand() / (32767.0f * 65536.0f))
{
MoveTo(x,y);
Line(0,0);
}
accum += pixel;
accum += accumV[x];
if(accum >= 0.5f)
accum -= 1.0f;
else
{
MoveTo(x,y);
Line(0,0);
}
accumV[x] = accum = accum / 2;
#elif 0
//if(pixel < Random() / 32767.0)
if(pixel < (float)std::rand() / (32767.0f * 65536.0f))
{
MoveTo(x,y);
Line(0,0);
}
#else
float thresh = (float)rand() / (32767.0f * 65536.0f);
thresh = 0.5f + 0.4f * (thresh - 0.5f);
accum += pixel;
accum += accumV[x];
if(accum >= thresh)
accum -= 1.0f;
else
{
MoveTo(x,y);
Line(0,0);
}
accumV[x] = accum = accum / 2;
float thresh = (float)rand() / (32767.0f * 65536.0f);
thresh = 0.5f + 0.4f * (thresh - 0.5f);
accum += pixel;
accum += accumV[x];
if(accum >= thresh)
accum -= 1.0f;
else
{
MoveTo(x,y);
Line(0,0);
}
accumV[x] = accum = accum / 2;
#endif
}
if(Button())
return 0;
}
if(Button())
return 0;
#if TARGET_API_MAC_CARBON
QDFlushPortBuffer(GetWindowPort(win),NULL);
QDFlushPortBuffer(GetWindowPort(win),NULL);
#endif
}
long endTime = TickCount();
Str255 pstr;
NumToString( (long)( (float)r.right * r.bottom / (endTime - startTime) * 60.0f ),
pstr );
SetRect(&r, 10, 10, 10 + StringWidth("\ppps = ") + StringWidth(pstr) + 10, 30);
PaintRect(&r);
PenMode(patXor);
FrameRect(&r);
MoveTo(15,25);
TextMode(srcBic);
DrawString("\ppps = ");
DrawString(pstr);
}
long endTime = TickCount();
Str255 pstr;
NumToString( (long)( (float)r.right * r.bottom / (endTime - startTime) * 60.0f ),
pstr );
SetRect(&r, 10, 10, 10 + StringWidth("\ppps = ") + StringWidth(pstr) + 10, 30);
PaintRect(&r);
PenMode(patXor);
FrameRect(&r);
MoveTo(15,25);
TextMode(srcBic);
DrawString("\ppps = ");
DrawString(pstr);
#if TARGET_API_MAC_CARBON
QDFlushPortBuffer(GetWindowPort(win),NULL);
QDFlushPortBuffer(GetWindowPort(win),NULL);
#endif
while(!Button())
;
FlushEvents(everyEvent, -1);
return 0;
while(!Button())
;
FlushEvents(everyEvent, -1);
return 0;
}
+207 -207
View File
@@ -52,69 +52,69 @@ using std::floor;
inline int floor_to_int(float f)
{
return static_cast<int>(std::floor(f));
return static_cast<int>(std::floor(f));
}
template<class T>
class vec3
{
public:
T x,y,z;
vec3(T x, T y, T z) : x(x), y(y), z(z) {}
vec3() : x(0), y(0), z(0) {}
vec3<T> operator+(const vec3<T>& other) const { return vec3(x + other.x, y + other.y, z + other.z); }
vec3<T> operator-(const vec3<T>& other) const { return vec3(x - other.x, y - other.y, z - other.z); }
vec3<T> operator*(T a) const { return vec3(x*a, y*a, z*a); }
T length() const { return sqrt(x*x + y*y + z*z); }
T operator*(const vec3<T>& other) const { return x*other.x + y*other.y + z*other.z; }
T x,y,z;
vec3(T x, T y, T z) : x(x), y(y), z(z) {}
vec3() : x(0), y(0), z(0) {}
vec3<T> operator+(const vec3<T>& other) const { return vec3(x + other.x, y + other.y, z + other.z); }
vec3<T> operator-(const vec3<T>& other) const { return vec3(x - other.x, y - other.y, z - other.z); }
vec3<T> operator*(T a) const { return vec3(x*a, y*a, z*a); }
T length() const { return sqrt(x*x + y*y + z*z); }
T operator*(const vec3<T>& other) const { return x*other.x + y*other.y + z*other.z; }
#if 1
vec3<T> normalize() const {
T l = length();
//if(l == 0)
// return *this;
//else
return (*this) * (T(1) / l);
}
vec3<T> normalize() const {
T l = length();
//if(l == 0)
// return *this;
//else
return (*this) * (T(1) / l);
}
#else
vec3<T> normalize() const {
T l = length();
if(l == 0)
return *this;
else
return vec3<T>(x/l, y/l, z/l);
}
vec3<T> normalize() const {
T l = length();
if(l == 0)
return *this;
else
return vec3<T>(x/l, y/l, z/l);
}
#endif
};
template<class T>
bool hitSphere(vec3<T> p0, vec3<T> dir, T& t)
{
const vec3<T> center(0.0f, 1.0f, -6.0f);
const T r = 2.0f;
vec3<T> p0c(p0 - center);
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
T a = dir*dir;
T b = 2*(p0c*dir);
T c = p0c*p0c - r*r;
T D = b*b - 4 * a * c;
if(D >= 0)
{
t = (-b - sqrt(D)) / (2*a);
return t >= 0;
}
return false;
const vec3<T> center(0.0f, 1.0f, -6.0f);
const T r = 2.0f;
vec3<T> p0c(p0 - center);
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
T a = dir*dir;
T b = 2*(p0c*dir);
T c = p0c*p0c - r*r;
T D = b*b - 4 * a * c;
if(D >= 0)
{
t = (-b - sqrt(D)) / (2*a);
return t >= 0;
}
return false;
}
@@ -122,71 +122,71 @@ template<class T>
T ray(int n, vec3<T> p0, vec3<T> dir)
{
#if 1
static const vec3<T> light = vec3<T>(-2,4,3).normalize();
if(1){
const vec3<T> center(0.0f, 1.0f, -6.0f);
const T r = 2.0f;
vec3<T> p0c(p0 - center);
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
T a = dir*dir;
T b = 2*(p0c*dir);
T c = p0c*p0c - r*r;
T D = b*b - 4 * a * c;
if(D >= 0)
{
T t = (-b - sqrt(D)) / (2*a);
if(t > 0)
{
vec3<T> p = p0 + dir * t;
vec3<T> dir2 = (p - center) * (T(1)/r);
T l = dir2*dir;
T reflected;
if(n)
reflected = ray(n-1, p, dir - dir2*(l*2));
else
reflected = 0.0f;
T lambert = dir2 * light;
return T(0.2f) + T(0.4f) * std::max(T(0),lambert) + T(0.4f) * reflected;
}
}
}
static const vec3<T> light = vec3<T>(-2,4,3).normalize();
if(1){
const vec3<T> center(0.0f, 1.0f, -6.0f);
const T r = 2.0f;
vec3<T> p0c(p0 - center);
/*
(x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2;
(x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2;
x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2
(dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2
*/
T a = dir*dir;
T b = 2*(p0c*dir);
T c = p0c*p0c - r*r;
T D = b*b - 4 * a * c;
if(D >= 0)
{
T t = (-b - sqrt(D)) / (2*a);
if(t > 0)
{
vec3<T> p = p0 + dir * t;
vec3<T> dir2 = (p - center) * (T(1)/r);
T l = dir2*dir;
T reflected;
if(n)
reflected = ray(n-1, p, dir - dir2*(l*2));
else
reflected = 0.0f;
T lambert = dir2 * light;
return T(0.2f) + T(0.4f) * std::max(T(0),lambert) + T(0.4f) * reflected;
}
}
}
if(dir.y < 0)
{
T t = (T(-1.5f) - p0.y) / dir.y;
vec3<T> p = p0 + dir*t;
T color;
if( (floor_to_int(p.x)
+ floor_to_int(p.z)) % 2 )
color = 0.8f;
else
color = 0.1f;
T ts;
if(hitSphere(p, light, ts))
color *= T(0.2f);
return std::min(T(1), color + T(0.5f) * ray(n-1, p,vec3<T>(dir.x, -dir.y, dir.z)));
}
if(dir.y < 0)
{
T t = (T(-1.5f) - p0.y) / dir.y;
vec3<T> p = p0 + dir*t;
T color;
if( (floor_to_int(p.x)
+ floor_to_int(p.z)) % 2 )
color = 0.8f;
else
color = 0.1f;
T ts;
if(hitSphere(p, light, ts))
color *= T(0.2f);
return std::min(T(1), color + T(0.5f) * ray(n-1, p,vec3<T>(dir.x, -dir.y, dir.z)));
}
#endif
return std::max(T(0), dir.y * T(0.3f));
return std::max(T(0), dir.y * T(0.3f));
}
typedef fixed numtype;
@@ -195,130 +195,130 @@ typedef fixed numtype;
template<class T>
struct rand1
{
static T get()
{
return T(std::rand()) / T(32767.0f * 65536.0f);
}
static T get()
{
return T(std::rand()) / T(32767.0f * 65536.0f);
}
};
template<>
struct rand1<fixed>
{
static fixed get()
{
return fixed(std::rand() >> 15, fixed::raw());
}
static fixed get()
{
return fixed(std::rand() >> 15, fixed::raw());
}
};
int main()
{
WindowPtr win;
WindowPtr win;
#if !TARGET_API_MAC_CARBON
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
Rect r = qd.screenBits.bounds;
Rect r = qd.screenBits.bounds;
#else
BitMap bm;
GetQDGlobalsScreenBits(&bm);
Rect r = bm.bounds;
BitMap bm;
GetQDGlobalsScreenBits(&bm);
Rect r = bm.bounds;
#endif
SetRect(&r, r.left + 5, r.top + 45, r.right - 5, r.bottom -5);
win = NewWindow(NULL, &r, "\pRaytracer (C++ Version)", true, 0, (WindowPtr)-1, false, 0);
win = NewWindow(NULL, &r, "\pRaytracer (C++ Version)", true, 0, (WindowPtr)-1, false, 0);
#if !TARGET_API_MAC_CARBON
SetPort(win);
r = win->portRect;
#if !TARGET_API_MAC_CARBON
SetPort(win);
r = win->portRect;
#else
SetPortWindowPort(win);
GetPortBounds(GetWindowPort(win), &r);
SetPortWindowPort(win);
GetPortBounds(GetWindowPort(win), &r);
#endif
EraseRect(&r);
numtype accum = 0.0f;
short cx = r.right /2;
short cy = r.bottom / 2;
long startTime = TickCount();
std::vector<numtype> accumV(r.right);
BitMap line;
std::vector<unsigned char> bits(((r.right + 31) / 8) & ~0x3);
SetRect(&line.bounds, 0,0,r.right,1);
line.rowBytes = bits.size();
line.baseAddr = (char*)(&bits[0]);
numtype preRandoms[29*31];
for(int i = 0; i < 29*31; i++)
{
numtype thresh = rand1<numtype>::get();
thresh = numtype(0.5f) + numtype(0.4f) * (thresh - numtype(0.5f));
preRandoms[i] = thresh;
}
int randIdx = 0;
numtype accum = 0.0f;
short cx = r.right /2;
short cy = r.bottom / 2;
long startTime = TickCount();
std::vector<numtype> accumV(r.right);
BitMap line;
std::vector<unsigned char> bits(((r.right + 31) / 8) & ~0x3);
SetRect(&line.bounds, 0,0,r.right,1);
line.rowBytes = bits.size();
line.baseAddr = (char*)(&bits[0]);
numtype preRandoms[29*31];
for(int i = 0; i < 29*31; i++)
{
numtype thresh = rand1<numtype>::get();
thresh = numtype(0.5f) + numtype(0.4f) * (thresh - numtype(0.5f));
preRandoms[i] = thresh;
}
int randIdx = 0;
for(int y = 0; y < r.bottom; y++)
{
std::fill(bits.begin(),bits.end(), 0);
for(int x = 0; x < r.right; x++)
{
numtype pixel;
// cam = (0,0,0)
// ray = t * (x-r.right/2, - (y-r.bottom/2), -1)
// plane: y = -2
pixel = ray(1,vec3<numtype>(),vec3<numtype>(numtype(x-cx)/numtype(cx),-numtype(y-cy)/numtype(cx),-1).normalize());
for(int y = 0; y < r.bottom; y++)
{
std::fill(bits.begin(),bits.end(), 0);
for(int x = 0; x < r.right; x++)
{
numtype pixel;
// cam = (0,0,0)
// ray = t * (x-r.right/2, - (y-r.bottom/2), -1)
// plane: y = -2
pixel = ray(1,vec3<numtype>(),vec3<numtype>(numtype(x-cx)/numtype(cx),-numtype(y-cy)/numtype(cx),-1).normalize());
numtype thresh = preRandoms[randIdx++];
if(randIdx == 29*31)
randIdx = 0;
accum += pixel;
accum += accumV[x];
if(accum >= thresh)
accum -= 1;
else
{
//MoveTo(x,y);
//Line(0,0);
bits[x / 8] |= (0x80 >> (x%8));
}
accumV[x] = accum = accum / numtype(2);
}
Rect r2;
SetRect(&r2,0,y,r.right,y+1);
numtype thresh = preRandoms[randIdx++];
if(randIdx == 29*31)
randIdx = 0;
accum += pixel;
accum += accumV[x];
if(accum >= thresh)
accum -= 1;
else
{
//MoveTo(x,y);
//Line(0,0);
bits[x / 8] |= (0x80 >> (x%8));
}
accumV[x] = accum = accum / numtype(2);
}
Rect r2;
SetRect(&r2,0,y,r.right,y+1);
#if TARGET_API_MAC_CARBON
CopyBits(&line, GetPortBitMapForCopyBits(GetWindowPort(win)), &line.bounds, &r2, srcCopy, NULL);
CopyBits(&line, GetPortBitMapForCopyBits(GetWindowPort(win)), &line.bounds, &r2, srcCopy, NULL);
#else
CopyBits(&line, &win->portBits, &line.bounds, &r2, srcCopy, NULL);
CopyBits(&line, &win->portBits, &line.bounds, &r2, srcCopy, NULL);
#endif
if(Button())
return 0;
if(Button())
return 0;
#if TARGET_API_MAC_CARBON
QDFlushPortBuffer(GetWindowPort(win),NULL);
QDFlushPortBuffer(GetWindowPort(win),NULL);
#endif
}
long endTime = TickCount();
char buf[256];
unsigned char* pstr = (unsigned char*)buf;
std::sprintf(buf+1, "pps = %d %ld %ld %ld %ld", (int)( (long)r.right * r.bottom * 60 / (endTime - startTime) ),
fixed::nMul, fixed::nIMul, fixed::nDiv, fixed::nSqrt);
buf[0] = std::strlen(buf+1);
SetRect(&r, 10, 10, 10 + StringWidth(pstr) + 10, 30);
PaintRect(&r);
PenMode(patXor);
FrameRect(&r);
MoveTo(15,25);
TextMode(srcBic);
DrawString(pstr);
}
long endTime = TickCount();
char buf[256];
unsigned char* pstr = (unsigned char*)buf;
std::sprintf(buf+1, "pps = %d %ld %ld %ld %ld", (int)( (long)r.right * r.bottom * 60 / (endTime - startTime) ),
fixed::nMul, fixed::nIMul, fixed::nDiv, fixed::nSqrt);
buf[0] = std::strlen(buf+1);
SetRect(&r, 10, 10, 10 + StringWidth(pstr) + 10, 30);
PaintRect(&r);
PenMode(patXor);
FrameRect(&r);
MoveTo(15,25);
TextMode(srcBic);
DrawString(pstr);
#if TARGET_API_MAC_CARBON
QDFlushPortBuffer(GetWindowPort(win),NULL);
QDFlushPortBuffer(GetWindowPort(win),NULL);
#endif
while(!Button())
;
FlushEvents(everyEvent, -1);
return 0;
while(!Button())
;
FlushEvents(everyEvent, -1);
return 0;
}
+19 -19
View File
@@ -25,10 +25,10 @@
# Build the code resource as a regular executable
# (not using the add_application macro)
add_executable(SystemExtension
SystemExtension.c
ShowInitIcon.c
SystemExtension.r
ShowInitIcon.h)
SystemExtension.c
ShowInitIcon.c
SystemExtension.r
ShowInitIcon.h)
if(TARGET retrocrt)
# Hack: if we are building as part of the Retro68 source tree,
@@ -40,23 +40,23 @@ endif(TARGET retrocrt)
set_target_properties(SystemExtension PROPERTIES
OUTPUT_NAME SystemExtension.flt
# set a linker flag that says we want a flat piece
# of code in a data file
LINK_FLAGS -Wl,--mac-flat)
OUTPUT_NAME SystemExtension.flt
# set a linker flag that says we want a flat piece
# of code in a data file
LINK_FLAGS -Wl,--mac-flat)
# Use Rez to put it together
# Use Rez to put it together
add_custom_command(
OUTPUT SystemExtension.bin SystemExtension.dsk
COMMAND ${REZ} -I ${REZ_INCLUDE_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/SystemExtension.r
--copy ${CMAKE_CURRENT_SOURCE_DIR}/Icons.rsrc.bin
-o SystemExtension.bin
--cc SystemExtension.dsk
--cc SystemExtension
-t INIT
DEPENDS SystemExtension SystemExtension.r Icons.rsrc.bin)
OUTPUT SystemExtension.bin SystemExtension.dsk
COMMAND ${REZ} -I ${REZ_INCLUDE_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/SystemExtension.r
--copy ${CMAKE_CURRENT_SOURCE_DIR}/Icons.rsrc.bin
-o SystemExtension.bin
--cc SystemExtension.dsk
--cc SystemExtension
-t INIT
DEPENDS SystemExtension SystemExtension.r Icons.rsrc.bin)
add_custom_target(SystemExtension_INIT ALL DEPENDS SystemExtension.dsk)
+72 -72
View File
@@ -33,10 +33,10 @@
// The MPW C compiler doesn't accept variables declared at an absolute address, so I use these macros instead.
// Only one macro is defined per variable; there is no need to define a Set and a Get accessor like in <LowMem.h>.
#define LMVCheckSum (* (unsigned short*) 0x928)
#define LMVCoord (* ( short*) 0x92A)
#define LMHCoord (* ( short*) 0x92C)
#define LMHCheckSum (* (unsigned short*) 0x92E)
#define LMVCheckSum (* (unsigned short*) 0x928)
#define LMVCoord (* ( short*) 0x92A)
#define LMHCoord (* ( short*) 0x92C)
#define LMHCheckSum (* (unsigned short*) 0x92E)
// ---------------------------------------------------------------------------------------------------------------------
// Prototypes for the subroutines. The main routine comes first; this is necessary to make THINK C's "Custom Header" option work.
@@ -50,41 +50,41 @@ static void DrawBWIcon (short iconID, Rect *iconRect);
// Main routine.
typedef struct {
QDGlobals qd; // Storage for the QuickDraw globals
long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
QDGlobals qd; // Storage for the QuickDraw globals
long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
} QDStorage;
pascal void ShowInitIcon (short iconFamilyID, Boolean advance)
{
long oldA5; // Original value of register A5
QDStorage qds; // Fake QD globals
CGrafPort colorPort;
GrafPort bwPort;
Rect destRect;
SysEnvRec environment; // Machine configuration.
oldA5 = SetA5((long) &qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
SysEnvirons(curSysEnvVers, &environment); // Find out what kind of machine this is
long oldA5; // Original value of register A5
QDStorage qds; // Fake QD globals
CGrafPort colorPort;
GrafPort bwPort;
Rect destRect;
SysEnvRec environment; // Machine configuration.
oldA5 = SetA5((long) &qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
SysEnvirons(curSysEnvVers, &environment); // Find out what kind of machine this is
ComputeIconRect(&destRect, &qds.qd.screenBits.bounds); // Compute where the icon should be drawn
ComputeIconRect(&destRect, &qds.qd.screenBits.bounds); // Compute where the icon should be drawn
if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
OpenCPort(&colorPort);
PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
CloseCPort(&colorPort);
}
else {
OpenPort(&bwPort);
DrawBWIcon(iconFamilyID, &destRect);
ClosePort(&bwPort);
}
if (advance)
AdvanceIconPosition (&destRect);
SetA5(oldA5); // Restore A5 to its previous value
if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
OpenCPort(&colorPort);
PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
CloseCPort(&colorPort);
}
else {
OpenPort(&bwPort);
DrawBWIcon(iconFamilyID, &destRect);
ClosePort(&bwPort);
}
if (advance)
AdvanceIconPosition (&destRect);
SetA5(oldA5); // Restore A5 to its previous value
}
// ---------------------------------------------------------------------------------------------------------------------
@@ -92,7 +92,7 @@ pascal void ShowInitIcon (short iconFamilyID, Boolean advance)
static unsigned short CheckSum (short x)
{
return (unsigned short)(((x << 1) | (x >> 15)) ^ 0x1021);
return (unsigned short)(((x << 1) | (x >> 15)) ^ 0x1021);
}
// ---------------------------------------------------------------------------------------------------------------------
@@ -100,56 +100,56 @@ static unsigned short CheckSum (short x)
static void ComputeIconRect (Rect* iconRect, Rect* screenBounds)
{
if (CheckSum(LMHCoord) != LMHCheckSum) // If we are first, we need to initialize the shared data.
LMHCoord = 8;
if (CheckSum(LMVCoord) != LMVCheckSum)
LMVCoord = (short)(screenBounds->bottom - 40);
if (LMHCoord + 34 > screenBounds->right) { // Check whether we must wrap
iconRect->left = 8;
iconRect->top = (short)(LMVCoord - 40);
}
else {
iconRect->left = LMHCoord;
iconRect->top = LMVCoord;
}
iconRect->right = (short)(iconRect->left + 32);
iconRect->bottom = (short)(iconRect->top + 32);
if (CheckSum(LMHCoord) != LMHCheckSum) // If we are first, we need to initialize the shared data.
LMHCoord = 8;
if (CheckSum(LMVCoord) != LMVCheckSum)
LMVCoord = (short)(screenBounds->bottom - 40);
if (LMHCoord + 34 > screenBounds->right) { // Check whether we must wrap
iconRect->left = 8;
iconRect->top = (short)(LMVCoord - 40);
}
else {
iconRect->left = LMHCoord;
iconRect->top = LMVCoord;
}
iconRect->right = (short)(iconRect->left + 32);
iconRect->bottom = (short)(iconRect->top + 32);
}
// AdvanceIconPosition updates the shared global variables so that the next extension will draw its icon beside ours.
static void AdvanceIconPosition (Rect* iconRect)
{
LMHCoord = (short)(iconRect->left + 40); // Update the shared data
LMVCoord = iconRect->top;
LMHCheckSum = CheckSum(LMHCoord);
LMVCheckSum = CheckSum(LMVCoord);
LMHCoord = (short)(iconRect->left + 40); // Update the shared data
LMVCoord = iconRect->top;
LMHCheckSum = CheckSum(LMHCoord);
LMVCheckSum = CheckSum(LMVCoord);
}
// DrawBWIcon draws the 'ICN#' member of the icon family. It works under System 6.
static void DrawBWIcon (short iconID, Rect *iconRect)
{
Handle icon;
BitMap source, destination;
GrafPtr port;
icon = Get1Resource('ICN#', iconID);
if (icon != NULL) {
HLock(icon);
// Prepare the source and destination bitmaps.
source.baseAddr = *icon + 128; // Mask address.
source.rowBytes = 4;
SetRect(&source.bounds, 0, 0, 32, 32);
GetPort(&port);
destination = port->portBits;
// Transfer the mask.
CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
// Then the icon.
source.baseAddr = *icon;
CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
}
Handle icon;
BitMap source, destination;
GrafPtr port;
icon = Get1Resource('ICN#', iconID);
if (icon != NULL) {
HLock(icon);
// Prepare the source and destination bitmaps.
source.baseAddr = *icon + 128; // Mask address.
source.rowBytes = 4;
SetRect(&source.bounds, 0, 0, 32, 32);
GetPort(&port);
destination = port->portBits;
// Transfer the mask.
CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
// Then the icon.
source.baseAddr = *icon;
CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
}
}
// ---------------------------------------------------------------------------------------------------------------------
+7 -7
View File
@@ -4,13 +4,13 @@
void _start()
{
RETRO68_RELOCATE();
Retro68CallConstructors();
RETRO68_RELOCATE();
Retro68CallConstructors();
ShowInitIcon(130, false);
Delay(20, NULL);
ShowInitIcon(128, true);
Delay(40, NULL);
ShowInitIcon(130, false);
Delay(20, NULL);
ShowInitIcon(128, true);
Delay(40, NULL);
Retro68FreeGlobals();
Retro68FreeGlobals();
}
+14 -14
View File
@@ -1,19 +1,19 @@
# Copyright 2015 Wolfgang Thaller.
# Copyright 2015 Wolfgang Thaller.
#
# This file is part of Retro68.
# This file is part of Retro68.
#
# Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Retro68 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# Retro68 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License
# along with Retro68. If not, see <http://www.gnu.org/licenses/>.
# To use this example as a standalone project using CMake:
# mkdir build
@@ -78,14 +78,14 @@ add_custom_command(
# Now build the application
add_application(WDEFShell
wdefshell.c
wdefshell.c
wdefshell.r
wdef.c # the WDEF as a plain source file in the application
# the separately compiled WDEF resource
${CMAKE_CURRENT_BINARY_DIR}/WDEF.rsrc.bin
)
)
# Again, add some options to make things smaller.
set_target_properties(WDEFShell PROPERTIES COMPILE_OPTIONS -ffunction-sections)
+1 -1
View File
@@ -300,5 +300,5 @@ int main()
}
}
}
return 0;
return 0;
}