Jump to content

Just Jeff

Members
  • Posts

    592
  • Joined

  • Last visited

Everything posted by Just Jeff

  1. New .bin attached Alright.. I settled on reducing the display down to 8 and 32 and I suppose I'll use missiles for something on the other side of the score. The number of taxis remaining is now displayed and a basic game over state now exists. If you crash 3 times the game ends and you'll see "The End" Displayed ("Game Over" wouldn't fit). To start a new game you can hit the reset switch or the fire button for the other joystick (f key in Stella). Enjoy! SpaceTaxi.asm.bin
  2. Good afternoon.. Wondering if anyone has a solution to this.. .bin attached, though the dashboard is not working properly.. I've been working crashing with death plummet (which is largely done- try it), number of lives, game over etc. But I did get hung up on trying to change the bottom half of the dashboard so it displays number of taxis remaining and am giving up on it unless someone knows how to fit it in. If you do, please let me know: I split up a 48 bit display so it is a 8-32-8 bit display seen below. Seemed like it wouldn't be too complicated but I can't seem to be able to get it to work. No combination of VDELS, preloads, x-register, etc seems to be able to get it past the fact that you have two copies of the same player on each end and it makes VDEL more trouble than help. (in this case P0, P0, P1, P0, P1, P1.) Note: I have some complicated loads, but there's probably a way around that if necessary.. ;preloads ;lda (PadPtr1),y ;5 5 Taxis remaining ;sta GRP1 ;3 ;lda (PadPtr4),y ;5 5 100s and 10s ;ora (PadPtr5),y ;5 5 Combine the 100s and the 10s ;sta GRP0 ;3 8 .kernelLoop2 ;Bottom half of the dashboard sta WSYNC ;3 0 lda (PadPtr1),y ;5 5 Taxis remaining sta GRP1 ;3 8 lda (PadPtr4),y ;5 13 100s and 10s ora (PadPtr5),y ;5 18 Combine the 100s and the 10s sta GRP0 ;3 21 lda (Sprite1),y ;5 26 Dollar-digit sta GRP1 ;3 29 lda (Sprite1+2),y ;5 34 Pennies ora (Sprite1+4),y ;5 39 sta GRP0 ;3 42 After 41 lda (Sprite1+6),y ;4 46 Ones-decmal sta GRP1 ;3 49 lda (PadPtr2),y ;5 54 Duplicate Taxis remaining for now sta GRP0 ;3 57 dey ;2 59 ;cpy #0 ;2 61 bpl .kernelLoop2 ;2/3 63/64 Thanks! -Jeff SpaceTaxi.asm.bin
  3. Thanks I did find your blog previously and have looked through it but its written in a way that I am not familiar with so it's slow going. Also received the file you sent with similar result. I really appreciate the help so far. Thanks!
  4. I'm looking for some simple or commented code examples of 3E+ Bank switching. Can anyone point me to some?
  5. Awesome! I did not occur to me that code will not work in different segments but I suppose that's not a big issue. In fact I think the arrangement I suggested would work that way. Why won't code run in deferent segments? Program counter I suppose? Could you please point me to some example code?- like maybe a small shell that is set up with the RORGs and macros, etc Or is it easy to just set up myself? Oh and.. This will all work on Stella, PlusCart, Harmony, as well as actual cartridges I assume? Thanks again! -Jeff
  6. @Thomas Jentzsch Thanks! That does look a lot more versatile. One thing that is unclear to me is- can you combine these? Its said that its a "combination", but to be clear, I could have?: D7 D6 D5D4D3D2D1D0 0 0 x x x x x x switch a 1K ROM bank xxxxxx to $F000 0 1 switch a 512 byte RAM bank xxxxxx to $F400 with write @ $F600 1 0 switch a 512 byte RAM bank xxxxxx to $F800 with write @ $FA00 1 1 switch a 1K ROM bank xxxxxx to $FC00 And that once I write the banks to $3E and $3F one time, these segments stay there and stick together and act as one single 4K space until I write to one of them again? Using the above arrangement, I envision something like: $F000 VBLANK and Overscan $F400 Customized kernel bands assembled in order in RAM $F800 Unpacked Voice Data (Bytes split in half, left nibbles moved to right nibbles of next byte) $FC00 Compressed voice sample currently being accessed This is possible?
  7. OK I'm not familiar with those types of bankswitching. Do I have this correct?-- I could have my current voice data in the lower 2K area as needed (these will need to be switched) The upper 2K could contain game code that fetches from the lower 2K area with no bankswitch per each fetch? The description I saw mentioned JMPs and JSRs but didn't specifically mention what I would want- indexed loads and indirect addressing to the lower bank. Also, one person called it "RAM" is there RAM? Can I have multiple upper banks? The game code wouldn't fit into a single 2K upper bank. I currently have 4K for VBLANK and Overscan, and 8K reserved for the play kernels alone.
  8. Thanks- this is a technique I wasn't familiar with, but it doesn't work here.. Looks like you are expecting y values of 0 to 15 but these bytes are 0 to 255. Probably that's what you meant when you mentioned a 256-byte table being necessary? Alternatively, I was able to get this code to work by loading the accumulator with Voice+32, then AND #$0f, then TAY, but at that point it saves no time. Thanks! That's some crazy code, but it does work. Note- it also saves 2 bytes. Though I don't think the comment "Strip the right nibble of the RAM value" is correct- values are left in there, being various xors of one of the preserved RAM nibbles and a used voice nibble. So to answer your questions.. The right nibble of voice- The right nibble is the only relevant nibble when it comes to AUDV1- but I'm sure you knew that. Here is an abridged, two byte explanation of what I'm doing: Note below, VoiceCounter and VoicePointer are really the same counter- just a typo. Voice ds 1 ;Left nibble stores right half of FrameCounter while in kernel FrameCounter ds 1 ;Can be any value. Left nibble is always FrameCounter's left nibble. Right nibble borrowed for voice nibbles ;So two pieces of voice data fit per 1 byte of RAM reserved.. ;If FrameCounter's value is at, for example $A2, then for the kernel split that up so ;Voice = $20 and FrameCounter = $A0. This is OK becasue FrameCounter is not used in the kernel ;Jump to a voice data bank ;The voice data is 4 bits, played right nibble first, then left nibble second ;Load a byte of Voice Data and store each nibble in the right nibble of Voice and FrameCounter lda VoiceByte and #$0F ora Voice sta Voice lda VoiceByte lsr lsr lsr lsr ora FrameCounter sta FrameCounter ;Complicated here, so the kernel is fast and simple Kernel ;This code every 4 scan lines dec VoicePointer 5 5 ldx VoiceCounter 3 8 lda Voice,x 4 12 sta AUDV1 3 15 ;or maybe tya 2 2 ;use the kernel index lsr 2 4 lsr 2 6 ;multiply by 4 tax 2 8 lda Voice,x 4 12 sta AUDV1 3 15 ;Then when the kernel is done, put FramCounter back together Secondly, duplicating the kernels is impractical since there are 24 screens and multiple kernel bands, and 8 voice data banks. I'll probably end up with 100 to 200 kernel bands then duplicated on 8 banks = 800 to 1600 kernels. I'll consider more flexible bank switching, but still I don't think that will help me inside the kernel. How am I doing? -Jeff
  9. Good afternoon! Two things... Firstly, YouTube suggested this video to me. Freaked me out- in a good way: Secondly, I finally worked up the nerve to begin the voice code this morning after I had an epiphany... Bit-Packing! I believe I need to run through 50 AUDV1 register changes for every frame shown. That's just in the kernel section which should be the most difficult part. Since the data is spread over multiple banks, its impractical to grab any data while in the kernel, therefore it must be grabbed in VBLANK and Overscan, then stored in RAM and used every 4 scan lines while in the kernel. But 50 bytes of RAM seemed impractical and wasteful, if not impossible. Finally, this morning it occurred to me that I can get away with 25 bytes if I take existing RAM that is only used outside the kernel and store the right nibble of it in the left nibble of 25 bytes of designated VoiceRAM. In this way, 50 right nibbles are available for use for the price of only 25 bytes. Oh right- it's important to note that only the right nibble is used by the Atari, so the left nibble will be ignored and can therefore still be used to store useful data for other things, which makes this whole scheme work. Additionally, 25 is on the high end. With some code changes, there are some bytes that can get wrecked entirely while speech is happening and therefore, don't even need the swap space (VoiceRAM). Also, some bytes don't need two nibbles to begin with, in those cases the data can simply stay in the left nibble full time. After these code changes, I think I can bring the dedicated bytes needed down to 19 if necessary. So here's my bit packing and unpacking code. I'd be curious to know if it could be more efficient. It does run in the time allowed as is but then again, all this is doing is splitting the bytes (in preparation for grabbing voice data), then putting them back together after the screen is drawn. The RepackingBits looks a little unwieldy to me. What do you think? ;in Bank 1 UnpackBits SUBROUTINE ;added in TypicalPlayLogic.asm ;Sound registers only use the right nibble. So preserve the right nibble in the left nibble of VoiceRAM while ;in the kernel. Then restore it when out of the kernel ldx #31 ;This can probably be reduced to about 19 with some code modifications. ;I have 10 RAM bytes that can probably be trashed during speech and 3 RAM bytes that are single ;nibbles so they don't need swap space. Additionally, I probably could have used #25 here to get ;through the kernel to begin with. .ramSplit lda Voice+32,x ;This area of RAM will be borrowed for voice asl asl asl asl sta Voice,x ;The right nibble is stored in the left nibble of Voice. Right nibble is zero which is convenient. dex bpl .ramSplit rts ;Return, then jump to a voice bank ;Added in Overscan RepackBits ;Restore the left nibble of Voice, to the right nibble of Voice+32 while preserving that left nibble. ldx #31 .ramCombine lda Voice+32,x and #$f0 ;Strip the right nibble of the RAM value sta Voice+32,x lda Voice,x ;Right nibble of Voice+32 was stored in left nibble here. lsr lsr lsr lsr ora Voice+32,x sta Voice+32,x dex bpl .ramCombine rts Any suggestions? -Jeff
  10. AtariAge Day went nicely.. Here's a link to the Blocks segment. Also, I've attached some visual aids below: Here's my original cut and paste mockup based on Surround: Jeremiah's first iteration of the heads-up display: Jeremiah marking up one of Dean's images. View of the game in debug mode. Only three color registers are available, but they are interlaced to give some flexibility when writing to them. Only five objects are used to make the 64 "objects". Two missiles, two quad-sized players, and PF2 are turned on and left on, saving the time necessary for writing all the colors. Note the comb lines on the left. These are due to the HMOVEs that draw the zero. Also note, by its nature, TIA is really drawing three zeros so the other two have to be masked with PF1 when its time for that:
  11. OK.. I've gotten it back down to 192 scanlines and also the fuel gauge functioning now. .bin attached Thanks Thomas... I converted several of the loads to this. I wasn't able to do one of them on the top half (with the fuel gauge) because there isn't enough time. I also created another set of digits 0-9 followed by a decimal in ROM so I could do a single load on those. And I have the same thing for dollar sign with one digit. .kernelLoop1 ;Top half of the dashboard sta WSYNC ;3 0 lda (PadPtr5),y ;5 5 sta GRP0 ;3 8 lda (PadPtr4),y ;5 13 sta GRP1 ;3 16 lda (Sprite1+6),y ;4 20 sta GRP0 ;3 23 VDELP0 is on lda FuelGaugeNUSIZ,y ;4 27 sta ENAM1 ;3 30 sta NUSIZ1 ;3 33 After ~31 lda (Sprite1),y ;5 38 ldx #RED ;2 40 stx COLUPF ;3 43 $34 Turn red after 42 sta GRP1 ;3 46 lda #GREEN ;2 48 $B0 SLEEP 3 ;3 51 sta COLUPF ;3 54 lda #3 ;2 56 3 players close sta NUSIZ1 ;3 59 store after ~55 lda Sprite3,y ;4 63 dey ;2 65 sta GRP1 ;3 68 bpl .kernelLoop1 ;2/3 70/73 -break- .kernelLoop2 ;Bottom half of the dashboard sta WSYNC ;3 0 lda (PadPtr4),y ;5 5 ora (PadPtr5),y ;5 10 Combine the 100s and the 10s sta GRP0 ;3 13 lda (Sprite1),y ;5 18 sta GRP1 ;3 21 lda (Sprite1+2),y ;5 26 ora (Sprite1+4),y ;5 31 sta GRP0 ;3 34 VDELP0 is on SLEEP 7 ;7 41 lda (Sprite1+6),y ;4 45 sta GRP1 ;3 48 dey ;2 50 bpl .kernelLoop2 ;2/3 52/53 SpaceTaxi.asm.bin
  12. Well I have those 4 indicator lights on the same row which I have not even started on. They require setup as well as time on those lines so I don't know what's going to happen there either. To make your idea work, I need to also add some ORAs- right? Indirect load left nibble, ORA indirect address of right nibble? Thanks for pointing out the ANDs.. I'll change that.
  13. Nothing really. My plan at this point is to load up the most time consuming 10 bytes in vblank and just hold on to it during the kernel. That would be the cents at the right of the decimals for both the tip and the score. Its the most time consuming because two nibbles need to be ora'd with each other then all stored as a sprite in RAM. That's the best I could think of. I think the rest could be set up inside the dashboard. What do you think?
  14. Thanks! Yeah that's going to take some effort because the RESP1 is taking place at different times in different locations. The taxi's X position will need to be translated into distance from each RESP1, not to mention, converted to early HMOVE values. So, when each screen is done, that's probably when I'll work on those. Right now I simply AND the FrameCounter and store it in HMP1 so the movement is only just to make him wander around until he collides with the taxi. It will have voice for sure and I posted an example here some time ago, but like many other things, its probably something that is better done later. I plan to get a working gas gauge and a death plummet crash sequence next. I have the Tips and Score fields functioning now, so we're finally making some money: Its taking too much kernel time though. I'm at 267 scan lines now- 26 of them for the dash. And you can see the dash is a little distorted now as a result. I'd really like to reduce the dash height to 24 scan lines. The issue centers around setting up the digits for the Tips and the Score. Does anyone have any ideas? ;Setup line #2 ;Load up RAM buffer with either pointers or graphics lda Tip ;This is the Dollar sign and the 10s digit for the tip and #%11110000 lsr lsr lsr lsr tay lda DollarGfxLo,y ;Store a pointer which will be accessed while drawing sta Sprite1 lda DollarGfxHi,y sta Sprite1+1 ;This is dollar 1s digit before the decimal. The decimal will be manually added lda Tip and #%00001111 tax lda DigitBlankGfxLo,x ;Store a pointer which will be accessed when loading a RAM buffer sta Sprite1+6 lda DigitBlankGfxHi,x sta Sprite1+7 ;Load and combine cents lda Tip+1 and #%11110000 lsr lsr lsr lsr tax .loadCents10s lda DigitBlankGfxLo,x ;Store a pointer which will be accessed when loading a RAM buffer sta Sprite1+2 lda DigitBlankGfxHi,x sta Sprite1+3 lda Tip+1 and #%00001111 tax lda BlankDigitGfxLo,x ;Store a pointer which will be accessed when loading a RAM buffer sta Sprite1+4 lda BlankDigitGfxHi,x sta Sprite1+5 ldy #4 .loadSprites ;Load the RAM buffer with full sprites lda (Sprite1+2),y ;Load one of the penny digits ora (Sprite1+4),y ;Combine it with the other sta Sprite3,y ;Store the combo lda (Sprite1+6),y ;Load the single dollar digit in front of the decial sta Sprite2,y ;Store it, add the decimal to right nibble later dey bpl .loadSprites lda #%00000010 ;Add the decimal ora Sprite2 sta Sprite2 ;Set up the passenger's requests lda #>ShoutOuts ;Set the big end of the pointers. Don't go over one page. sta PadPtr4+1 sta PadPtr5+1 ldy #11 ;Load the offset for Hey! lda PassengerState bmi .storePtr ;If PASSENGER_HAIL, then store the 11 (Hey!) ldy #10 ;Load the offset for blank cmp #PASSENGER_ONBOARD ;Is the passenger onboard bne .storePtr ;If not, then don't display anything ldy #9 ;Load the offset for Up! just in case lda StopNumber ;Then check for which stop bmi .storePtr ;#$ff means the screen is done, so store 9 for Up! ldy CurrentTarget ;Otherwise, pick the message for the next stop .storePtr lda ShoutOuts4,y ;This is the table for the left half of the word(s) sta PadPtr4 lda ShoutOuts5,y ;This is the table for the right half of the word(s) sta PadPtr5 SpaceTaxi.asm.bin
  15. Awesome! You bought it? Maybe you were the first! I have no idea. Thanks!
  16. Who is going to PRGE? I'd really appreciate pictures or video of Blocks and setup at the AtariAge Booth! Would anyone be able to do that for me?
  17. Greetings, New .bin attached.. I laid out the dashboard to prep for adding the tip, bank, and fuel functions as well as to see how much I could realistically fit in. Also trying some new colors which are more of a departure from the original. Any opinions on the new dash colors or anything else? SpaceTaxi.asm.bin
  18. Nice.. I based my grid loosely on Steven Covey stuff- perfect for large tasks, largely because it helps me determine what not to work on.
  19. Much better progress this week. I achieved my major goal of having the game start with title screens, then run through 24 customizable play screens with 24 intros. Now... to get through it all, I had to point to existing code, tables, and routines and just did a few color changes for the first few play screens just as a proof of concept, so its pretty much the same screen over and over. But at this point the code is laid out nice and the customizations should be pretty straight forward. I'll basically copy a screen, rename it, change pointers for the jump, then customize it. I felt like this is the base point I had to reach and then build up from here. I also fixed and finished most of the stuff I left undone last week such as: Cab should be already occupied when screens start (except 1st) Correct hailing-shout-outs When you jump off a correct pad, then return, it no longer throws off the sequence When the gate is open, you can no longer land on the (hidden) designated pad (incorrectly) Passenger goes back into hailing state if you lift off prematurely This week saw the return of my famous task grid- and I credit much of my progress to it: Not a lot of items on it but it did help me focus and recall. -Jeff SpaceTaxi.asm.bin
  20. Well I haven't posted an update in a couple of weeks so I'll put this .bin up even though its glitchy and incomplete. Its been a significant amount of work, with little to show. Basically, my previous uploads had some cut corners that needed to be dealt with. I really wanted to get the program to run through all the screens- so a level intro, then a play screen, and so on. Even if the play screens are identical. But once I started, it seemed like I had to fix some things first or I'd be just duplicating messes. Firstly, you may have noticed that the previous version always played the same- I think it was pad 2 to pad 3, then pad 3 to Up. Now its randomized. All of that code I posted on September 3rd was static- wasn't going to get me past the one screen and always the same order. Now, that code is basically in table form, and the program can do those things in random order and future screens will just have their own tables. I wonder if the C64 version is random.. I'm just assuming it is. The other thing you'll notice is basic intro screens- this required me to redo my jump tables to make it more logical. Intro screens end in 0 (D0), play screens end in 1. This allowed me to split the jump tables in half- useful because a carry branch quickly gets to the proper bank with its own table. So its does like 3 screens now before it goes off the rails. I know why it does, I just haven't gotten around to writing the code. Also- the "Itinerary" of the dashboard is a little confusing at this point. The "Hey" and "Up" are gone at the moment, You'll always see a pad number when its generated- just remember- you don't see "Up" when its time to leave. Just look for the gate to disappear. .bin below. SpaceTaxi.asm.bin
  21. OK, I see the difference. Thanks! Though yours does still run every frame- correct? This looks a little like what I did for friction I think, though my "#gravity" is effectively #1 there. As for friction being a fraction of the speed itself- how do you suggest doing that? LSRs of the speed byte? A divide loop? I'm pretty happy with the way the taxi behaves now, except it is pretty noticeable at very slow speeds that the friction is a bit much. So I think this would help that. Attaching the latest .bin.. This is now a somewhat playable screen. Notice an itinerary is now on the bottom right corner, in the dashboard. It took me quite a while to figure this out and used more tables than I thought it would. Most of this is based on RAM bytes named "Itinerary" and "PassengerState". In the attached bin, the Itinerary essentially says- Pad2, Pad3, Pad 4, Up. PassengerState tracks if he is visible, boarding, hailing, etc, The goal of all of this is that the kernel only has to decide if the passenger is on that level of pads or not- nothing more. So in the above screenshot, the kernel only knows the passenger is on pad 1 or 2 because in RAM, Sprite1 is already loaded with zeros, and Sprite2 is already loaded with the passenger graphics. When it gets to pads 3 and 4, it simply skips over them both. In VBLANK: FlightPlanLevels: ;This is how the kernel determines if it should diplay the passenger on a particular level of pads ;.byte 1 ;Need an odd number of pads .byte 2 .byte 2 .byte 1 ;Moved FlightPlanSides to bank2 because it loads graphics from bank 2 ;This table contains ObjectX and ObjectY limits to check if contact was made at the right pad from the Itinerary. FlightPlanPickUps: ;From bottom, up WestLimitPU ;.byte #0 ;Making Itinerary offset $ff = Up. .byte #117 ;Pickup Pad 4 .byte #0 ;Dropoff Pad 3 .byte #117 ;Pickup Pad 2 EastLimitPU ;.byte #35 ;Dropoff .byte #152 ;Pickup .byte #35 ;Dropoff .byte #152 ;Pickup NorthLimitPU ;.byte #186 ;Dropoff .byte #114 ;Pickup .byte #114 ;Dropoff .byte #186 ;Pickup SouthLimitPU ;.byte #123 ;Dropoff .byte #75 ;Pickup .byte #75 ;Dropoff .byte #123 ;Pickup ShoutOuts4: ;Currently keeping the graphics 8 high- so this number times 8 .byte #UPGfx_HEIGHT-8 ;Up! .byte #HeGfx_HEIGHT-8 ;Hey! .byte #PaGfx_HEIGHT-8 ;Pad 3 .byte #HeGfx_HEIGHT-8 ;Hey! ShoutOuts5: .byte #PexGfx_HEIGHT-8 ;Up! .byte #YGfx_HEIGHT-8 ;Hey! .byte #D3Gfx_HEIGHT-8 ;Pad 3 .byte #YGfx_HEIGHT-8 ;Hey! And in another bank: FlightPlanSides: ;.byte 0 Removed so the last item is a pickup, and therefore the gate will open .byte 1 .byte 0 .byte 1 The in-kernel decision: .loop2 ;-----0 3 Five cycles quicker for the remainder of the loop sta GRP0 ;3 11 lda PassengerLevel ;3 14 Check to see if the passenger is on this line bne .notHere ;2/3 16/17 Zero means he is on this level of pads lda Sprite1,x ;4 18 sta GRP1 ;3 21 -Jeff SpaceTaxi.asm.bin
  22. I'm on it! I told myself I wasn't going to worry about comb lines and I'd probably have to shrink the screen down by 16 clocks for time reasons anyway, but things are coming together nicely so far and I'll see if I can stick with the full screen. Early HMOVEs fit in fairly easily so far and I think its worth it. Player 1 is the gate, passenger, pad numbers and platform "caps?". I'm in the middle of writing the taxi and passenger states so basically at this point the game is: When the passenger, who is clearly inebriated, appears at pad 2, you pick him up and bring him to pad 3. An argument ensues and he refuses to get out of the cab. In a fit of suicidal rage, you take off and slam the taxi into a wall, taking the both of you out and starting the process all over again. Is that how the original game is played? I don't remember exactly. SpaceTaxi.asm.bin
  23. align 256 TaxiGearUpGfx: .byte %00000000,%00000000,%00100100,%11011010,%11111111,%01000110,%01001000,%00110000 ;Taxi, gear up Player0Gfx: .byte %10000001,%01000010,%00100100,%11011010,%11111111,%01000110,%01001000,%00110000 ;Taxi, gear down Player0_HEIGHT = * - Player0Gfx ;Additional frames for landing collision checking .byte %00000000,%01000010,%00100100,%11011010,%11111111,%01000110,%01001000,%00110000 ;Both legs short .byte %00000001,%01000010,%00100100,%11011010,%11111111,%01000110,%01001000,%00110000 ;Left leg short .byte %10000000,%01000010,%00100100,%11011010,%11111111,%01000110,%01001000,%00110000 ;right leg short Hmm well I figured this would have prevented that, but it did not.
  24. Ah so it is the reason then since it a little quicker. I always thought it was used because it took exactly the same amount of time as the code it skips. Guess I never looked into it. Thanks!
  25. Good Morning.. I don't recall ever running into this before. Looks like a typical page boundary issue, but no amount of align 256s seem to be able to fix it. The shearing here is my fault, but note how it changes when the taxi is on the line. So it seems obvious I'm gaining a cycle. I did see this in the debugger. What's up with the "4-5" cycles Whatever it is, it appears I'm getting it when the taxi flies through it, but that doesn't make sense either since the branch is taken when the taxi is present. Any ideas? Thanks- -Jeff
×
×
  • Create New...