Add games to samples

This commit is contained in:
drmortalwombat 2022-01-28 22:49:15 +01:00
parent 65201f27b6
commit 5ca651bc36
15 changed files with 692 additions and 349 deletions

View File

@ -2903,7 +2903,7 @@ void InterInstruction::Disassemble(FILE* file)
}
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr),
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr)
{
mInPath = false;
@ -3288,7 +3288,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
ins->mSrc[1].mOperandSize = tvalue[ins->mSrc[1].mTemp]->mConst.mOperandSize;
ins->mSrc[1].mTemp = -1;
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_BINARY_OPERATOR)
while (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_BINARY_OPERATOR)
{
InterInstruction* iins = tvalue[ins->mSrc[0].mTemp];
if (iins->mOperator == IA_ADD)
@ -3303,6 +3303,8 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
ins->mSrc[0].mTemp = iins->mSrc[1].mTemp;
ins->mSrc[1].mIntConst += iins->mSrc[0].mIntConst;
}
else
break;
}
else if (iins->mOperator == IA_SUB)
{
@ -3311,8 +3313,11 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
ins->mSrc[0].mTemp = iins->mSrc[1].mTemp;
ins->mSrc[1].mIntConst -= iins->mSrc[0].mIntConst;
}
else
break;
}
else
break;
}
}
break;
@ -7585,16 +7590,41 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
// shorten lifespan
int loopTmp = -1;
int limit = mInstructions.Size() - 1;
if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH)
{
limit--;
if (limit > 0 && mInstructions[limit]->mCode == IC_RELATIONAL_OPERATOR)
{
if (mInstructions[limit]->mSrc[1].mTemp)
loopTmp = mInstructions[limit]->mSrc[1].mTemp;
else if (mInstructions[limit]->mSrc[0].mTemp)
loopTmp = mInstructions[limit]->mSrc[0].mTemp;
limit--;
if (limit > 0 && mInstructions[limit]->mCode == IC_BINARY_OPERATOR &&
(mInstructions[limit]->mDst.mTemp == mInstructions[limit + 1]->mSrc[0].mTemp || mInstructions[limit]->mDst.mTemp == mInstructions[limit + 1]->mSrc[1].mTemp))
limit--;
if (loopTmp >= 0)
{
int i = limit;
while (i >= 0 && !(mInstructions[i]->mCode == IC_BINARY_OPERATOR && mInstructions[i]->mDst.mTemp == loopTmp))
i--;
if (i >= 0 && i < limit)
{
InterInstruction* ins(mInstructions[i]);
int j = i;
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
{
mInstructions[j] = mInstructions[j + 1];
j++;
}
if (i != j)
mInstructions[j] = ins;
}
if (limit > 0 && mInstructions[limit]->mCode == IC_BINARY_OPERATOR && (mInstructions[limit]->mDst.mTemp == loopTmp))
limit--;
}
}
}
else if (limit >= 0 && mInstructions[limit]->mCode == IC_JUMP)

View File

@ -7397,14 +7397,14 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
case IA_CMPEQ:
case IA_CMPLEU:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
if (ins->mSrc[0].mType != IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] > 1)
mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(trueJump, falseJump, ASMIT_BEQ);
break;
case IA_CMPNE:
case IA_CMPGU:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
if (ins->mSrc[0].mType != IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] > 1)
mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(trueJump, falseJump, ASMIT_BNE);
break;
@ -7415,14 +7415,14 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
this->Close(falseJump, nullptr, ASMIT_JMP);
break;
case IA_CMPGES:
if (ins->mSrc[0].mType == IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] == 1)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt]));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(trueJump, falseJump, ASMIT_BPL);
break;
case IA_CMPLS:
if (ins->mSrc[0].mType == IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] == 1)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt]));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
@ -7431,12 +7431,12 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
case IA_CMPGS:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
if (ins->mSrc[0].mType == IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] == 1)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt]));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, falseJump, ASMIT_BPL);
if (ins->mSrc[0].mType != IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] != 1)
eblock->mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->Close(trueJump, falseJump, ASMIT_BNE);
break;
@ -7444,12 +7444,12 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
case IA_CMPLES:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
if (ins->mSrc[0].mType == IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] == 1)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt]));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, trueJump, ASMIT_BPL);
if (ins->mSrc[0].mType != IT_INT8)
if (InterTypeSize[ins->mSrc[0].mType] != 1)
eblock->mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->Close(trueJump, falseJump, ASMIT_BEQ);
break;
@ -7457,7 +7457,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
}
}
else if (ins->mSrc[0].mType == IT_INT8)
else if (InterTypeSize[ins->mSrc[0].mType] == 1)
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
NativeCodeBasicBlock* nblock = nproc->AllocateBlock();
@ -8127,7 +8127,6 @@ void NativeCodeBasicBlock::BuildGlobalProvidedRegSet(NumberSet fromProvidedRegs)
bool NativeCodeBasicBlock::BuildGlobalRequiredRegSet(NumberSet& fromRequiredRegs)
{
bool revisit = false;
int i;
if (!mVisited)
{
@ -10925,6 +10924,41 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
bool changed = false;
int sz = mIns.Size();
#if 1
if (sz > 3 &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE &&
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
{
if (mBranch == ASMIT_BCS && mIns[sz - 2].mAddress < 0xff)
{
int val = mIns[sz - 2].mAddress + 1;
mBranch = ASMIT_BCC;
mIns[sz - 2].mMode = ASMIM_ZERO_PAGE; mIns[sz - 2].mAddress = mIns[sz - 1].mAddress;
mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = val;
}
else if (mBranch == ASMIT_BCC && mIns[sz - 2].mAddress < 0xff)
{
int val = mIns[sz - 2].mAddress + 1;
mBranch = ASMIT_BCS;
mIns[sz - 2].mMode = ASMIM_ZERO_PAGE; mIns[sz - 2].mAddress = mIns[sz - 1].mAddress;
mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = val;
}
else if ((mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_C))
{
int val = mIns[sz - 2].mAddress;
mIns[sz - 2].mMode = ASMIM_ZERO_PAGE; mIns[sz - 2].mAddress = mIns[sz - 1].mAddress;
mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = val;
}
}
#endif
if (mFalseJump == this)
{
mBranch = InvertBranchCondition(mBranch);
mFalseJump = mTrueJump;
mTrueJump = this;
}
if (sz > 3 && sz < 200 && mNumEntries == 2 && mTrueJump == this)
{
bool simple = true;
@ -10937,10 +10971,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
if (simple)
{
if (mIns[sz - 3].mType == ASMIT_INC && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
if ((mIns[sz - 3].mType == ASMIT_INC || mIns[sz - 3].mType == ASMIT_DEC) && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y)) &&
mBranch == ASMIT_BCC)
(mBranch == ASMIT_BCC || mBranch == ASMIT_BCS || mBranch == ASMIT_BNE))
{
// check for usage of Y register
@ -10972,11 +11006,15 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
yother = true;
if (mIns[i].mType == ASMIT_INX || mIns[i].mType == ASMIT_DEX || mIns[i].mType == ASMIT_TAX)
if (mIns[i].mType == ASMIT_TAX)
xother = true;
else if (mIns[i].mType == ASMIT_INX)
xinc++;
else if (mIns[i].mType == ASMIT_DEX)
xinc--;
else if (mIns[i].mType == ASMIT_LDX)
{
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg && xinc >= -1 && xinc <= 1)
xindex = true;
else
xother = true;
@ -10989,7 +11027,11 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
if (!yother)
{
int linc = yinc - 1;
int linc = yinc;
if (mIns[sz - 3].mType == ASMIT_INC)
linc--;
else
linc++;
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
@ -11053,16 +11095,49 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
}
else if (!xother)
{
int linc = xinc;
if (mIns[sz - 3].mType == ASMIT_INC)
linc--;
else
linc++;
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
xinc = 0;
for (int i = 0; i + 3 < sz; i++)
{
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TXA, ASMIM_IMPLIED));
else if (mIns[i].mType != ASMIT_LDX)
else if (mIns[i].mType == ASMIT_LDX)
{
if (xinc > 0)
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEX));
else if (xinc < 0)
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INX));
xinc = 0;
}
else
{
lblock->mIns.Push(mIns[i]);
if (mIns[i].mType == ASMIT_INX)
xinc++;
else if (mIns[i].mType == ASMIT_DEX)
xinc--;
}
}
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INX, ASMIM_IMPLIED));
while (linc < 0)
{
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INX, ASMIM_IMPLIED));
linc++;
}
while (linc > 0)
{
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
linc--;
}
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPX, ASMIM_IMMEDIATE, limit));
lblock->mBranch = mBranch;
lblock->mTrueJump = lblock;

View File

@ -126,6 +126,7 @@ bool SourceFile::PushSource(void)
stack->mUp = mStack;
mStack = stack;
stack->mFilePos = ftell(mFile);
stack->mLocation = mLocation;
return true;
}
@ -134,6 +135,7 @@ bool SourceFile::PopSource(void)
SourceStack* stack = mStack;
if (stack)
{
mLocation = stack->mLocation;
fseek(mFile, stack->mFilePos, SEEK_SET);
mStack = mStack->mUp;
return true;
@ -315,8 +317,14 @@ bool Preprocessor::PushSource(void)
bool Preprocessor::PopSource(void)
{
mLocation = mSource->mLocation;
return mSource->PopSource();
if (mSource->PopSource())
{
mLocation = mSource->mLocation;
return true;
}
else
return false;
}
bool Preprocessor::DropSource(void)

View File

@ -754,7 +754,48 @@ void Scanner::NextToken(void)
NextChar();
}
else
{
while (mTokenChar == '#' && mLine[mOffset] == '#')
{
mOffset++;
NextChar();
char tkbase[256];
strcpy_s(tkbase, mTokenIdent->mString);
int n = 0;
char tkident[256];
while (IsIdentChar(mTokenChar))
{
if (n < 255)
tkident[n++] = mTokenChar;
NextChar();
}
tkident[n] = 0;
const Ident* ntkident = Ident::Unique(tkident);
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(ntkident);
if (!def)
def = mDefines->Lookup(ntkident);
if (def)
strcat_s(tkbase, def->mString);
else
strcat_s(tkbase, tkident);
n = strlen(tkbase);
while (n > 0 && tkbase[n - 1] == ' ')
n--;
tkbase[n] = 0;
mTokenIdent = Ident::Unique(tkbase);
}
return;
}
}
else
return;

View File

@ -73,7 +73,7 @@ int main(int argc, const char** argv)
#else
strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.3.70");
strcpy(strProductVersion, "1.3.72");
#ifdef __APPLE__
uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,3,70,0
PRODUCTVERSION 1,3,70,0
FILEVERSION 1,3,72,0
PRODUCTVERSION 1,3,72,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.3.70.0"
VALUE "FileVersion", "1.3.72.0"
VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.3.70.0"
VALUE "ProductVersion", "1.3.72.0"
END
END
BLOCK "VarFileInfo"

View File

@ -34,8 +34,8 @@
}
"Entry"
{
"MsmKey" = "8:_03D7013B0D39A89CEA9D267005ADCE39"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmKey" = "8:_04ABABC55200450383686DD782DD1548"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
@ -118,12 +118,6 @@
}
"Entry"
{
"MsmKey" = "8:_2CA3A525072974368303677563606FFE"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_2D828D0247F144CDB0112B2AD4004C2C"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -184,12 +178,6 @@
}
"Entry"
{
"MsmKey" = "8:_3FA71395262A4AB4A1C2839FD6B91190"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_3FFD08277B804985BDF072C0C1877287"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -238,6 +226,12 @@
}
"Entry"
{
"MsmKey" = "8:_539501D7FC4941B8AEE943A2D5C74703"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_542D20FAC6B34E318FA36AD50BF3EEBE"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -274,6 +268,12 @@
}
"Entry"
{
"MsmKey" = "8:_65286F9E8B2F496B95A50DA63A1F0D5B"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_683E44581EBB4154841523B526E1B4B4"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -298,24 +298,12 @@
}
"Entry"
{
"MsmKey" = "8:_777CE896BB0B3C09C1B5FB6CB3BFE84F"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_79985361F09A43299E258E1A8E5ED934"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_7A40466D5E5D2D3FD71213A0C0AA5075"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_7A9E700FC438425580655F7C1BC07FD3"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -334,6 +322,12 @@
}
"Entry"
{
"MsmKey" = "8:_7DC360D088E84BB5AA7B338C464439A9"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -490,12 +484,6 @@
}
"Entry"
{
"MsmKey" = "8:_B2B920A649CF4027457BBAB004078A03"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_B4265CBF352343D2867DBCCE67D9F493"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -604,6 +592,12 @@
}
"Entry"
{
"MsmKey" = "8:_D34AB6F4EE6C4E18A8C6D44CC8E23CB7"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_D76DA8C7D3964C93ABE193A7B53A0A9B"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -622,18 +616,6 @@
}
"Entry"
{
"MsmKey" = "8:_DC9FDF52011EB7C47318682BA0B3F26F"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_DE2BF7C92569053E7C3DCE88AB7E2566"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_E218D776D9014F99BE2B046AEF2D6E8B"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -688,12 +670,6 @@
}
"Entry"
{
"MsmKey" = "8:_EA3C0BCB01F2639DFA2E37EC8436E5F6"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_ED872D39D58443D590B7C80604BC0FF4"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -893,12 +869,12 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_03D7013B0D39A89CEA9D267005ADCE39"
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_04ABABC55200450383686DD782DD1548"
{
"SourcePath" = "8:VCRUNTIME140.dll"
"TargetName" = "8:VCRUNTIME140.dll"
"SourcePath" = "8:..\\samples\\games\\lander.c"
"TargetName" = "8:lander.c"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Folder" = "8:_BC04C0DDE264410096618981E4E890DA"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
@ -910,7 +886,7 @@
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_05BBBE09BC7047B6AB2F10A2E9032E37"
@ -1173,26 +1149,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2CA3A525072974368303677563606FFE"
{
"SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2D828D0247F144CDB0112B2AD4004C2C"
{
"SourcePath" = "8:..\\samples\\scrolling\\tunnel.c"
@ -1393,26 +1349,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3FA71395262A4AB4A1C2839FD6B91190"
{
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3FFD08277B804985BDF072C0C1877287"
{
"SourcePath" = "8:..\\include\\assert.c"
@ -1573,6 +1509,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_539501D7FC4941B8AEE943A2D5C74703"
{
"SourcePath" = "8:..\\samples\\games\\snake.c"
"TargetName" = "8:snake.c"
"Tag" = "8:"
"Folder" = "8:_BC04C0DDE264410096618981E4E890DA"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_542D20FAC6B34E318FA36AD50BF3EEBE"
{
"SourcePath" = "8:..\\include\\string.h"
@ -1693,6 +1649,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_65286F9E8B2F496B95A50DA63A1F0D5B"
{
"SourcePath" = "8:..\\samples\\resources\\maze3dchars.bin"
"TargetName" = "8:maze3dchars.bin"
"Tag" = "8:"
"Folder" = "8:_758C6547998745659548D0656D380FEA"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_683E44581EBB4154841523B526E1B4B4"
{
"SourcePath" = "8:..\\samples\\memmap\\make.bat"
@ -1773,26 +1749,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_777CE896BB0B3C09C1B5FB6CB3BFE84F"
{
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_79985361F09A43299E258E1A8E5ED934"
{
"SourcePath" = "8:..\\include\\gfx\\mcbitmap.c"
@ -1813,26 +1769,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7A40466D5E5D2D3FD71213A0C0AA5075"
{
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7A9E700FC438425580655F7C1BC07FD3"
{
"SourcePath" = "8:..\\samples\\rasterirq\\textcrawler.c"
@ -1893,6 +1829,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7DC360D088E84BB5AA7B338C464439A9"
{
"SourcePath" = "8:..\\samples\\games\\make.bat"
"TargetName" = "8:make.bat"
"Tag" = "8:"
"Folder" = "8:_BC04C0DDE264410096618981E4E890DA"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
{
"SourcePath" = "8:..\\samples\\kernalio\\filewrite.c"
@ -2413,26 +2369,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B2B920A649CF4027457BBAB004078A03"
{
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B4265CBF352343D2867DBCCE67D9F493"
{
"SourcePath" = "8:..\\include\\c64\\joystick.c"
@ -2793,6 +2729,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D34AB6F4EE6C4E18A8C6D44CC8E23CB7"
{
"SourcePath" = "8:..\\samples\\games\\maze3d.c"
"TargetName" = "8:maze3d.c"
"Tag" = "8:"
"Folder" = "8:_BC04C0DDE264410096618981E4E890DA"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D76DA8C7D3964C93ABE193A7B53A0A9B"
{
"SourcePath" = "8:..\\samples\\stdio\\make.bat"
@ -2853,46 +2809,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DC9FDF52011EB7C47318682BA0B3F26F"
{
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DE2BF7C92569053E7C3DCE88AB7E2566"
{
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E218D776D9014F99BE2B046AEF2D6E8B"
{
"SourcePath" = "8:..\\include\\stdlib.c"
@ -3073,26 +2989,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_EA3C0BCB01F2639DFA2E37EC8436E5F6"
{
"SourcePath" = "8:VERSION.dll"
"TargetName" = "8:VERSION.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ED872D39D58443D590B7C80604BC0FF4"
{
"SourcePath" = "8:..\\samples\\kernalio\\fileread.c"
@ -3385,6 +3281,17 @@
{
}
}
"{9EF0B969-E518-4E46-987F-47570745A589}:_BC04C0DDE264410096618981E4E890DA"
{
"Name" = "8:games"
"AlwaysCreate" = "11:FALSE"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Property" = "8:_2FC18ABE685C4EC1A2E232741074C931"
"Folders"
{
}
}
"{9EF0B969-E518-4E46-987F-47570745A589}:_BDDE04AB523C4059AABE326807998F7A"
{
"Name" = "8:fractals"
@ -3507,15 +3414,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{580E5547-0F6E-4635-B33F-06C4C70E3CB7}"
"PackageCode" = "8:{09FC216E-6C34-4C82-A15F-05B7E88D2A71}"
"ProductCode" = "8:{07197B62-14CB-4607-AF17-B93D06B4E603}"
"PackageCode" = "8:{05C9040B-AB11-4EEF-B99C-0BC6CAB578AC}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.3.70"
"ProductVersion" = "8:1.3.72"
"Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"

View File

@ -3,6 +3,10 @@ cd fractals
./build.sh
cd ..
cd games
./build.sh
cd ..
cd hires
./build.sh
cd ..

5
samples/games/build.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh
../../bin/oscar64 snake.c
../../bin/oscar64 lander.c -n
../../bin/oscar64 maze3d.c -n

View File

@ -223,15 +223,15 @@ void game_loop(void)
case GS_PLAYING:
{
// Check player input on every frame
joy_poll(0);
lander_move(&TheGame.lander, joyx[0], joyy[0]);
joy_poll(1);
lander_move(&TheGame.lander, joyx[1], joyy[1]);
LanderCollision col = lander_check(&TheGame.lander);
if (col == LCOL_GROUND)
game_state(GS_COLLIDE);
else if (col == LCOL_PAD)
game_state(GS_LANDED);
else
lander_show(&TheGame.lander, joyx[0], joyy[0]);
lander_show(&TheGame.lander, joyx[1], joyy[1]);
} break;
case GS_LANDED:
if (!--TheGame.count)

View File

@ -1,15 +1,23 @@
#include <c64/joystick.h>
#include <c64/vic.h>
#include <c64/sprites.h>
#include <c64/memmap.h>
#include <c64/rasterirq.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#define Screen ((byte *)0x0400)
#define Color ((byte *)0xd800)
// Moving the VIC into the third bank and making
// room for double buffering+
byte * const Screen0 = (byte *)0xc800;
byte * const Screen1 = (byte *)0xcc00;
byte * const Font = (byte *)0xd000;
byte * const Color = (byte *)0xd800;
byte * const Color1 = (byte *)0xc400;
// Just to get started a mini maze
static const char * maze[16] =
{
"################",
@ -30,187 +38,448 @@ static const char * maze[16] =
"################",
};
void maze_init(void)
{
// Character set including some ramps for the upper edge
char charset[2048] = {
#embed "../resources/maze3dchars.bin"
}
// Current target screen
char * DrawScreen;
static char zxdist0[] = {18, 6, 4, 3, 2, 1, 0};
static char zxdist1[] = { 9, 5, 3, 2, 1, 0, 0};
// Put one char on screen
inline void screen_put(byte x, byte y, char ch, char color)
{
__assume(y < 25);
Screen[40 * y + x] = ch;
Color[40 * y + x] = color;
}
// Get one char from screen
inline char screen_get(byte x, byte y)
{
__assume(y < 25);
return Screen[40 * y + x];
}
// Current target index
bool FlipIndex;
// Position and direction inside the maze
sbyte px = 1, py = 3, dx = 1, dy = 0;
// Distance of blocks to the side, relative to the center ot the screen
// for full and half step
static const char zxdist0[] = {18, 6, 4, 3, 2, 1, 0};
static const char zxdist1[] = { 9, 5, 3, 2, 1, 0, 0};
// Flip double buffer, copying the color ram
void screen_flip(void)
{
// Change idnex of screen
FlipIndex = !FlipIndex;
// Wait until raster beam reaches bottom
vic_waitBottom();
// Change vic start address
vic_setmode(VICM_TEXT, FlipIndex ? Screen0 : Screen1, Font);
// Copy the color ram in four chunks, to avoid
// colliding with the beam
char i = 0;
do {
Color[0x000 + i] = Color1[0x000 + i];
i++;
} while (i != 0);
do {
Color[0x100 + i] = Color1[0x100 + i];
i++;
} while (i != 0);
do {
Color[0x200 + i] = Color1[0x200 + i];
i++;
} while (i != 0);
do {
Color[0x300 + i] = Color1[0x300 + i];
i++;
} while (i != 0);
// Change target buffer for next frame
DrawScreen = FlipIndex ? Screen1 : Screen0;
}
// Rotating left or right is simulated by scrolling. For
// performance reasons, we have four different scroll routines
// due to two buffers and two directions
// Loop over the two buffers
#assign si 0
#repeat
// other buffer
#assign ri 1 - si
// pointers of the two screen buffers, from and to
#define dst Screen##si
#define src Screen##ri
// scroll left Screen0 or Screen1
void screen_left_##si(void)
{
for(char sx=0; sx<40; sx+=4)
{
// Wait for the beam to be just below the first line
vic_waitLine(58);
// Unroll for each row of screen and color ram
#assign ry 0
#repeat
// Copy one row by four chars
for(char x=0; x<36; x++)
{
dst[40 * ry + x] = dst[40 * ry + x + 4];
Color[40 * ry + x] = Color[40 * ry + x + 4];
}
// Fill in new screen and color data
dst[40 * ry + 36] = src[40 * ry + sx + 0];
dst[40 * ry + 37] = src[40 * ry + sx + 1];
dst[40 * ry + 38] = src[40 * ry + sx + 2];
dst[40 * ry + 39] = src[40 * ry + sx + 3];
Color[40 * ry + 36] = Color1[40 * ry + sx + 0];
Color[40 * ry + 37] = Color1[40 * ry + sx + 1];
Color[40 * ry + 38] = Color1[40 * ry + sx + 2];
Color[40 * ry + 39] = Color1[40 * ry + sx + 3];
// repeat for each row
#assign ry ry + 1
#until ry == 25
#undef ry
}
}
// scroll right Screen0 or Screen1
void screen_right_##si(void)
{
for(char sx=40; sx>0; sx-=4)
{
vic_waitLine(58);
#assign ry 0
#repeat
for(char x=39; x>=4; x--)
{
dst[40 * ry + x] = dst[40 * ry - 4 + x];
Color[40 * ry + x] = Color[40 * ry - 4 + x];
}
dst[40 * ry + 0] = src[40 * ry + sx - 4];
dst[40 * ry + 1] = src[40 * ry + sx - 3];
dst[40 * ry + 2] = src[40 * ry + sx - 2];
dst[40 * ry + 3] = src[40 * ry + sx - 1];
Color[40 * ry + 0] = Color1[40 * ry + sx - 4];
Color[40 * ry + 1] = Color1[40 * ry + sx - 3];
Color[40 * ry + 2] = Color1[40 * ry + sx - 2];
Color[40 * ry + 3] = Color1[40 * ry + sx - 1];
#assign ry ry + 1
#until ry == 25
#undef ry
}
}
#assign si si + 1
#until si == 2
#undef si
#undef ri
// Scroll current screen left
void screen_left(void)
{
if (FlipIndex)
screen_left_0();
else
screen_left_1();
}
// Scroll current screen right
void screen_right(void)
{
if (FlipIndex)
screen_right_0();
else
screen_right_1();
}
// Fill one color column
void color_column(char cx, char color)
{
#assign ry 0
#repeat
Color1[40 * ry + cx] = color;
#assign ry ry + 1
#until ry == 25
#undef ry
}
// Fill one screen column
void screen_column(char cx, char sx, char tc, char mc, char bc)
{
// Calculate top and bottom row
char ty = sx / 4;
char by = 25 - sx;
// Target pointer
char * dp = DrawScreen + cx;
// Check for non empty column
if (by > ty)
{
// Space above
for(char cy=0; cy<ty; cy++)
{
*dp = 126; dp += 40;
}
// Top element
*dp = tc; dp += 40;
// Wall body
char n = by - ty - 2;
for(char cy=0; cy<n; cy++)
{
*dp = mc; dp += 40;
}
// Bottom element
*dp = bc; dp += 40;
// Space below
for(char cy=by; cy<25; cy++)
{
*dp = 126; dp += 40;
}
}
else
{
// Special case, clear column
for(char cy=0; cy<25; cy++)
{
*dp = 126; dp += 40;
}
}
}
// Draw the current maze using the given z/x distance array
void maze_draw(const char * zxdist)
{
// pick colors based on orientation
char cleft, cright, cfront;
if (dx)
{
cfront = VCOL_MED_GREY;
if (dx < 0)
{
cleft = VCOL_LT_GREY;
cright = VCOL_DARK_GREY;
}
else
{
cleft = VCOL_DARK_GREY;
cright = VCOL_LT_GREY;
}
}
else
{
cleft = cright = VCOL_MED_GREY;
cfront = dy > 0 ? VCOL_LT_GREY : VCOL_DARK_GREY;
}
// Start position of player
sbyte ix = px, iy = py;
// Starting at first screen column
sbyte sx = 0;
for(char i=0; i<7; i++)
{
// Next screen column
sbyte tx = 20 - zxdist[i];
sbyte ty = sx / 4;
sbyte by = 25 - sx;
// View blocked by wall
if (maze[iy][ix] == '#')
{
for(char cy=0; cy<ty; cy++)
// Fill with wall color
for(char cx=sx; cx<40-sx; cx++)
{
for(char cx=sx; cx<20; cx++)
{
screen_put( cx, cy, 32, 0);
screen_put(39 - cx, cy, 32, 0);
}
}
for(char cy=ty; cy<by; cy++)
{
for(char cx=sx; cx<20; cx++)
{
screen_put( cx, cy, 102, 0);
screen_put(39 - cx, cy, 102, 0);
}
}
for(char cy=by; cy<25; cy++)
{
for(char cx=sx; cx<20; cx++)
{
screen_put( cx, cy, 32, 0);
screen_put(39 - cx, cy, 32, 0);
}
color_column(cx, cfront);
screen_column(cx, sx, 96 + (sx & 3), 96, 96)
}
// And be done
return ;
}
// Check for left wall
if (maze[iy - dx][ix + dy] == '#')
{
for(char x=sx; x<tx; x++)
// Draw left wall
for(char cx=sx; cx<tx; cx++)
{
sbyte ty = x / 4;
sbyte by = 25 - x;
for(char cy=0; cy<ty; cy++)
screen_put(x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(x, cy, 160, 0);
for(char cy=by; cy<25; cy++)
screen_put(x, cy, 32, 0);
// Perspective
sbyte ty = cx / 4;
sbyte by = 25 - cx;
color_column(cx, cleft);
screen_column(cx, cx, 100 + (cx & 3), 96, 124)
}
}
else
{
// Draw adjacent wall visible due to free space left
sbyte ty = tx / 4;
sbyte by = 25 - tx;
for(char x=sx; x<tx; x++)
// All at same height, wall is facing us
for(char cx=sx; cx<tx; cx++)
{
for(char cy=0; cy<ty; cy++)
screen_put(x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(x, cy, 102, 0);
for(char cy=by; cy<25; cy++)
screen_put(x, cy, 32, 0);
color_column(cx, cfront);
screen_column(cx, tx, 96 + (tx & 3), 96, 96)
}
}
// Check for right wall
if (maze[iy + dx][ix - dy] == '#')
{
for(char x=sx; x<tx; x++)
for(char cx=sx; cx<tx; cx++)
{
sbyte ty = x / 4;
sbyte by = 25 - x;
for(char cy=0; cy<ty; cy++)
screen_put(39 - x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(39 - x, cy, 160, 0);
for(char cy=by; cy<25; cy++)
screen_put(39 - x, cy, 32, 0);
sbyte ty = cx / 4;
sbyte by = 25 - cx;
color_column(39 - cx, cright);
screen_column(39 - cx, cx, 107 - (cx & 3), 96, 125)
}
}
else
{
sbyte ty = tx / 4;
sbyte by = 25 - tx;
for(char x=sx; x<tx; x++)
for(char cx=sx; cx<tx; cx++)
{
for(char cy=0; cy<ty; cy++)
screen_put(39 - x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(39 - x, cy, 102, 0);
for(char cy=by; cy<25; cy++)
screen_put(39 - x, cy, 32, 0);
color_column(39 - cx, cfront);
screen_column(39 - cx, tx, 96 + (tx & 3), 96, 96);
}
}
// Advance in maze
sx = tx;
ix += dx;
iy += dy;
}
}
// Raster interrupts for ceiling and floor colors
RIRQCode center, bottom;
int main(void)
{
#if 0
for(char i=0; i<8; i++)
{
float z = 0.5 + i;
float x = 9.0 / z;
printf("%d : %f / %f : %d\n", i, z, x, (int)(x + 0.5));
}
return 0;
#else
bool rotate = false;
mmap_trampoline();
// Install character set
mmap_set(MMAP_RAM);
memcpy(Font, charset, 2048);
mmap_set(MMAP_NO_BASIC);
// Switch screen
vic_setmode(VICM_TEXT, Screen0, Font);
// Change colors
vic.color_border = VCOL_BLACK;
// initialize raster IRQ
rirq_init(true);
// Build switch to scroll line IRQ
rirq_build(&center, 1);
// Change color for floor
rirq_write(&center, 0, &vic.color_back, VCOL_BLACK);
// Put it into the perspective focus point
rirq_set(0, 50 + 2 * 20, &center);
// Build the switch to normal IRQ
rirq_build(&bottom, 1);
// Change color for ceiling
rirq_write(&bottom, 0, &vic.color_back, VCOL_WHITE);
// place this at the bottom
rirq_set(1, 250, &bottom);
// sort the raster IRQs
rirq_sort();
// start raster IRQ processing
rirq_start();
// Block multiple rotations
bool rotate = false;
// Draw initial frame
screen_flip();
maze_draw(zxdist0);
screen_flip();
for(;;)
{
maze_draw(zxdist0);
// Read joystick input
joy_poll(1);
// Forward or backward motion
if (joyy[1])
{
// Target square
sbyte tx = px - dx * joyy[1];
sbyte ty = py - dy * joyy[1];
// Check i empty
if (maze[ty][tx] != '#')
{
px = tx;
py = ty;
maze_draw(zxdist1);
if (joyy[1] < 0)
{
// Forward animation
px = tx;
py = ty;
maze_draw(zxdist1);
screen_flip();
}
else
{
// Backward animation
maze_draw(zxdist1);
screen_flip();
px = tx;
py = ty;
}
}
// New frame at new position
maze_draw(zxdist0);
screen_flip();
}
// Check if new rotation
if (!rotate)
{
if (joyx[1] == 1)
{
// Rotate right
sbyte t = dx; dx = -dy; dy = t;
rotate = true;
rotate = true;
maze_draw(zxdist0);
screen_left();
}
else if (joyx[1] == -1)
{
// Rotate left
sbyte t = dx; dx = dy; dy = -t;
rotate = true;
maze_draw(zxdist0);
screen_right();
}
}
else if (!joyx[1])
{
// No rotation, may rotate again in next frame
rotate = false;
}
}
#endif
return 0;
}

View File

@ -233,8 +233,8 @@ void game_loop(void)
break;
case GS_PLAYING:
// Check player input on every frame
joy_poll(0);
snake_control(&TheGame.snake, joyx[0], joyy[0]);
joy_poll(1);
snake_control(&TheGame.snake, joyx[1], joyy[1]);
if (!--TheGame.count)
{

View File

@ -2,6 +2,10 @@ cd fractals
call make.bat
cd ..
cd games
call make.bat
cd ..
cd hires
call make.bat
cd ..

Binary file not shown.

Binary file not shown.